Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1350383
  • 博文数量: 244
  • 博客积分: 10311
  • 博客等级: 上将
  • 技术积分: 3341
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-14 21:50
文章分类

全部博文(244)

文章存档

2013年(6)

2012年(5)

2011年(16)

2010年(11)

2009年(172)

2008年(34)

分类: LINUX

2009-03-09 12:00:26

概述
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
再次触发这个钩子。
步骤
Netfilter 的工作方式与防火墙钩子非常相似。作为 LKM 注册到内核的结构调用特定于进程的函数。任何基于 netfilter 的数据包拦截器都必须遵循开发 LKM 所采用的步骤。
特定于进程的函数
特定于进程的函数(或钩子)的原型如下所示:

   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_OUT、NF_IP_LOCAL_IN、NF_IP_ FORWARD 等。
**pskb
指向 TCP/IP 协议栈中数据包容器的指针;例如 sk_buff。
*indev & *outdev
指向流入和流出网络设备的设备结构的指针。在内核中注册的每种设备(例如,以太网卡)都有一个由 IRQ、IO 地址等组成的设备结构。当机器只有一个网络接口来处理流入和流出流量时,这两个结构是相同的。当流入和流出的流量由两种设备处理时,这两种结构是不同的。
(*okfn) (struct sk_buff *)
在激活钩子时调用该函数。
netfilter 结构
核心 netfilter 结构在 /usr/src/include/linux/netfilter.h 中定义,类似如下:

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

int nf_register_hook(struct nf_hook_ops *req);
这里,nf_hook_ops 是 netfilter 操作结构。
一旦该结构注册到内核中,Linux 将调用这里定义的函数来处理数据包。
取消注册 netfilter 结构
卸载 LKM 时,netfilter 结构需要从内核中取消注册。这一操作在 cleanup_module 函数中完成:
void nf_unregister_hook(struct nf_hook_ops *req);
nf_hook_ops 也是 netfilter 操作结构。
阅读(1967) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~