LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Blogs > yaplej
User Name
Password

Notices

Just some entries about what I have learned in my effort to write an open source network accelerator.

http://www.opennop.org
Rate this Entry

Intercepting IP packets using Netfilter hooks

Posted 04-22-2010 at 11:26 PM by yaplej
Updated 04-22-2010 at 11:33 PM by yaplej

Netfilter hooks are very useful when you wish to intercept, and modify IP packets inside a kernel module.

One great thing about using Netfilter hooks over say dev_add_pack() is that the bad L2 frames, and bad IP packets get filtered out earlier in the network stack so you only deal with good packets.

Now the whole point of the Netfilter hook is to customize what the kernel does with the packets received by the system so here is an example hook function. It simply does some checks to make sure the packet is a TCP packet, and then prints the IP, and port info if it is. You may also want to check for other traffic types such as UDP, or ICMP you should be able to figure that out.

Somewhere in your function you must tell the system what to do with the packet that is being processed. You have several options with what you do with the packet. They are.
  1. NF_DROP Discard the packet.
  2. NF_ACCEPT Keep the packet.
  3. NF_STOLEN Forget about the packet.
  4. NF_QUEUE Queue packet for userspace.
  5. NF_REPEAT Call this hook function again.

My example hook function.
Code:
static unsigned int
myhook_func(unsigned int hooknum, 
struct sk_buff **skb, 
const struct net_device *in, 
const struct net_device *out, 
int (*okfn)(struct sk_buff *)){
	struct iphdr *iph = NULL;
	struct tcphdr *tcph = NULL;

	if ((skb != NULL) && 
		((*skb)->pkt_type == PACKET_HOST) && 
		((*skb)->protocol == htons(ETH_P_IP))){
		iph = ip_hdr((*skb)); // access ip header.

		/*
		 * yaple: Process only TCP segments.
		 */

		if ((iph->protocol == IPPROTO_TCP) ){
			tcph = (struct tcphdr *)(skb_network_header((*skb)) + ip_hdrlen((*skb))); // access tcp header.
			printk(KERN_ALERT "INFO: Source IP Address: %u.\n",iph->saddr);
			printk(KERN_ALERT "INFO: Destination IP Address: %u.\n",iph->daddr);
			printk(KERN_ALERT "INFO: Source Port: %u.\n",tcph->source);
			printk(KERN_ALERT "INFO: Destination Port: %u.\n",tcph->dest);

		}
	}
	return NF_ACCEPT; // Tells the system to accept the packet, and process the next one.
}
One thing to note about accessing the IP header, and TCP header fields. The data within most of them will be in a in a reversed order than the system is use to working with. To swap the "endianness" between host format, and network format use these function ntohs(), htons(), ntohs(), and ntohl().

So now that you have your hook function lets setup the hook. Its actually quite simple here is an example.

Code:
static struct nf_hook_ops my_hook = { // This is a Netfilter hook.
	.hook = myhook_func, // Function that executes when a packet hits this hook.
	.hooknum = NF_IP_FORWARD, // For routed traffic only.
	.pf = PF_INET, // Only for IP packets.
	.priority = NF_IP_PRI_FIRST, // My hook executes first.
};
You can hook into five different points as the packets pass through the system. Good documentation can be found here about each of them. http://www.iptables.org/documentatio...g-HOWTO-3.html
  1. NF_IP_PRE_ROUTING
  2. NF_IP_LOCAL_IN
  3. NF_IP_FORWARD
  4. NF_IP_POST_ROUTING
  5. NF_IP_LOCAL_OUT

Now in your module initialization function you need to register your hook.

Code:
nf_register_hook(&my_hook);
You also need to unregister your hook in your module exit function.

Code:
nf_unregister_hook(&my_hook);
Views 1612 Comments 1
« Prev     Main     Next »
Total Comments 1

Comments

  1. Old Comment
    wew that's interesting, thanks!
    Posted 04-23-2010 at 06:59 AM by Web31337 Web31337 is offline
 

  



All times are GMT -5. The time now is 04:07 AM.

Main Menu
Advertisement

My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration