Hello Everyone,
I am developing a kernel module which acts as a sniffer and also a module which edits the TCP packet window size as per requirement of the admin. And in the process I developed this kernel module which is tainting my kernel (Opensuse11.2).The sniffing module developed by me works fine but this editing module is dumping the kernel...

#include <linux/ip.h>             
#include <linux/kernel.h> 
#include <linux/module.h> 
#include <linux/netdevice.h>      
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/skbuff.h>         
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/string.h>
#include <linux/ipv6.h> 
#include<linux/inet.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("csurfer");
MODULE_DESCRIPTION("Packet Sniffer");

static struct nf_hook_ops netfilter_ops_out; /* NF_IP_POST_ROUTING */
struct tcphdr *tcp_header;
struct sk_buff *sock_buff;
struct iphdr *ip_header;
int dadd,sadd,bit1,bit2,bit3,bit4;
struct net_device * dev;

/* Function prototype in <linux/netfilter> */
unsigned int main_hook(unsigned int hooknum,  
                  struct sk_buff *skb,
                  const struct net_device *in,
                  const struct net_device *out,
                  int (*okfn)(struct sk_buff*))
{
sock_buff=skb_copy(skb,GFP_ATOMIC);

ip_header=(struct iphdr*)(sock_buff->network_header);

dadd= ip_header->daddr;
sadd=ip_header->saddr;
bit1=255 & sadd;
bit2=(0xff00 & sadd)>>8;
bit3=(0xff0000 & sadd)>>16;
bit4=(0xff000000 & sadd)>>24;

printk("Source IP %d.%d.%d.%d",bit1,bit2,bit3,bit4);

bit1=255 & dadd;
bit2=(0xff00 & dadd)>>8;
bit3=(0xff0000 & dadd)>>16;
bit4=(0xff000000 & dadd)>>24;

printk("     Destination IP %d.%d.%d.%d",bit1,bit2,bit3,bit4);

tcp_header=tcp_hdr(sock_buff);
printk("HW %d",ntohs(tcp_header->window));
tcp_header->window=htons(777);

// Choose the device through which the packet is to be sent
for_each_netdev(&init_net,dev)  
                if(strcmp(dev->name,"eth0")==0)
                        sock_buff->dev=dev;

dev_queue_xmit(sock_buff);             // Transmit the packet
return NF_STOLEN;
}

int init_module()
{
        netfilter_ops_out.hook=main_hook;
        netfilter_ops_out.pf=PF_INET;
        netfilter_ops_out.hooknum=NF_INET_POST_ROUTING;
        netfilter_ops_out.priority=NF_IP_PRI_FIRST;
        nf_register_hook(&netfilter_ops_out);
 /* register NF_IP_POST_ROUTING hook */
	return 0;
}

void cleanup()
{
	nf_unregister_hook(&netfilter_ops_out); 
       /*unregister NF_IP_POST_ROUTING hook*/
}

Can anyone tell me where i m wrong and any suggestions on how I can take it forward...???

I believe you are supposed to kfree_skb when you done with it. And at least check the value returned from skb_copy. Same goes for all other resources you allocate.

@nezachem : The skb_copy returns the correct value... I have checked it... and as far as kfree_skb of sock buff is concerned ... I m not allocating it any memory by some calls... and hence I don't need to de-allocate the memory it has... Thanks

@others : Any suggestions or links in this aspect would be great...

@nezachem : The skb_copy returns the correct value... I have checked it...

Well you did it. Your code does not.

and as far as kfree_skb of sock buff is concerned ... I m not allocating it any memory by some calls... and hence I don't need to de-allocate the memory it has...

Yes you do. That's what my manpage on skb_copy says:

Returns NULL on failure or the pointer to the buffer on success. The returned buffer has a reference count of 1.

I do not see anything in your code which would decrement the refcount.

I rectified all the mistakes which you had mentioned... and also took care about the kfree of allocated modules... But now its not only tainting the kernel but also is causing immediate hang of the system...

and also took care about the kfree of allocated modules

Just to make sure: you do kfree_skb(sock_buff) , not just kfree, right?

I did try with kfree(sock_buff) and also kfree_skb(sock_buff) both are resulting in system hang...In the above program all I have changed is to add the skb_free thing to the end after transmission of the buffer by the xmit() call...

I just realized that your biggest problem is at line 27:

struct sk_buff *skb

It should be

struct sk_buff **skb

I hope you figured it out by now.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.