From: "Michael Lawson (mshindo)" <michael@sphinix.com>
To: netfilter-devel@vger.kernel.org
Subject: Re: Modifying TCP packets with libnetfilter_queue
Date: Mon, 7 Sep 2009 16:45:15 +1200 [thread overview]
Message-ID: <c97a47b90909062145m233e912dyfa4f9b102b60c02e@mail.gmail.com> (raw)
In-Reply-To: <c97a47b90909061952kaacdd2ama86f073855af87ed@mail.gmail.com>
This is a relative dump of the packet stream when filtered on wireshark
No. Time Source Destination Protocol Info
1808 3010.627337 10.0.0.29 127.0.0.1 TCP
42479 > http [SYN] Seq=0 Win=5840 Len=0 MSS=1460 TSV=4597297 TSER=0
WS=6
Frame 1808 (76 bytes on wire, 76 bytes captured)
Linux cooked capture
Internet Protocol, Src: 10.0.0.29 (10.0.0.29), Dst: 127.0.0.1 (127.0.0.1)
Version: 4
Header length: 20 bytes
Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00)
Total Length: 60
Identification: 0x5c7b (23675)
Flags: 0x04 (Don't Fragment)
Fragment offset: 0
Time to live: 64
Protocol: TCP (0x06)
Header checksum: 0x5523 [correct]
Source: 10.0.0.29 (10.0.0.29)
Destination: 127.0.0.1 (127.0.0.1)
Transmission Control Protocol, Src Port: 42479 (42479), Dst Port: http
(80), Seq: 0, Len: 0
Source port: 42479 (42479)
Destination port: http (80)
Sequence number: 0 (relative sequence number)
Header length: 40 bytes
Flags: 0x02 (SYN)
Window size: 5840
Checksum: 0x6a0f [correct]
Options: (20 bytes)
No. Time Source Destination Protocol Info
1809 3010.627381 127.0.0.1 10.0.0.29 TCP
http > 42479 [SYN, ACK] Seq=0 Ack=1 Win=32768 Len=0 MSS=16396
TSV=4597297 TSER=4597297 WS=6
Frame 1809 (76 bytes on wire, 76 bytes captured)
Linux cooked capture
Internet Protocol, Src: 127.0.0.1 (127.0.0.1), Dst: 10.0.0.29 (10.0.0.29)
Version: 4
Header length: 20 bytes
Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00)
Total Length: 60
Identification: 0x0000 (0)
Flags: 0x04 (Don't Fragment)
Fragment offset: 0
Time to live: 64
Protocol: TCP (0x06)
Header checksum: 0xb19e [correct]
Source: 127.0.0.1 (127.0.0.1)
Destination: 10.0.0.29 (10.0.0.29)
Transmission Control Protocol, Src Port: http (80), Dst Port: 42479
(42479), Seq: 0, Ack: 1, Len: 0
Source port: http (80)
Destination port: 42479 (42479)
Sequence number: 0 (relative sequence number)
Acknowledgement number: 1 (relative ack number)
Header length: 40 bytes
Flags: 0x12 (SYN, ACK)
Window size: 32768
Checksum: 0xf6d4 [correct]
Options: (20 bytes)
[SEQ/ACK analysis]
No. Time Source Destination Protocol Info
1810 3010.627403 10.0.0.29 127.0.0.1 TCP
42479 > http [RST] Seq=1 Win=0 Len=0
Frame 1810 (56 bytes on wire, 56 bytes captured)
Linux cooked capture
Internet Protocol, Src: 10.0.0.29 (10.0.0.29), Dst: 127.0.0.1 (127.0.0.1)
Version: 4
Header length: 20 bytes
Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00)
Total Length: 40
Identification: 0x0000 (0)
Flags: 0x04 (Don't Fragment)
Fragment offset: 0
Time to live: 64
Protocol: TCP (0x06)
Header checksum: 0xb1b2 [correct]
Source: 10.0.0.29 (10.0.0.29)
Destination: 127.0.0.1 (127.0.0.1)
Transmission Control Protocol, Src Port: 42479 (42479), Dst Port: http
(80), Seq: 1, Len: 0
Source port: 42479 (42479)
Destination port: http (80)
Sequence number: 1 (relative sequence number)
Header length: 20 bytes
Flags: 0x04 (RST)
Window size: 0
Checksum: 0x0f35 [correct]
On Mon, Sep 7, 2009 at 2:52 PM, Michael Lawson
(mshindo)<michael@sphinix.com> wrote:
> Still having problems modifying the packet destination, the packets
> appear to be getting out onto the wire, however the host receiving
> them sets the RST flag in the TCP payload, can anyone suggest a reason
> as to why this might occur once I adjust the destination address?
>
> Regards
>
> On Sat, Aug 29, 2009 at 10:48 AM, Michael Lawson
> (mshindo)<michael@sphinix.com> wrote:
>> I have made some form of progress late last night, basically a core
>> problem I found was in how I was getting struct tcphdr, once I fixed
>> this after a bit if fiddling round and some dirty string manipulation
>> I was able to match the checksums, so the packets get send out onto
>> the wire.
>>
>> However this has led to another problem (perhaps the one you are
>> referring to) that ethereal picks up, but tcpdump does not. Under
>> SEQ/ACK Analysis, ethereal notes that the packets being transmitted
>> are duplicate ACK's. This might simply require some dirty hacks to
>> fix.
>>
>> The code so far is on: http://pastebin.org/13016
>>
>> Sadly, I have to jump a 5 hour train shortly, so not much work will be
>> done this afternoon.
>>
>> Regards
>>
>> On Sat, Aug 29, 2009 at 7:53 AM, Zhiyun Qian<zhiyunq@umich.edu> wrote:
>>> Have you solved your problem? I've run into the same problem before and then even if I successfully set the TCP checksum. The packet cannot be delivered.
>>>
>>> More specifically, I can queue the packets as expected but after I rewrite the packet and generate the correct checksum at both IP and TCP header, and when I try re-injecting the packets into the network, it just never get sent out according to TCPDUMP. I've posted my question here before but no one answers... I am guess you might also encounter the same problem. If you can let me know if you have made any progress, that'll be great.
>>>
>>> -Zhiyun
>>> -----邮件原件-----
>>> 发件人: netfilter-devel-owner@vger.kernel.org [mailto:netfilter-devel-owner@vger.kernel.org] 代表 Michael Lawson (mshindo)
>>> 发送时间: Thursday, August 27, 2009 12:17 AM
>>> 收件人: netfilter-devel@vger.kernel.org
>>> 主题: Fwd: Modifying TCP packets with libnetfilter_queue
>>>
>>> Hi,
>>> I am attempting to adjust contents of tcp packets using the nf queue
>>> system, the queue part is working as I expected, however I am running
>>> into problems recalculating the tcp checksum. At the moment, the
>>> packet isnt being changed, and I am simply reading the checksum, then
>>> trying to regenerate it, these values arent matching and I am at a
>>> loss as to where I am going wrong.
>>>
>>> Here is the checksum code at the moment:
>>> struct tcp_pseudo /*the tcp pseudo header*/
>>> {
>>> __u32 src_addr;
>>> __u32 dst_addr;
>>> __u8 zero;
>>> __u8 proto;
>>> __u16 length;
>>> }pseudohead;
>>>
>>>
>>> long checksum(unsigned short *addr, unsigned int count) {
>>> register long sum = 0;
>>> while( count > 1 ) {
>>> /* This is the inner loop */
>>> sum += * addr++;
>>> count -= 2;
>>> }
>>>
>>> /* Add left-over byte, if any */
>>> if( count > 0 )
>>> sum += * (unsigned char *) addr;
>>>
>>> /* Fold 32-bit sum to 16 bits */
>>> while (sum>>16)
>>> sum = (sum & 0xffff) + (sum >> 16);
>>>
>>> return ~sum;
>>> }
>>>
>>> long get_tcp_checksum(struct iphdr * myip, struct tcphdr * mytcp) {
>>> mytcp->check = 0;
>>>
>>> u16 total_len = ntohs(myip->tot_len);
>>> int tcpopt_len = mytcp->doff*4 - 20;
>>> int tcpdatalen = total_len - (mytcp->doff*4) - (myip->ihl*4);
>>>
>>> /*Setup the pseudo header*/
>>> pseudohead.src_addr=myip->saddr;
>>> pseudohead.dst_addr=myip->daddr;
>>> pseudohead.zero=0;
>>> pseudohead.proto=IPPROTO_TCP;
>>> pseudohead.length=htons(sizeof(struct tcphdr) + tcpopt_len + tcpdatalen);
>>>
>>> /*Calc lengths*/
>>> int totaltcp_len = sizeof(struct tcp_pseudo) + sizeof(struct
>>> tcphdr) + tcpopt_len + tcpdatalen;
>>> unsigned short * tcp = new unsigned short[totaltcp_len];
>>>
>>> /*Copy to required mem*/
>>> memcpy((unsigned char *)tcp,&pseudohead,sizeof(struct tcp_pseudo));
>>> memcpy((unsigned char *)tcp+sizeof(struct tcp_pseudo),(unsigned
>>> char *)mytcp,sizeof(struct tcphdr));
>>>
>>> if(tcpopt_len > 0)
>>> memcpy((unsigned char *)tcp+sizeof(struct
>>> tcp_pseudo)+sizeof(struct tcphdr), (unsigned char
>>> *)myip+(myip->ihl*4)+(sizeof(struct tcphdr)), tcpopt_len);
>>>
>>> if(tcpdatalen > 0)
>>> memcpy((unsigned char *)tcp+sizeof(struct
>>> tcp_pseudo)+sizeof(struct tcphdr), (unsigned char
>>> *)mytcp+(mytcp->doff*4), tcpdatalen);
>>>
>>> // memcpy((unsigned char *)tcp+sizeof(struct
>>> tcp_pseudo)+sizeof(struct tcphdr)+tcpopt_len, (unsigned char
>>> *)mytcp+(mytcp->doff*4), tcpdatalen);
>>>
>>> return checksum(tcp, totaltcp_len);
>>> }
>>>
>>> and the whole file, although not much bigger is here:
>>> http://pastebin.com/m2bc636ed
>>>
>>> An example of the output values I am getting at the moment is:
>>> packet size = 529 ip->checksum = 22679 tcp->checksum = 14964 new
>>> ip->checksum = 22679 new tcp->checksum = 8007
>>> packet size = 52 ip->checksum = 13465 tcp->checksum = 8007 new
>>> ip->checksum = 13465 new tcp->checksum = 31444
>>> packet size = 52 ip->checksum = 13209 tcp->checksum = 31444 new
>>> ip->checksum = 13209 new tcp->checksum = 50105
>>> packet size = 52 ip->checksum = 12953 tcp->checksum = 50105 new
>>> ip->checksum = 12953 new tcp->checksum = 12783
>>>
>>> Any help or suggestions please? I am at a loss
>>>
>>> --
>>> Michael Lawson (mshindo)
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>>
>>>
>>>
>>>
>>
>>
>>
>> --
>> Michael Lawson (mshindo)
>>
>
>
>
> --
> Michael Lawson (mshindo)
>
--
Michael Lawson (mshindo)
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
prev parent reply other threads:[~2009-09-07 4:45 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <c97a47b90908262115l1dc29b78q7c02661b64af8cd9@mail.gmail.com>
2009-08-27 4:16 ` Fwd: Modifying TCP packets with libnetfilter_queue Michael Lawson (mshindo)
2009-08-27 5:34 ` Kuzin Andrey
[not found] ` <c97a47b90908271909l5849517bp729022d4cdd7cb6f@mail.gmail.com>
2009-08-28 2:09 ` Michael Lawson (mshindo)
2009-08-28 11:26 ` Bruno Moreira Guedes
2009-08-28 19:53 ` Zhiyun Qian
2009-08-28 20:51 ` Bruno Moreira Guedes
2009-08-28 22:48 ` Michael Lawson (mshindo)
2009-09-07 2:52 ` Michael Lawson (mshindo)
2009-09-07 4:45 ` Michael Lawson (mshindo) [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=c97a47b90909062145m233e912dyfa4f9b102b60c02e@mail.gmail.com \
--to=michael@sphinix.com \
--cc=netfilter-devel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).