LINUX nf"/>
LINUX nf
最近一个项目需要检查TCP/IP包,于是就有了它
- HOOK代码编写
下面展示一些内联代码片
。
// 钩子回调函数
unsigned int myHookCallBack(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)
{
···············
}
struct nf_hook_ops g_stMyNfHook =
{.hook = myHookCallBack, //回调函数.pf = PF_INET, //协议类型.hooknum = NF_BR_LOCAL_OUT, //hook注册点.priority = NF_IP_PRI_FIRST, //优先级
};
static void hello_NfHook_Init(void)
{ int iRet;printk(KERN_ALERT "hello ini success!\n");iRet = nf_register_hook(&g_stMyNfHook); // 注册if (0 != iRet){printk(KERN_WARNING "nf_register_hook failed\n");return;}return;
}
static void hello_NfHook_Fini(void)
{printk(KERN_ALERT "hello_NfHook_Fini\n");nf_unregister_hook(&g_stMyNfHook); //卸载return;
}module_init(hello_NfHook_Init);//注册
module_exit(hello_NfHook_Fini);//卸载MODULE_LICENSE("GPL");//模块的license,有GPL、BSD等,即模块遵循的开源协议;
MODULE_AUTHOR("Stone");//模块作者
//MODULE_DESCRIPTION--模块描述
obj-m += test.o
#generate the path
CURRENT_PATH:=$(shell pwd)
#the current kernel version number
LINUX_KERNEL:=$(shell uname -r)
#the absolute path
LINUX_KERNEL_PATH:=/usr/src/kernels/linux-headers-$(LINUX_KERNEL)
#complie object
all:make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
#clean
clean:make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean
通过上面的命令就可以生产一个test.ko模块
- 模块的操作命令
装载模块 insmod test.ko
卸载模块 rmmod test.ko
查看打印日志 dmesg(查看内核日志,因为prink是打印到内核的)
列出系统所有内核模块 lsmod - struct nf_hook_ops
struct nf_hook_ops {struct list_head list;/* User fills in from here down. */nf_hookfn *hook; //hook处理函数struct net_device *dev; void *priv;u_int8_t pf; //协议类型unsigned int hooknum; //hook点/* Hooks are ordered in ascending priority. */int priority; //优先级
};struct nf_hook_ops g_stMyNfHook =
{.hook = myHookCallBack, //回调函数.pf = PF_INET, //协议类型.hooknum = NF_BR_LOCAL_OUT, //hook注册点.priority = NF_IP_PRI_FIRST, //优先级
};
协议类型一般分为:
enum {NFPROTO_UNSPEC = 0,NFPROTO_INET = 1, NFPROTO_IPV4 = 2, NFPROTO_ARP = 3,NFPROTO_NETDEV = 5,NFPROTO_BRIDGE = 7,NFPROTO_IPV6 = 10,NFPROTO_DECNET = 12,NFPROTO_NUMPROTO,
};
hook注册点
/* Bridge Hooks */
/* After promisc drops, checksum checks. */------网卡混杂丢包和校验和检查之后(所有进入协议栈的数据包都会经过PRE_ROUTING)
#define NF_BR_PRE_ROUTING 0
/* If the packet is destined for this box. */------经过路由判决,确定发往本机
#define NF_BR_LOCAL_IN 1
/* If the packet is destined for another interface. */--------经过路由判决,不是发往本机,需要从其他接口转发出去
#define NF_BR_FORWARD 2
/* Packets coming from a local process. */--------由本机外发出去的报文路径
#define NF_BR_LOCAL_OUT 3
/* Packets about to hit the wire. */--------所有数据包离开本机前的路径
#define NF_BR_POST_ROUTING 4/* Not really a hook, but used for the ebtables broute table */-------非hook点,用于其他目的
#define NF_BR_BROUTING 5
#define NF_BR_NUMHOOKS 6
priority 钩子优先级
NF_IP_PRI_FIRST = INT_MIN,NF_IP_PRI_CONNTRACK_DEFRAG = -400,NF_IP_PRI_RAW = -300,NF_IP_PRI_SELINUX_FIRST = -225,NF_IP_PRI_CONNTRACK = -200,NF_IP_PRI_MANGLE = -150,NF_IP_PRI_NAT_DST = -100,NF_IP_PRI_FILTER = 0,NF_IP_PRI_SECURITY = 50,NF_IP_PRI_NAT_SRC = 100,NF_IP_PRI_SELINUX_LAST = 225,NF_IP_PRI_CONNTRACK_CONFIRM = INT_MAX,NF_IP_PRI_LAST = INT_MAX,
回调函数的返回值
/* Responses from hook functions. */#define NF_DROP 0 ----丢弃,释放sk_buff结构#define NF_ACCEPT 1 ----继续正常传输数据报(按照5个钩子点正常传输)#define NF_STOLEN 2 ----模块接管该数据报,告诉Netfilter“忘掉”该数据报。该回调函数将从此开始对数据包的处理,并且Netfilter应当放弃对该数据包做任何的处理。但是,这并不意味着该数据包的资源已经被释放。这个数据包以及它独自的sk_buff数据结构仍然有效,只是回调函数从Netfilter获取了该数据包的所有权。#define NF_QUEUE 3 ----对该数据报进行排队(通常用于将数据报给用户空间的进程进行处理)#define NF_REPEAT 4 ----再次调用该回调函数,应当谨慎使用这个值,以免造成死循环#define NF_STOP 5 ----终止hook链处理,不会释放sk_buff数据
借鉴了网上很多文章,这里就不一一说了,谢谢大家,有不对的地方请指出
更多推荐
LINUX nf
发布评论