TCP checksum fails

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux