i'm developing a kernel module, basically i have to put 12 bytes at the end of the packet on the tx side and then take them off on the rx side,

after a while of http navigation the kernel crashes and i don't know why..can anybody help me?

here's the code:

Code:
// funzione per il calcolo del checksum a livello IP

unsigned short csum (u16 *buf, int nwords)  {
        unsigned long sum;
 
        for (sum = 0; nwords > 0; nwords--)
                sum += *buf++;
                sum = (sum >> 16) + (sum & 0xffff);
                sum += (sum >> 16);
        return ~sum;
}


// calcolo checksum a livello transport

unsigned short transport_csum (struct sk_buff *sk) {
unsigned long sum;
unsigned char *addr, *p;
unsigned short len;
unsigned short provacheck;
struct iphdr *ip_h = ip_hdr(sk);


	//inizializzo la somma
	sum = 0;
	//pseudo header
	p = (unsigned char *) &(ip_h->saddr);
	sum += ((*p << 8) + *(p + 1));
	sum += ((*(p + 2) << 8) + *(p + 3));

	p = (unsigned char *) &(ip_h->daddr);
	sum += ((*p << 8) + *(p + 1));
	sum += ((*(p + 2) << 8) + *(p + 3));

	sum += (0 + ip_h->protocol);

	len = ntohs(ip_h->tot_len) - 20;

	sum += len;

	if(ip_h->protocol == 0x06){

		memset(sk->data + 36, 0, 2); 
		addr = (unsigned char *) (sk->data + 20);

		while(len > 1){
			sum += ((*addr << 8) + *(addr + 1));
			addr += 2;
			len -= 2;
		}
		
		if(len > 0)
			sum += (*addr << 8);
		
		while(sum >> 16)
			sum = (sum &0xFFFF) + (sum >> 16);
			
	provacheck = htons(~sum);	
	memcpy(sk->data + 36, &provacheck, 2);

	}
	else{	
		memset(sk->data + 26, 0, 2);
		addr = (unsigned char *) (sk->data + 20);
	
		while(len > 1){
			sum += ((*addr << 8) + *(addr + 1));
			addr += 2;
			len -= 2;
		}

		if(len > 0)
			sum += (*addr << 8);
		
		while(sum >> 16)
			sum = (sum &0xFFFF) + (sum >> 16);

	provacheck = htons(~sum);	
	memcpy(sk->data + 26, &provacheck, 2);

	}
	
	return 0;

} 
          


// Hook RX side

unsigned int hook_pre_routing(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 = ip_hdr(skb);   
	ushort ip_new_len;		
	uint controllo;
	ushort pippo, pippo1;
	unsigned char *pport;
	
	printk(KERN_ALERT "Received a new packet %p\n", skb);

	
	if(!strcmp(in->name,DEVICE_MESH))	{	

		if(!skb) {
			printk(KERN_ALERT " - skb is null\n"); 
			return NF_ACCEPT;
		}
		
		pport = (unsigned char *) (skb->data +20);
		pippo = (*pport << 8) + *(pport + 1);
		pippo1 = (*(pport + 2) << 8) + *(pport + 3);		
		
		if(pippo == 0x01bb || pippo1 == 0x01bb)
			return NF_ACCEPT;
			
		if(skb->mark != 0x000000bb){	
			memcpy(&controllo, skb->tail - 12, 4);	
			memcpy(&t_arrive, skb->tail - 8, 8);

					
			ip_new_len = ntohs(iph->tot_len) - 12;
			iph->tot_len = htons(ip_new_len);
			iph->check = 0;
			iph->check = csum ((u16*) iph, 10);
			skb_trim(skb, ip_new_len);
			
			if(skb_is_nonlinear(skb))
				skb_linearize(skb);

			if(iph->protocol == 0x06 || iph->protocol == 0x11)
				transport_csum(skb);			
			
			skb->mark = 0x000000bb;
		}
	}		

	else 
		printk(KERN_ALERT"Packet not processed RX\n");	
	
	return NF_ACCEPT;
}

//	hook TX SIDE

unsigned int hook_post_routing(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=ip_hdr(skb);
	ushort ip_new_len;
	ushort pippo, pippo1;
	unsigned char *pport;

	printk(KERN_ALERT "Sent a new packet\n");
	
	if(!strcmp(out->name,DEVICE_MESH))	{

		if(!skb) {
			printk(KERN_ALERT " - skb is null\n");	/*controllo che skb contenga il pacchetto*/
			return NF_ACCEPT;
		}

		pport = (unsigned char *) (skb->data +20);
		pippo = (*pport << 8) + *(pport + 1);
		pippo1 = (*(pport + 2) << 8) + *(pport + 3);		
		
		if(pippo == 0x01bb || pippo1 == 0x01bb)
			return NF_ACCEPT;
	
		if(skb->mark != 0x000000aa){
			//in caso non ci sia abbastanza spazio per i 12 byte nella tailroom aggiungo spazio
			
			if(skb_tailroom(skb) < 12){
				struct sk_buff *pkt = skb_copy_expand(skb, skb_headroom(skb), skb_tailroom(skb) + 12, GFP_KERNEL);

				if(!pkt){
					printk(KERN_ALERT "attenzione, non c' spazio per il clone del pacchetto!!!\n");
					return -1;
				}	

				kfree_skb(skb);
				skb = pkt;	
			}	

		// inserisco i 12 byte necessari, aggiorno i campi e ricalcolo il checksum
	
			skb_put(skb,12);		 
			ip_new_len = ntohs(iph->tot_len) + 12;
			iph->tot_len = htons(ip_new_len);
			iph->check = 0;
			iph->check = csum ((u16*) iph, 10);
			memcpy(skb->tail - 12, &counter, 4);
			//counter++;
			do_gettimeofday(&t_sent);
			memcpy(skb->tail - 8, &t_sent, 8);
			skb->mark = 0x000000aa;
		}
	}	

	else
		printk(KERN_ALERT "Packed not processed TX\n");
			
	return NF_ACCEPT;
}

//register and unregister modules

int init_test(void) {
	
	int ret = 0;
//	t_stamp = (struct timeval *) kmalloc(sizeof(struct timeval), GFP_KERNEL);
	printk(KERN_ALERT "Loading module %s...\n", DESC);
	printk(KERN_ALERT "NF_IP_NUMHOOKS = %d\n", NF_INET_NUMHOOKS);
	netfilter_ops_in.hook                   =       hook_pre_routing;
	netfilter_ops_in.pf                     =       PF_INET;
	netfilter_ops_in.hooknum                =       NF_INET_PRE_ROUTING;
	netfilter_ops_in.priority               =       NF_IP_PRI_FIRST;
	
	netfilter_ops_local_in.hook             =       hook_pre_routing;
	netfilter_ops_local_in.pf               =       PF_INET;
	netfilter_ops_local_in.hooknum          =       NF_INET_LOCAL_IN;
	netfilter_ops_local_in.priority         =       NF_IP_PRI_LAST;
	
	netfilter_ops_out.hook                  =       hook_post_routing;
	netfilter_ops_out.pf                    =       PF_INET;
	netfilter_ops_out.hooknum               =       NF_INET_POST_ROUTING;
	netfilter_ops_out.priority              =       NF_IP_PRI_LAST;
	
	netfilter_ops_local_out.hook            =       hook_post_routing;
	netfilter_ops_local_out.pf              =       PF_INET;
	netfilter_ops_local_out.hooknum         =       NF_INET_LOCAL_OUT;
	netfilter_ops_local_out.priority        =       NF_IP_PRI_FIRST;
	
	ret = nf_register_hook(&netfilter_ops_in); /* register NF_IP_PRE_ROUTING hook */
	printk(KERN_ALERT "   PRE_ROUTING hook registered (%d)!\n", ret);	
	ret = nf_register_hook(&netfilter_ops_local_in); /* register NF_IP_PRE_ROUTING hook */
	printk(KERN_ALERT "   LOCAL_IN hook registered (%d)!\n", ret);	
	ret = nf_register_hook(&netfilter_ops_out); /* register NF_IP_POST_ROUTING hook */
	printk(KERN_ALERT "   POST_ROUTING hook registered (%d)!\n", ret);
	ret = nf_register_hook(&netfilter_ops_local_out); /* register NF_IP_POST_ROUTING hook */
	printk(KERN_ALERT "   LOCAL_OUT hook registered (%d)!\n", ret);


	return 0;
}
void cleanup_test(void) {
	
//	remove_proc_entry(PROCFS_NAME, &proc_root);
	printk(KERN_ALERT "Unloading module %s...\n", DESC);
	nf_unregister_hook(&netfilter_ops_in); /*unregister NF_IP_PRE_ROUTING hook*/
	memset(&netfilter_ops_in, 0, sizeof(struct nf_hook_ops));
	//kfree(netfilter_ops_in);
	printk(KERN_ALERT "   PRE_ROUTING hook released.\n");
	
	nf_unregister_hook(&netfilter_ops_local_in); /*unregister NF_IP_PRE_ROUTING hook*/
	memset(&netfilter_ops_local_in, 0, sizeof(struct nf_hook_ops));
	//kfree(netfilter_ops_in);
	printk(KERN_ALERT "   LOCAL_IN hook released.\n");
	
	nf_unregister_hook(&netfilter_ops_out); /*unregister NF_IP_POST_ROUTING hook*/
	memset(&netfilter_ops_out, 0, sizeof(struct nf_hook_ops));
	//kfree(netfilter_ops_out);
	printk(KERN_ALERT "   POST_ROUTING hook released.\n");
	
	nf_unregister_hook(&netfilter_ops_local_out); /*unregister NF_IP_POST_ROUTING hook*/
	memset(&netfilter_ops_local_out, 0, sizeof(struct nf_hook_ops));
	//kfree(netfilter_ops_out);
	printk(KERN_ALERT "   LOCAL_OUT hook released.\n");
//	kfree(t_stamp);

}

module_init(init_test);
module_exit(cleanup_test);

#endif