2012-11-25 65 views
2

我們正在嘗試爲Linux內核實現一個NAT模塊。 正在面臨的問題是,對於傳入掛鉤處的TCP數據包,預期指向目標端口的指針不會這樣做。 Snipplet傳出鉤:netfilter傳入掛鉤:struct tcphdr - > dest指針不指向正確的位置?

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 

但同樣的事情適用於在改變的源地址和源端口傳出鉤包。 Follwing作品傳出的數據包

tcph = tcp_hdr(skb); 
    if (!tcph)return NF_ACCEPT; 

    src_port = ntohs(tcph->source); 

有它得到了與進入的數據包的IP報頭的大小或結構tcphdr一個問題有一個bug或tcphdr-> DEST指針是錯誤的?還是更多的東西可能會出錯?

需要幫助。 謝謝。

+1

我不知道,但它可能是傳輸頭尚未設置。你可以嘗試手動執行:''tcph =(struct tcphdr *)(((char *)iph)+ iph-> ihl * 4)'' – Fred

+0

這裏是一個解釋:http://stackoverflow.com/questions/23693335/why-skb-buffer-needs-be-be-by-20-bytes-to-read-the-transport-buffer-whil –

+0

這是一個解釋:http://stackoverflow.com/questions/ 23693335 /爲什麼-SKB-緩衝器需要將要跳過的逐20字節到讀的傳輸緩衝 - 得到控制而 –

回答

2

我有同樣的問題,解決了由於一些同學和the class' teacher.

對於通過網絡過濾的傳入鉤到達的數據包,您應該使用+20(你現在有+22代替)。

示例代碼:

skb_linearize(skb); 
struct tcphdr* tcp_header; 
tcp_header = (struct tcphdr *)(skb_transport_header(skb)+20); 
相關問題