上篇我们看了netfilter的实现机制,这篇来实现下netfilter模块实操一把。
为了注册一个钩子,需要填充nf_hook_ops结构体,包括优先级,钩子地点和钩子函数。然后调用nf_register_hook()函数。
1. 数据结构
struct nf_hook_ops {
/* User fills in from here down. */
nf_hookfn *hook;
struct net_device *dev;
void *priv;
u_int8_t pf;
unsigned int hooknum;
/* Hooks are ordered in ascending priority. */
int priority;
};
定义在include/linux/netfilter.h
2. 模块代码一丢弃所有UDP输入包
本DEMO实现将所有输入的UDP包丢弃。钩子函数为hook_func,通过ip头的协议来指定,协议17就是表示此包是UDP包,如果将17改成1就会丢弃icmp包了。
.hooknum = 1表示是入口点过滤 NF_IP_LOCAL_IN ,如果改成3就是NF_IP_LOCAL_OUT了,这个定在内核文件include/uapi/linux/netfilter_ipv4.h,如下:
/* IP Hooks */
/* After promisc drops, checksum checks. */
#define NF_IP_PRE_ROUTING 0
/* If the packet is destined for this box. */
#define NF_IP_LOCAL_IN 1
/* If the packet is destined for another interface. */
#define NF_IP_FORWARD 2
/* Packets coming from a local process. */
#define NF_IP_LOCAL_OUT 3
/* Packets about to hit the wire. */
#define NF_IP_POST_ROUTING 4
#define NF_IP_NUMHOOKS 5
编写源码netmod.c如下:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netfilter_ipv4.h>
#include <linux/skbuff.h>
#include <linux/udp.h>
#include <linux/ip.h>