From: "Michael Lawson (mshindo)" <michael@sphinix.com>
To: Zhiyun Qian <zhiyunq@umich.edu>
Cc: netfilter-devel@vger.kernel.org
Subject: Re: Modifying TCP packets with libnetfilter_queue
Date: Mon, 7 Sep 2009 14:52:28 +1200 [thread overview]
Message-ID: <c97a47b90909061952kaacdd2ama86f073855af87ed@mail.gmail.com> (raw)
In-Reply-To: <c97a47b90908281548t5b31fb36i374e53ca27693d69@mail.gmail.com>
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)
--
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
next prev parent reply other threads:[~2009-09-07 2:52 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) [this message]
2009-09-07 4:45 ` Michael Lawson (mshindo)
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=c97a47b90909061952kaacdd2ama86f073855af87ed@mail.gmail.com \
--to=michael@sphinix.com \
--cc=netfilter-devel@vger.kernel.org \
--cc=zhiyunq@umich.edu \
/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).