Netfilter框架通过hook捕获数据包

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liyaohui_szz/article/details/49131691

数据包截获:Netfilter

Netfilter 是由内核 2.4.x 2.6.x 提供的数据包截获机制,它替代了内核 2.2.x 中 使用的 ipchains、防火墙钩子和其他方法。Netfilter 也可以作为 LKM 获得。

要使用 netfilter,在内核编译时设置 Packet Filtering 选项。

可以对采用防火墙钩子机制的同类应用程序使用 netfilter 机制,这些应用程序有:路由程序、数据包嗅探器和其他位于网络边缘并访问通信流的实体。

使用 Netfilter

Netfilter 可以在通过 TCP/IP 协议栈的路径中的几个定义良好的点上捕获数据包:

    NF_IP_PRE_ROUTING
    在对数据包进行初始正确性检查(校验和等)后,保存该数据包。
    NF_IP_LOCAL_IN
    如果数据包将要到达本地主机,则捕获该数据包。
    NF_IP_FORWARD
    如果数据包将要到达某些其他主机,则捕获该数据包。
    NF_IP_LOCAL_OUT
    在本地捕获其目的地是外部的已创建的数据包。
    NF_IP_POST_ROUTING
    这是最后的钩子,在此之后将传输数据包。

当数据包穿过 TCP/IP 协议栈后,协议调用带有数据包和钩子号的 netfilter 框架。钩子也 可以指派优先级。

函数的返回值包括:

    NF_ACCEPT
    数据包继续在正常的 TCP/IP 路径上传输。
    NF_DROP
    丢弃数据包;不进一步处理。
    NF_STOLEN
    已获得数据包;不进一步处理。
    NF_QUEUE
    对数据包排队(通常用于用户空间处理)。
    NF_REPEAT
    再次触发这个钩子。

特定于进程的函数

特定于进程的函数(或钩子)的原型如下所示:

   static unsigned int packet_interceptor_hook(unsigned int hook, struct
   sk_buff **pskb,

   const struct net_device *indev, const struct net_device *outdev, int

   (*okfn) (struct sk_buff *))


您可以将字段定义为:

    hook
    您感兴趣的钩子的编号;例如 NF_IP_LOCAL_OUTNF_IP_LOCAL_INNF_IP_ FORWARD 等。
    **pskb
    指向 TCP/IP 协议栈中数据包容器的指针;例如 sk_buff*indev & *outdev
    指向流入和流出网络设备的设备结构的指针。在内核中注册的每种设备(例如,以太网卡)都 有一个由 IRQIO 地址等组成的设备结构。当机器只有一个网络接口来处理流入和流出流量时,这两个结构是相同的。当流入和流出的流量由两种设备处理时,这两种结构是 不同的。
    (*okfn) (struct sk_buff *)
    在激活钩子时调用该函数。


netfilter 结构
核心 netfilter 结构在 /usr/src/include/linux/netfilter.h 中定义,类似如下:

struct nf_hook_ops
{
         struct list_head list;

         
         nf_hookfn *hook;
         int pf;
         int hooknum;
         
         int priority;
};

参数是:

    list
    Netfilter 本身是一个钩子链;它指向 netfilter 钩子的头部,通常设置为 { NULL, NULL }hook
    该函数在数据包碰到钩子点时被调用。该函数与前面描述的函数相同,它必须返回 NF_ACCEPTNF_DROP NF_QUEUE。如 果返回 NF_ACCEPT,则下一个钩子将被附加到将要调用的点。如 果返回 NF_DROP,则数据包被丢弃。如果返回 NF_QUEUE,则对数据包进行排队。sk_buff 指针被传递到该函数中,并用数据包信息如 IP 报头、TCP 报头等进 行填充。您可以使用 sk_buff 结构指针来操作或删除数据包(要删除数据包,只需将 skb 指 针设置为空即可)。
    pf
    协议簇;例如,适用于 IPv4 PF_INEThooknum
    您感兴趣的钩子号;例如 NF_IP_LOCAL_IN 等。
内核注册

init_module 函数中,需要注册在内核中填充的结构:

int nf_register_hook(struct nf_hook_ops *req);


这里,nf_hook_ops netfilter 操作结构。

一旦该结构注册到内核中,Linux 将调用这里定义的函数来处理数据包。

取消注册 netfilter 结构

netfilter 结构需要从内核中取消注册。这一操作在 cleanup_module 函数中完成:

void nf_unregister_hook(struct nf_hook_ops *req);


nf_hook_ops 也是 netfilter 操作结构。





展开阅读全文
博主设置当前文章不允许评论。

没有更多推荐了,返回首页