我有一个需要识别IP数据包(即IPv4或IPv6)的IP地址族。 在设法使用libnetfilter
捕获数据包并获取源和目标IP地址。 但是现在我需要从我正在实现的kernel module
识别出获得的IP地址地址族。
IP地址存储如下,
struct iphdr *ip_header = (struct iphdr *)skb_network_header(skb); unsigned int src_ip = (unsigned int)ip_header->saddr; unsigned int dest_ip = (unsigned int)ip_header->daddr;
在我的研究过程中,我发现如何执行这个function,我只发现如何使用%pI4
和%pI6
格式化并显示为string。 而不是如何以编程方式识别IP地址族。 (可能像Linux内核模块相当于functionIPAddress.AddressFamily
)
如果你们的专家能帮我解决这个问题,我会被困在里面好几天,我会很感激的。
提前致谢 :)
编辑
有了@alk的build议,如果你的专家能够build议我改变上面提到的unsigned int
variables声明来支持IPv6,我将非常感激。 🙂
由skb_network_header
返回的指针指向的第一个4位为您提供了ip头的版本以及这个版本的数据包。
根据这个你需要踩不同的标题。
void * p = (void *) skb_network_header(skb); unsigned int protocol_version = (*((unsigned char *) p) & 0xf0) >> 4; switch (protocol_version) { case 4: struct ip_hdr * pip4_hdr = p; printk("src=%pI4\n", &pip4_hdr->saddr); printk("dst=%pI4\n", &pip4_hdr->daddr); break; case 6; struct ip6_hdr * pip6_hdr = p; printk("src=%pI6\n", &pip6_hdr->ip6_src); printk("dst=%pI6\n", &pip6_hdr->ip6_dst); break; default: printk("<unhandled protocol version: %u>\n", protocol_version); break; }
(另)
供参考: IPv6和IPv4标头的结构。