Linux Kernel Module to Drop Packets captured via netfilter hooksLinux Kernel Module to Drop Packets captured via netfilter hooks

Here is my sample Kernel Module to drop packets (i.e sk_buff instance) captured via netfilter hooks. When you want to drop packets in your custom netfilter hooks make sure you never do a manual kfree_skb(skb) API call. Since it is anyway performed once the flow of the code moves out of your kernel module netfilter hook. All you need to do is to return NF_DROP to drop gracefully the desired packet. Here is my detailed video and a sample Linux Kernel module.

Download this episode my entire kernel module sample code, make file, clean script HERE. And here is the source code for a quick reference.

/* pkt_drop.c
 * Author: Kiran Kankipati
 * Updated: 09-feb-2017
 */
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/module.h> 
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/skbuff.h>  
#include <linux/udp.h>
#include <linux/ip.h>
#include <linux/in.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/net.h>
#include <linux/netdevice.h>
#include <linux/socket.h>
#include <linux/sockios.h>
#include <linux/inet.h>
#include <linux/inetdevice.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/if_arp.h>
#include <linux/icmp.h>
#include <linux/netlink.h>
#include <linux/mroute.h>
#include <net/checksum.h>
#include <net/inet_ecn.h>
#include <net/xfrm.h>
#include <net/route.h>
#include <net/sock.h>
#include <net/ip.h>
#include <net/tcp.h>
#include <net/arp.h>
#include <net/udp.h>
#include <net/icmp.h>
#include <net/inetpeer.h>
#include <net/protocol.h>
#include <net/flow.h>
#include <asm/types.h>

static struct nf_hook_ops nfho_pre_routing;

unsigned int pre_routing_hook_func(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)
{
	//kfree_skb(skb);  //- dont do this, this will crash your system.
	return NF_DROP; //this will drop the packet
	
	//return NF_ACCEPT; //this will accept the packet
}


static int hello_init(void)
{
	//Packet RX
	nfho_pre_routing.hook = pre_routing_hook_func;
	nfho_pre_routing.hooknum = NF_INET_PRE_ROUTING;
	nfho_pre_routing.pf = PF_INET;
	nfho_pre_routing.priority = NF_IP_PRI_FIRST;
	nf_register_hook(&nfho_pre_routing);

	return 0;
}

static void hello_exit(void) { nf_unregister_hook(&nfho_pre_routing); }

module_init(hello_init);
module_exit(hello_exit);

Its makefile:

obj-m += pkt_drop.o
all: 
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

New Update: 01-Jan-2019:
WARNING:

If you are using recent kernels such as 4.17.x or 4.18.x and so on, the above code may fail to compile. Since they replaced the nf_register_hook() and nf_unregister_hook() APIs with nf_register_net_hook() and nf_unregister_net_hook(). So in that case replace these lines with the new corresponding constructs as shown:

//nf_register_hook(&nfho_pre_routing); //compatible for old kernels
nf_register_net_hook(&init_net, &nfho_pre_routing); //compatible for new kernels

and …

//nf_unregister_hook(&nfho_pre_routing); //compatible for old kernels
nf_unregister_net_hook(&init_net, &nfho_pre_routing); //compatible for new kernels

* which is why it is worth to note that the Linux Kernel is always evolving and constantly changing. As a kernel developer you have to be aware of these. And this is what time to time I always emphasize in many videos. Following just books or some examples wont help. You should learn kernel programming from kernel source itself. Kindly watch my video on this topic if you are more curious: 0x17d Linux Kernel Programming | Tracking changes in Kernel Source code