2009/8/28 Zhiyun Qian <zhiyunq@xxxxxxxxx>: > 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. I had the same problem in the past. So it was because I was changing source/destination information. If you want to do it take a look at libnetfilter_conntrack. But I don't have ever make it works fine for me. I don't know why but the connection gets too slow when I do SNAT/DNAT with libnetfilter_conntrack. > > -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 > > > > -- > 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 > -- 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