Skip to content

Creating a simple ‘hello world’ Netfilter module

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.

{ 3 } Comments

  1. Srudeep K | October 29, 2009 at 6:08 pm | Permalink

    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

  2. Paul Kiddie | November 2, 2009 at 12:15 pm | Permalink

    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

  3. Pankaj Tanwar | November 22, 2009 at 3:38 am | Permalink

    Thanks Paul It’s just I was trying to find

{ 2 } Trackbacks

  1. [...] Add Netfilter hooks to kernel module [...]

  2. [...] Last time we created a Netfilter kernel module which simply dropped all packets which gave the structure and functions that need to be implemented for a Netfilter module to work. [...]

Post a Comment

Your email is never published nor shared. Required fields are marked *

Additional comments powered by BackType