netfilter-like内核模块获取源地址和目的地址

netfilter-like kernel module to get source and destination address

我阅读 this guide 编写内核模块来进行简单的网络过滤。

首先,我不知道下面的文字是什么意思,入站和出站数据包(按传输层)有什么区别?

When a packet goes in from wire, it travels from physical layer, data link layer, network layer upwards, therefore it might not go through the functions defined in netfilter for skb_transport_header to work.

其次,我讨厌幻数,我想用 linux 内核实用程序中的任何函数替换 20(典型 IP 的长度 header)(source file).

任何帮助将不胜感激。

这篇文章现在有点过时了。看不懂的文字只适用于3.11以下内核版本

对于新内核 (>= 3.11)

如果您确定您的代码将仅用于 >= 3.11 的内核,您可以将下一个代码用于 inputoutput 数据包:

udp_header = (struct udphdr *)skb_transport_header(skb);  

或更优雅:

udp_header = udp_hdr(skb);

这是因为 运输 header 已经在 ip_rcv():

中为您设置好了
skb->transport_header = skb->network_header + iph->ihl*4;

此更改由 this commit 带来。

对于旧内核 (< 3.11)

传出数据包(NF_INET_POST_ROUTING

在本例中 .transport_header 字段在 sk_buffer 中正确设置,因此它指向实际的 传输层 header (UDP/TCP).所以你可以使用这样的代码:

udp_header = (struct udphdr *)skb_transport_header(skb);  

或更好看(但实际上相同):

udp_header = udp_hdr(skb);  

传入数据包(NF_INET_PRE_ROUTING

这是棘手的部分。

在这种情况下,.transport_header 字段未设置为 sk_buffer 结构中的实际 传输层 header(UDP 或 TCP) (你在你的 netfilter 钩子函数中得到)。相反,.transport_header 指向 IP header(即 网络层 header)。

所以你需要自己计算传输header的地址。为此,您需要跳过 IP header(即将 IP header 长度添加到您的 .transport_header 地址)。这就是为什么你可以在文章中看到下一个代码:

udp_header = (struct udphdr *)(skb_transport_header(skb) + 20);

所以20这里只是IP的长度header.

可以这样做更优雅:

struct iphdr *iph;
struct udphdr *udph;

iph = ip_hdr(skb);

/* If transport header is not set for this kernel version */
if (skb_transport_header(skb) == (unsigned char *)iph)
    udph = (unsigned char *)iph + (iph->ihl * 4); /* skip IP header */
else
    udph = udp_hdr(skb);

在此代码中,我们使用实际 IP header 大小(即 iph->ihl * 4,以字节为单位)而不是幻数 20

文章中的另一个神奇数字是 17 在下一个代码中:

if (ip_header->protocol == 17) {

在这段代码中你应该使用 IPPROTO_UDP 而不是 17:

#include <linux/udp.h>

if (ip_header->protocol == IPPROTO_UDP) {

Netfilter input/output 数据包解释

如果您需要一些关于 netfilter 中传入和传出数据包之间差异的参考,请参见下图。

详情:

[1]: Some useful code from GitHub

[2]: "Linux Kernel Networking: Implementation and Theory" by Rami Rosen

[3]: This answer may be also useful