Linux核心:從skb獲取udp頭,udp_hdr()獲取到是錯誤的udp頭
阿新 • • 發佈:2019-01-04
一、skb中獲取ip頭、udp頭
核心程式碼HOOK函式中:
從skb獲取ip頭,使用核心API ip_hdr():
#include <linux/ip.h>
struct iphdr *iph;
iph = ip_hdr(skb);
從skb獲取udp頭,使用核心API udp_hdr():
#include <linux/udp.h>
struct udphdr *udph;
udph = udp_hdr(skb);
二、udp_hdr()獲取到是錯誤的udp頭
2.1 現象
上述獲取的iph是正確的ip頭,獲取的udph是錯誤的udp頭。
2.2 原因
因為此時sk_buff的transport_header並沒有指向正確的udp頭,而是和network_header一同指向了ip頭。
三、正確的獲取udp頭
3.1 通過ip頭計算udp頭
struct udphdr *udph;
udph = (struct udphdr *) ((u8 *) iph + (iph->ihl << 2));
3.2 先設定transport_header指向正確的udp頭,再用udp_hdr()獲取
四、例項程式碼struct udphdr *udph; skb_set_transport_header(skb, sizeof(struct iphdr)); //iph->ihl << 2 udph = udp_hdr(skb);
4.1 程式碼
unsigned int hook_mark1(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 udphdr *udph1; struct udphdr *udph2; iph = ip_hdr(skb); if (iph->protocol == 17) { iph = ip_hdr(skb); udph1 = udp_hdr(skb); udph2 = (struct udphdr *) ((u8 *) iph + (iph->ihl << 2)); printk("001 iph:%p, udph1:%p, udph2:%p\n", iph, udph1, udph2); skb_set_transport_header(skb, sizeof(struct iphdr)); iph = ip_hdr(skb); udph1 = udp_hdr(skb); udph2 = (struct udphdr *) ((u8 *) iph + (iph->ihl << 2)); printk("002 iph:%p, udph1:%p, udph2:%p\n", iph, udph1, udph2); } return NF_ACCEPT; }
4.2 輸出結果