ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

linux – 类似netfilter的内核模块,用于获取源和目标地址

2019-10-03 07:50:25  阅读:248  来源: 互联网

标签:linux linux-kernel kernel-module


我读了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内核的实用程序(source file)中的任何函数替换20(典型IP头的长度).

任何帮助将不胜感激.

解决方法:

这篇文章现在有点过时了.您不理解的文本仅适用于3.11以下的内核版本.

对于新内核(> = 3.11)

如果您确定您的代码仅用于内核> = 3.11,则可以对输入和输出数据包使用下一个代码:

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

或者更优雅:

udp_header = udp_hdr(skb);

这是因为ip_rcv()已经为您设置了传输标头:

skb->transport_header = skb->network_header + iph->ihl*4;

这一变化是在this commit之前提出的.

对于旧内核(< 3.11) 传出数据包(NF_INET_POST_ROUTING) 在这种情况下.transport_header字段在sk_buffer中正确设置,因此它指向实际的传输层标头(UDP / TCP).所以你可以使用这样的代码:

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

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

udp_header = udp_hdr(skb);  

传入数据包(NF_INET_PRE_ROUTING)

这是棘手的部分.

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

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

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

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

以这种方式可以做得更优雅:

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头大小(即iph-> ihl * 4,以字节为单位)而不是幻数20.

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

if (ip_header->protocol == 17) {

在此代码中,您应该使用IPPROTO_UDP而不是17:

#include <linux/udp.h>

if (ip_header->protocol == IPPROTO_UDP) {

Netfilter输入/输出包解释

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

细节:

[1]:Some useful code from GitHub

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

[3]:This answer may be also useful

标签:linux,linux-kernel,kernel-module
来源: https://codeday.me/bug/20191003/1847794.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有