Creating a simple ‘hello world’ Netfilter module
by Paul Kiddie • October 7, 2009 • kernel module, linux, networking • 11 Comments
This is the second part of the series in creating a NetFilter module for Ubuntu 8.04 (running linux kernel 2.6.24-23). In it I’ll write a simple Netfilter module as a kernel module that simply drops all packets and logs dropped packets to /var/log/messages. In order to implement this we take the code for the kernel module we coded up in part 1, which we’ll add the relevant Netfilter logic to.
For an in-depth look at the structure of Netfilter and code upon which this article is based upon, check out http://www.linuxjournal.com/article/7184.
To create a simple Netfilter hook requires several steps. We write a function which we call hook_func which is called whenever a packet comes in that meets the conditions of nf_hook_ops. This function performs the appropriate logic, which in our case is to drop packets. We fill in the nf_hook_ops structure which defines the particular Netfilter hook to target target, the priority of it (very important if you have multiple hooks), and gives the type of packet to target (in this case IPV4), and bind hook_func to it.
In the previous entry we defined the methods init_module() and cleanup_module(). For the Netfilter module, init_module() should now contain the code to set up the nf_hook_o
ps structure and register the hook with Netfilter. In cleanup_module() we put any code required to clean up. In this case, it corresponds to the code to unregister the hook from Netfilter.
We need to include several standard header files – if you have installed the linux-headers package for your distribution this should be enough and this file should compile using the Makefile we wrote in part 1 just fine.
Here is the complete code:
//'Hello World' netfilter hooks example
//For any packet, we drop it, and log fact to /var/log/messages
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
static struct nf_hook_ops nfho; //struct holding set of hook function options
//function to be called by hook
unsigned int hook_func(unsigned int hooknum, struct sk_buff **skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *))
{
printk(KERN_INFO "packet dropped\n"); //log to var/log/messages
return NF_DROP; //drops the packet
}
//Called when module loaded using 'insmod'
int init_module()
{
nfho.hook = hook_func; //function to call when conditions below met
nfho.hooknum = NF_IP_PRE_ROUTING; //called right after packet recieved, first hook in Netfilter
nfho.pf = PF_INET; //IPV4 packets
nfho.priority = NF_IP_PRI_FIRST; //set to highest priority over all other hook functions
nf_register_hook(&nfho); //register hook
return 0; //return 0 for success
}
//Called when module unloaded using 'rmmod'
void cleanup_module()
{
nf_unregister_hook(&nfho); //cleanup – unregister hook
}
Now if you compile the module using the procedure described in part 1, and install the module using insmod, you can test the module works by trying to ping, e.g. www.google.com. This will fail, because all packets are being dropped, and if you check /var/log/messages before and after you ping you should see appropriate “packet dropped” log messages on the end of the log file.
So we have a very simple and not very useful Netfilter module – next article I’ll extend the Netfilter module to access particular fields on the packet and act accordingly based on the protocol number. There have been some significant changes in kernel 2.6 in the way you access packet headers, which we will investigate then.
Pingback: Paul Kiddie’s Blog : Creating a “hello world” kernel module in linux
Dear Paul,
I went through your simple kernel module to drop all packets using netfilter hook. I have tried to access the packet headers and data using sk_buff structure. I have analyzed the kernel source code () and found out that there are three fields in the structure to access packet headers (transport_header, network_header and mac_header). I tried to extract source and destination IP addresses using network_header field. Unfortunately, I ended up with segmentation faults. Is there way to access packet data using sk_buff structure (like in kernel 2.4)? If so how can we get a pointer to packet data? How can we extract source and destination addresses? Please help me out….
Best Regards,
Srudeep K
Pingback: Paul Kiddie’s Blog : Creating a Netfilter kernel module which filters UDP packets
Hi Srudeep,
I was just in the process of writing my next post which deals with that, now live. You can find it at http://www.paulkiddie.com/2009/11/creating-a-netfilter-kernel-module-which-filters-udp-packets/. Just requires some straighforward modifications to the hook_func function — hope it helps,
Paul
Thanks Paul It’s just I was trying to find
to get rid of freezing problem change
sk_buff **skb
to
sk_buff *skb
and
socc_buff = * skb to
socc_buff = skb
Paul,
Great post and just what I need.
I’m trying to build this on a later kernel:
Linux ubuntu 2.6.35-22-generic #33-Ubuntu SMP Sun Sep 19 20:34:50 UTC 2010 i686 GNU/Linux
I can get the first program to compile, but the 2nd which introduces netfilter doesnt work for me.
I get this error:
error: ‘NF_IP_PRE_ROUTING’ undeclared (first use in this function)
Looking at the includes, this makes sense because that symbol in netfilter_ipv4.h is hidden behind an
ifndef __KERNEL__
And of course __KERNEL__ is defined so that makes NF_IP_PRE_ROUTING not defined.
Am I doing something wrong? or is my kernel just too different?
Thanks.
I just encounter the same error.
I don’t think this header is build for kernel module.
But, an :
7 #undef __KERNEL__
8 #include
9 #define __KERNEL__
has solved the problem.
Is there any other solution that isn’t that dirty ?
To avoid that error, remplace :
nfho.hooknum = NF_IP_PRE_ROUTING;
by
nfho.hooknum = NF_INET_PRE_ROUTING;
.
hi PAUL,
i got probelm as NF_IP_PRE_ROUTING not defined.
i resolved as above by changing
nfho.hooknum = NF_IP_PRE_ROUTING;
to
nfho.hooknum = NF_INET_PRE_ROUTING;
but if i do $sudo insmod firewall1.ko i got following
insmod: error inserting ‘firewall1.ko’: -1 Invalid parameters
how to resolve it ?? please help
in $ dmesg
nf_register_hook is unknown….. like this coming
give me solution to overcome this . please .