- 论坛徽章:
- 0
|
各位好,请教大家一个关于sk_buff的问题:
编写一个简单的防火墙工具,内核版本是“2.6.18-92.el5”,内核源码中sk_buff的关于各个协议层的头结构体如下:
struct sk_buff {
。。。。。。
。。。。。。
union {
struct tcphdr *th;
struct udphdr *uh;
struct icmphdr *icmph;
struct igmphdr *igmph;
struct iphdr *ipiph;
struct ipv6hdr *ipv6h;
unsigned char *raw;
} h;
union {
struct iphdr *iph;
struct ipv6hdr *ipv6h;
struct arphdr *arph;
unsigned char *raw;
} nh;
union {
unsigned char *raw;
} mac;
。。。。。。
。。。。。。
}
然后我在防火墙的hook函数里面进行以下三种方法试图获取数据包的IP地址,
方法一,直接用IP结构体头类型转换skb->data,执行结果是打印的地址值都是零。
unsigned int hook_func(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
struct iphdr *network_header = (struct iphdr *)skb->data;
printk("<1>%x ==> %x\n", network_header->saddr, network_header->daddr);
return NF_ACCEPT;
}
方法二,直接取得skb->nh.iph,执行结果是打印的地址值都是零。
unsigned int hook_func(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
struct iphdr *network_header = (struct iphdr *)skb->nh.iph;
printk("<1>%x ==> %x\n", network_header->saddr, network_header->daddr);
return NF_ACCEPT;
}
方法三,从skb->head开始偏移14个字节(Erthnet头长度),然后类型转换,执行结果是,系统崩溃。
unsigned int hook_func(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
struct iphdr *network_header = (struct iphdr *)(skb->head + 14);
printk("<1>%x ==> %x\n", network_header->saddr, network_header->daddr);
return NF_ACCEPT;
}
我在网上google了一下,方法二比较常见,但是我取出来的值总是零,很奇怪。
顺便说一下,在这个内核版本中没有skb_network_header()这样的函数,新的内核版本中的
skb_network_header()是通过第三种方法实现的,但是sk_buff结构体变化很大,没有以上三个联合体。
请问,如何才能正确取得skb->nh.iph->saddr和skb->nh.iph->daddr的值?
请各位达人不吝赐教,谢谢。 |
|