Re: Modifying TCP packets with libnetfilter_queue

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

 



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@xxxxxxxxxxx> 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@xxxxxxxxxxx> 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@xxxxxxxxx> 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@xxxxxxxxxxxxxxx [mailto:netfilter-devel-owner@xxxxxxxxxxxxxxx] 代表 Michael Lawson (mshindo)
>>> 发送时间: Thursday, August 27, 2009 12:17 AM
>>> 收件人: netfilter-devel@xxxxxxxxxxxxxxx
>>> 主题: 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@xxxxxxxxxxxxxxx
>>> 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@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux