c - IP地址族识别

标签 c linux ip ip-address kernel-module

我需要识别数据包的 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;
}

(未经测试)

供引用: IPv6 的结构和 IPv4 header 。

关于c - IP地址族识别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23842976/

相关文章:

c - 替代 Windows 主机的 mman.h

用系统在 C 中编译

linux - 仅当线程运行时才向线程发送信号

apache - 无法通过 UBUNTU 12.10 上的本地 IP 地址访问 Web 服务器

c - 在C中的thread_join之后重用线程结构

c - 使用 C 语言通过套接字编程负载均衡器

c - 如何在不使用 ncurses 的情况下在 linux 终端上设置终端背景颜色?

linux - CoreOS Kubernetes 如何监控 Node 进程?

kubernetes - 将 minikube 上的服务映射到主机 IP

PHP ip2long 函数没有给出当前结果