Transfer from http://ycnian.org/blog/archives/628
NetFilter is a module in the Linux kernel network subsystem that can intercept messages in the system for processing. The firewall iptables in the Linux system is built on the NetFilter module. The flow of messages in a single Linux host is as follows:
Assuming that a Linux host's eth0 port receives a message, the Linux host will first look for the routing table and determine whether the message's destination address is itself. If you are yourself, then peel the headers off layer by level and then submit them to the application for processing. If the destination address is not itself, you can determine which network port the message is forwarded from by looking for the routing table. In addition to receiving messages, the Linux host will also take the initiative to send out the paper. You also need to find the routing table before sending the message, and determine the network port of the sending message.
The NetFilter sets 5 processing points in the path of the message flow, as shown in the location. At these 5 processing points, NetFilter intercepts every message that passes through and calls a series of functions to process it. We can add our own processing functions at these processing points to implement specific functions. These 5 processing points are:
Nf_inet_pre_routing (position 1): Can intercept all received messages, including the destination address is its own message and the need to forward the message.
Nf_inet_local_in (position 2): Can intercept the destination address is its own message.
Nf_inet_forward (position 3): All forwarded messages can be intercepted.
Nf_inet_local_out (position 4): You can intercept all issues that you issue.
Nf_inet_post_routing (position 5): All messages sent can be intercepted, including their own messages and forwarded messages.
The processing result of the NetFilter module may be as follows:
#define NF_DROP 0//Discard the message, no further transmission
#define NF_ACCEPT 1//Continue normal transmission of messages
#define Nf_stolen 2//netfilter module takes over the message and does not continue to transmit
#define NF_QUEUE 3//Queues The datagram and is typically used to submit the datagram to the user space process
#define NF_REPEAT 4//Call the hook function again
#define NF_STOP 5//Continue normal transmission of messages
Among them, nf_accept and nf_stop all indicated that the message passed the check, can circulate normally downward, but the nf_stop effect is stronger than nf_accept. Multiple hook functions can be registered at each processing point, and these hooks are arranged in priority order. The high-priority hook function processes the message first, and the message is processed with a lower priority. Nf_accept indicates that the message is handled by a certain hook function, and the next hook function can be processed. and nf_stop that the message through the processing of a certain hook function, the following hook function you do not deal with, who let your priority low, I can take the decision for you. Assuming that the two hook functions registered in nf_inet_local_in Hook1 and Hook2,hook1 have precedence over the HOOK2,HOOK2 setting, the processing result is nf_drop. If HOOK1 sets the processing result to be nf_accept, then the message will not be submitted to the application because HOOK2 will discard the message. If HOOK1 set the processing result is nf_stop, then the message will be submitted to the application, because Hook1 released, will not give HOOK2 processing opportunities.
In NetFilter, the data structure of a hook function is as follows:
? 
 
  
   
   | 1234567891011121314 | typedefunsigned intnf_hookfn(conststructnf_hook_ops *ops,                structsk_buff *skb, // 正在处理的报文                conststructnet_device *in, // 输入设备                conststructnet_device *out, // 输出设备                int(*okfn)(structsk_buff *)) // 如果通过了检查,就调用这个函数。structnf_hook_ops {        structlist_head list;  // 同一个处理点的所有钩子函数链接在一条链表中        nf_hookfn       *hook;  // 这是钩子函数        structmodule   *owner; // 模块        void*priv;  // 私有指针        u_int8_t        pf;     // 协议族        unsigned inthooknum;// 钩子函数起作用的时间点        intpriority;// 钩子函数的优先级,数值越小优先级越高.}; | 
 
  
In Nf_hookfn (), we do not need to care about OKFN (), because this parameter is not normally used. We can write our own hook function and then call Nf_register_hook () to register the hook function with the NetFilter module so that we can intercept each message for processing. Here is an example that registers a hook function with nf_inet_local_in and prints a message "Receive Message from 192.168.7.121" and then releases it if a message sent by 192.168.7.121 is received.
? 
 
  
   
   | 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 66 | #include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/netfilter.h>#include <linux/skbuff.h>MODULE_AUTHOR("Yanchuan Nian");MODULE_LICENSE("GPL");staticchartarget[4];staticunsigned intnftest_fn(conststructnf_hook_ops *ops,        structsk_buff *skb,        conststructnet_device *in,        conststructnet_device *out,        int(*okfn)(structsk_buff *)){    intres;    charsaddr[4];    intoffset;    offset = skb_network_offset(skb);    offset += 12;    res = skb_copy_bits(skb, offset, saddr, 4);    if(res < 0) {        returnNF_ACCEPT;    }    res = memcmp(saddr, target, 4);    if(!res)        printk(KERN_INFO"receive message from 192.168.7.121\n");    returnNF_ACCEPT;}staticstructnf_hook_ops nf_test_ops = {    .hook = nftest_fn,    .owner = THIS_MODULE,    .pf = NFPROTO_IPV4,    .hooknum = NF_INET_LOCAL_IN,    .priority = 0,};staticint__init nftest_init(void){    intres;    target[0] = 192; target[1] = 168;    target[2] = 7; target[3] = 121;    res = nf_register_hook(&nf_test_ops);    if(res < 0)        printk(KERN_INFO"failed to register hook\n");    else        printk(KERN_INFO"hello nftest\n");    returnres;}staticvoid__exit nftest_exit(void){    printk(KERN_INFO"bye nftest\n");    nf_unregister_hook(&nf_test_ops);}module_init(nftest_init);module_exit(nftest_exit); | 
 
  
"Turn" netfilter mechanism