Hi All, I wrote a program where I am using the nfnetlink and netfilter_queue model to capture the packet. After that I just change the destination address of the packet and insert it back into the ip stack. Now instead of calculating the TCP checksum from scratch, I was just recalculating it by using incremental update mechanism as mentioned in RFC 1624. Good thing is that I was able to get the correct IP header checksum but packet's TCP checksum value is corrupted. Interesting thing is, the difference in checksum is exactly the same as that of difference in original and modified packet header. What I mean to say is that I was changing the destination IP from "10.102.35.22" to "10.102.35.24" and the difference in tcp checksum (expected and computed) is coming as 0x02. Attached is the source code and tcpdump. Any help will be really appreciated. -- Regards, Gaurav Aggarwal /* Function to recalculate the checksum */ inline u_int16_t checksum_update_32( u_int16_t old_check, u_int32_t old, u_int32_t new) { u_int32_t l; old_check = ~old_check; old = ~old; l = (u_int32_t)old_check + ((old >> 16) + (old & 0xffff)) + ((new >> 16) + (new & 0xffff)); return ~((u_int16_t)((l >> 16) + (l & 0xffff))); } /* END */ /* Code from where I was calling this function */ static void filter( unsigned char *packet, unsigned int payload_len) { struct iphdr *iphdr; struct tcphdr *tcphdr; iphdr = (struct iphdr *)packet; /* check need some datas */ if (payload_len < sizeof(struct iphdr) + sizeof(struct tcphdr)) { return; } /* check IP version */ if (iphdr->protocol == IPPROTO_TCP) { tcphdr = (struct tcphdr *)(((u_int32_t *)packet) + 4 * iphdr->ihl); if (iphdr->daddr == foreign.s_addr) { iphdr->check = checksum_update_32( iphdr->check, iphdr->daddr, local.s_addr); tcphdr->check = checksum_update_32( tcphdr->check, iphdr->daddr, local.s_addr); iphdr->daddr = local.s_addr; } } } /* End */
Attachment:
ethreal_dump.pcap
Description: Binary data
Attachment:
nfq_test.c
Description: Binary data
tcpdump: listening on eth0 21:00:01.490920 10.102.35.76.38067 > 10.102.35.24.3490: S [bad tcp cksum fdff!] 1064689745:1064689745(0) win 5840 <mss 1460,sackOK,timestamp 4491010 0,nop,wscale 7> (DF) (ttl 64, id 26451, len 60) 4500 003c 6753 4000 4006 7839 0a66 234c 0a66 2318 94b3 0da2 3f75 e051 0000 0000 a002 16d0 8c9f 0000 0204 05b4 0402 080a 0044 8702 0000 0000 0103 0307 21:00:04.489859 10.102.35.76.38067 > 10.102.35.24.3490: S [bad tcp cksum fdff!] 1064689745:1064689745(0) win 5840 <mss 1460,sackOK,timestamp 4491760 0,nop,wscale 7> (DF) (ttl 64, id 26452, len 60) 4500 003c 6754 4000 4006 7838 0a66 234c 0a66 2318 94b3 0da2 3f75 e051 0000 0000 a002 16d0 89b1 0000 0204 05b4 0402 080a 0044 89f0 0000 0000 0103 0307 21:00:06.489554 arp who-has 10.102.35.24 tell 10.102.35.76 0001 0800 0604 0001 000b cd3a 5bfb 0a66 234c 0000 0000 0000 0a66 2318 0000 0000 0000 0000 0000 0000 0000 0000 0000 21:00:06.489596 arp reply 10.102.35.24 is-at 0:80:c8:1:56:13 0001 0800 0604 0002 0080 c801 5613 0a66 2318 000b cd3a 5bfb 0a66 234c 4 packets received by filter 0 packets dropped by kernel