TCP Checksum Calculation

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

 



Hi,

i am doing a modification to the TCP protocol and want to use an
additional bit of the TCP header's Reserved field. I chose to use the
bit next to the Bits used by the ECN mechanism. Therefore i changed the
TCP header definition in include/linux/tcp.h of a 2.6.16.29 Kernel to

struct tcphdr {
        __u16   source;
        __u16   dest;
        __u32   seq;
        __u32   ack_seq;
#if defined(__LITTLE_ENDIAN_BITFIELD)
        __u16   res1:3,
                doff:4,
                fin:1,
                syn:1,
                rst:1,
                psh:1,
                ack:1,
                urg:1,
                ece:1,
                cwr:1,
                elcn:1;
#elif defined(__BIG_ENDIAN_BITFIELD)
        __u16   doff:4,
                res1:3,
                elcn:1,
                cwr:1,
                ece:1,
                urg:1,
                ack:1,
                psh:1,
                rst:1,
                syn:1,
                fin:1;
#else
#error  "Adjust your <asm/byteorder.h> defines"
#endif
        __u16   window;
        __u16   check;
        __u16   urg_ptr;

};

I added the ecln bit instead of one bit of the res1 field.

I used tcpdump to check the TCP traffic when using the modified version
of TCP and i ran into the problem that on connection setup the SYN
packet is dropped by the receiver because of a bad checksum.
(I tried the unmodified kernel first, and it worked ;) )

An example output of such a bad packet from tcpdump is as follows:

IP (tos 0x0, ttl  64, id 15794, offset 0, flags [DF], proto: TCP (6),
length: 60) sender > receiver: S, cksum 0xaa78 (incorrect (-> 0x0272),
2824515850:2824515850(0) win 5840 <mss 1460,sackOK,timestamp 294938686
0,nop,wscale 1>
0x0000:  4500 003c 3db2 4000 4006 c448 89e2 12f9  E..<=.@.@..H....
0x0010:  89e2 1204 0bf0 006f a85a b10a 0000 0000   .......o.Z......
0x0020:  a002 16d0 aa78 0000 0204 05b4 0402 080a  .....x..........
0x0030:  ffff 903e 0000 0000 0103 0301            ...>........

I cut the problem down to the tcp_v4_send_check and the tcp_v4_check
method respectively as these are responsible for calculating the TCP
checksum. However i am not able to follow the csum_partial method which
apparently calculates the checksum for the TCP packet without the pseudo
header.

My questions are
Why does the checksum calculation fail in case of the modified header
structure ?
Does the calculation method assume the Reserved field to be of size 4
and equal 0 ?
If yes, how can you fix the checksum calculation to consider the new
bit and the new size of the reserved field ?

Thx in advance for your help

greets
Michael

-
To unsubscribe from this list: send the line "unsubscribe linux-net" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux