我需要识别数据包的 IP 地址系列(即 IPv4 或 IPv6)。已成功利用libnetfilter
捕获数据包并获取源和目标IP地址。但现在我需要识别从我正在实现的内核模块
获取的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;
在我的研究过程中,我对如何执行此功能一无所获,我只找到了如何使用 %pI4
和 %pI6
将其格式化并显示为字符串>。但不包括如何以编程方式识别 IP 地址系列。 (可能就像Linux内核模块相当于函数IPAddress.AddressFamily
)
如果各位专家能够帮助我解决这个困扰我好几天的问题,我将非常感激。
提前致谢:)
编辑
根据 @alk 的建议,如果各位专家建议我更改上述 unsigned int
变量声明以支持 IPv6,我将非常感激。 :)
最佳答案
skb_network_header 返回的指针的前 4 位指向的内容为您提供了 ip header 的版本以及该版本的数据包。
根据这一点,您需要以不同的方式处理 header 。
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;
}
(未经测试)
关于c - IP地址族识别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23842976/