We are trying to implement a NAT module for linux kernel. The problem being faced is that for the TCP packets at the incoming hook, the pointer that is expected to point to destination port does not do so. Snipplet of outgoing hook:
unsigned int incoming_hook(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff*))
{
struct iphdr *iph;
struct tcphdr *tcph;
unsigned int dst_addr;
unsigned short dst_port;
unsigned short *dpptr;
printk(KERN_ALERT "****Incoming hook starts****\n");
if (!skb)return NF_ACCEPT;
iph = ip_hdr(skb);
if (!iph)return NF_ACCEPT;
dst_addr = ntohl(iph->daddr); // works correct
printk(KERN_ALERT " dst addr is %d \n", dst_addr);
if (iph->protocol==IPPROTO_TCP)
{
tcph = tcp_hdr(skb);
if (!tcph)return NF_ACCEPT;
dst_port = ntohs(tcph->dest); // gives incorrect result (unexpected.)
// dpptr = (unsigned short *)((char *)iph + 22); // just a try. does not work either
printk(KERN_ALERT " dst port is %d \n", *dpptr);
dst_port = ntohs(*dpptr);
// continues with the NAT code
The same thing however works for packets at the outgoing hook that changes the source address and source port. Follwing works for outgoing packets
tcph = tcp_hdr(skb);
if (!tcph)return NF_ACCEPT;
src_port = ntohs(tcph->source);
Has it got a problem with the incoming packets's IP header size or the struct tcphdr has a bug or the tcphdr->dest pointer is faulty? or is it something more that might be going wrong?
Need help. Thanks.
tcph = (struct tcphdr*) (((char*) iph) + iph->ihl * 4)
– Fred