我需要识别数据包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;
在我的研究过程中,我空洞地介绍了如何执行此功能,我只找到了如何格式化并使用%pI4
和%pI6
将其显示为字符串。但不是如何以编程方式识别IP地址族。 (可能类似于函数IPAddress.AddressFamily
)
如果专家能帮助我解决这个问题,我会非常感激,因为我被困了好几天。
提前致谢:)
修改
根据@alk的建议,如果专家建议我改变上面提到的unsigned int
变量声明以支持IPv6,我将非常感激。 :)
答案 0 :(得分:2)
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;
}
(未测试的)