C IP地址族标识
我需要识别数据包IP的IP地址族(即IPv4或IPv6)。在中,我们已设法利用C IP地址族标识,c,linux,ip,ip-address,kernel-module,C,Linux,Ip,Ip Address,Kernel Module,我需要识别数据包IP的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 i
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报头的版本以及该版本的数据包
根据这一点,您需要以不同的方式踩踏收割台
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;
}
void*p=(void*)skb_网络_头(skb);
unsigned int protocol_version=(*((unsigned char*)p)和0xf0)>>4;
交换机(协议\u版本)
{
案例4:
结构ip_hdr*pip4_hdr=p;
printk(“src=%pI4\n”,&pip4\u hdr->saddr);
printk(“dst=%pI4\n”,&pip4_hdr->daddr);
打破
案例6;
结构ip6_hdr*pip6_hdr=p;
printk(“src=%pI6\n”,&pip6\u hdr->ip6\u src);
printk(“dst=%pI6\n”和&pip6_hdr->ip6_dst);
打破
违约:
printk(“\n”,协议版本);
打破
}
(未经测试)
参考:标题和标题的结构。@alk谢谢您的回复,先生。我应该如何修改它以支持IPv4和IPv6并识别版本?谢谢你的回答:)我会检查并发回:)再次感谢你的回答:)我知道你提到它未经测试,我尝试了代码,但它始终提供了
协议\u版本
。我能知道这里发生了什么吗-void*p=(void*)skb_网络_头(skb);无符号整数协议版本=ntohs(*(uint16_t*)p)和0x000f代码>?此函数是否与执行struct iphdr*iph相同;未签名的int协议\u version=iph->version
?非常感谢您的帮助,先生:)请尝试删除转换功能ntohs
。可能标头数据已按主机字节顺序排列。如果只是执行无符号int协议_version=*((uint16_t*)p)代码>协议版本
您能得到什么?ntohs(*(uint16\u t*)p)和0x000f
将p
视为指向一个uint16\u t
,取消引用该指针,该指针给出一个16位的值,将其从网络字节顺序转换为主机字节顺序,并最终屏蔽除最低4位以外的所有内容。Ok最终修复了该问题,第一个字节的4个msb执行版本。