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 ...
- 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
