Fwd: Modifying TCP packets with libnetfilter_queue

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

 



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

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

  Powered by Linux