Results 1 to 1 of 1
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 ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
- 12-17-2009 #1Just Joined!
- Join Date
- Dec 2009
- Posts
- 1
netfilter problem
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





Reply With Quote
