c - IP checksum changes automatically -


i new network programming. past couple of days learning that. today tried play raw socket. went well. ip checksum didn't helped me well. whatever value gave manually iph->check, while receiving checksum different.

actually did created raw socket c program create tcp packet send loop interface using raw socket. , captured packet wireshark. when interpreting received packet, found whatever value gave check sum in program, shows different constant value.

here code

#include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/ip.h> #include <netinet/tcp.h> #include <arpa/inet.h> #include <errno.h> //#include <linux/in.h>  unsigned short calculate_check_sum (unsigned short *buf, int nwords) { unsigned long sum; (sum = 0; nwords > 0; nwords--) {     sum += *buf++; } sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); return ~sum; }  int main () { int sockfd = socket (pf_inet, sock_raw, 6); if (sockfd < 0) {     perror ("socket failed: ");     return -1; } char packet[4096];  struct iphdr *iph = (struct iphdr *) packet; struct tcphdr *tcph = (struct tcphdr *) packet + sizeof (struct iphdr); //char *payload = packet + sizeof (struct iphdr) + sizeof (struct tcphdr);  memset (packet, 0, 4096);  //strcpy (payload, "helllo");  struct sockaddr_in sin; sin.sin_family = af_inet; sin.sin_port = htons (1330); inet_pton (af_inet, "127.0.0.1", &(sin.sin_addr));  /* testing char var[123]; inet_ntop (af_inet, &(sin.sin_addr), var, inet_addrstrlen); printf ("%s\n", var); */  //writing on ip header iph->ihl = 5; iph->version = 4; iph->tos = 0; iph->tot_len = sizeof (struct iphdr) + sizeof (struct tcphdr); //+ strlen (payload); iph->id = htons (1234); iph->frag_off = 0; iph->ttl = 225; iph->protocol = 6; iph->check = 0; iph->saddr = inet_addr ("43.88.80.72"); iph->daddr = sin.sin_addr.s_addr;  //writing tcp header tcph->source = htons (1234); tcph->dest = htons (1330); tcph->seq = random (); tcph->ack_seq = 0; tcph->res1 = 0; tcph->doff = 0; tcph->syn = 1; tcph->window = htons (1000); tcph->check = 0; tcph->urg_ptr = 0;  //calculate check sum , put in places //iph->check = calculate_check_sum ((unsigned short *) packet, iph->tot_len >> 1); iph->check = 0xffff;  int 1 = 1; if (setsockopt (sockfd, 0, ip_hdrincl, &one, sizeof (one)) < 0) {     perror ("setsockopt faild: ");     return -1; }  int ret = sendto (sockfd, packet, iph->tot_len, 0, (struct sockaddr *) &sin, sizeof (sin)); if (ret < 0) {     perror ("sendto failed: ");     return -1; } return 0; } 

this stream captured wireshark 00000000000000000000000008004500002804d20000e106*da5c*2b5850487f0000010000000000000000000000000000000000000000

here 5cda (between astrics) checksum i'm getting.

also instead of wireshark, have created own capturing program follows,

#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> #include <netinet/tcp.h> #include <netinet/ip.h> #include <string.h> #include <errno.h>  int main () { int fd = socket (pf_inet, sock_raw, 6); int len_msg; if (fd < 0)     perror ("socket failed: "); char buf [8192]; memset (buf, 0, 8192); struct sockaddr_in sock_addr; inet_pton (af_inet, "127.0.0.1", &(sock_addr.sin_addr)); int len = sizeof (struct sockaddr); printf ("%s\n",inet_ntoa(sock_addr.sin_addr.s_addr)); if (bind (fd, (struct sockaddr *) &sock_addr, len)) {     perror ("bind failed: ");     return -1; } while ((len_msg = recvfrom (fd, buf, 8192, 0, (struct sockaddr *) &sock_addr, (socklen_t *)&len)) != -1) {     //printf ("%s\n", buf+sizeof(struct iphdr)+sizeof(struct tcphdr));     //printf ("%s\n", buf);     int i;     printf ("%d\n", len_msg);     (i = 0; < len_msg; += 1)         printf ("%x ", (unsigned char) *(buf + i));     printf ("\n");      printf ("*****************************************\n");     struct iphdr *iph = (struct iphdr *) buf;     printf ("checksum: %x\n", iph->check);     break; } printf ("%s\n",inet_ntoa(sock_addr.sin_addr.s_addr)); return 0; } 

still getting same value of check. regardless of whatever value inputing in first program, checksum, captured packet having value 0x5cda checksum.

i using centos. kernel alteration in packet? please me.

thanks in advance

from description, looks putting bogus ip checksum in sending code. not valid according rfc 1122. suspect linux raw socket handling code more lenient , accept packets invalid ip checksum overwrite checksum.

take at:

http://lxr.linux.no/linux+v3.4.1/net/ipv4/raw.c#l458 (this gets called when send message)


Comments

Popular posts from this blog

django - How can I change user group without delete record -

java - Need to add SOAP security token -

java - EclipseLink JPA Object is not a known entity type -