В Вто, 28/04/2009 в 20:30 +0530, Subhadeep Ghosh пишет: > Hello, > > I am trying to build a custom firewall kernel module for Linux. The > module registers itself in the pre-routing chain as the first module. > In the NetFilter callback function I check if the skb is for a tcp > connection and the port is 80. If the two requirements are meant, I > modify the destination address and the checksum of the IP as well as > the TCP header to the ip address of the machine where this (DNAT) is > taking place in the ip header and let the packet pass. Unfortunately, > this is not working. I've put a great deal of effort trying to > understand the DNAT'ing code in xtables but again of no use. As far as > I've read, at the time of pre-routing nothing in the skb, excepting > the ethernet, ip and protocol headers along with the payload is set. > If that is the case (and if the checksums are all right), I don't see > a reason why a packet should be dropped. > > Following is the NetFilter callback function code (I am not including > the rest of the code as it is trivial). > > static unsigned int _rfw_prerouting_hook(unsigned int _nHook, > struct sk_buff* _pSKB, > const struct net_device* _pInNIC, > const struct net_device* _pOutNIC, > int (*_pOkFn)(struct sk_buff*)) > { > if(!strcmp(_pInNIC->name, "eth1")) > { > if(_pSKB) > { > struct iphdr* _pIPHeader = ip_hdr(_pSKB); > > if(_pIPHeader) > { > switch(_pIPHeader->protocol) > { > case IPPROTO_TCP: > { > struct tcphdr* _pTCPHeader = (struct tcphdr*)(_pSKB->data > + (_pIPHeader->ihl << 2)); > > > if(_pTCPHeader && > (_pIPHeader->daddr != ((1 << 24) + 10)) && > (_pTCPHeader->dest == htons(80))) > { > // Only modifying TCP packets whose destination IP is not > 10.0.0.1 and destination port is 80 > _pIPHeader->daddr = (1 << 24) + 10; // Hopefully this > translates to 10.0.0.1 > _pIPHeader->check = 0; > _pIPHeader->check = ip_fast_csum((unsigned > char*)_pIPHeader, _pIPHeader->ihl); > > _pTCPHeader->check = 0; > _pTCPHeader->check = tcp_v4_check(_pTCPHeader->doff << 2, > _pIPHeader->saddr, > _pIPHeader->daddr, > csum_partial((char*)_ > pTCPHeader, > _pTCPHeader->doff << 2, > 0)); > } > } break; > } > } > } > } > > return NF_ACCEPT; > } > > One might say that this task can be easily done using a trivial > iptables rule, but my problem does not end at this point. What I am > expected to do is eventually conditionally do a DNAT for just a > specified, dynamic set of IP addresses. If the task needed is usual DNAT and the problem is in the fact that addresses are dynamic then "ipset" would solve your task. It is much more simple and easy to add/remove IPs to/from ipset in combination with static DNAT rules even from withing C program. -- Покотиленко Костик <casper@xxxxxxxxxxxx> -- To unsubscribe from this list: send the line "unsubscribe netfilter" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html