c - Add data to packet of a specific protocol -
i'm implementing new protocol called xor. first packets created in user space , sent network. after packet arrive other node in network. need create module intercept every module sent , add header or data. create module put data packet don't have success.
i try things when activate module packets dropped. module doing:
struct xorhdr { int in; int out; }; static unsigned int asnfwd_hook(const struct nf_hook_ops *ops, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { struct iphdr *iph; struct asnfwd_opt *opt; __be32 addr = 0; struct tcphdr *th; struct udphdr *uh; /* sanity check */ if (!skb) goto accept; /* recover ipv4 header */ iph = ip_hdr(skb); if (!iph) goto accept; if (iph->protocol == 17) { uh = (struct udphdr *) skb_transport_header(skb); if ((unsigned int) ntohs(uh->source) == xor_port && (unsigned int) ntohs(uh->dest) == xor_port) { printk("\n****************************\n"); printk("hook %s\n", (in ? "pre-routing" : "local-out")); printk("(ogirinal) %pi4 %pi4.\n", &iph->saddr, &iph->daddr); printk(kern_info "free:%d", skb_headroom(skb)); if (in) { struct xorhdr *ptr; if (skb->tail + sizeof(struct xorhdr) < skb->end) { unsigned char* tail_ptr = skb_tail_pointer(skb); ptr = (struct xorhdr *)(tail_ptr); printk(kern_info "cbin:%d\n", ptr->in); printk(kern_info "cbout:%d\n", ptr->out); } } else { if (skb_headroom(skb) > sizeof(struct xorhdr)) { struct xorhdr *xorh; xorh = kmalloc(sizeof(struct xorhdr), gfp_atomic); unsigned char *new_data; new_data = skb_tail_pointer(skb); if (skb->tail + sizeof(struct xorhdr) < skb->end) { xorh->in = 6; xorh->out = 5; printk(kern_info "cbin:%d\n", xorh->in); printk(kern_info "cbout:%d\n", xorh->out); skb->tail += sizeof(struct xorhdr); skb->len += sizeof(struct xorhdr); memcpy(new_data, xorh, sizeof(struct xorhdr)); } kfree(xorh); // update ip header pointer iph = ip_hdr(skb); // calculate udp checksum uh = udp_hdr(skb); uh->check = 0; uh->check = csum_tcpudp_magic(iph->saddr, iph->daddr, ip_payload_len(iph), ipproto_udp, csum_partial(uh, ip_payload_len(iph), skb->csum)); skb->ip_summed = checksum_none; // calculate ip checksum ip_send_check (iph); } } printk("\n****************************\n\n"); } } accept: return nf_accept; }
what i'm doing wrong?
i solved problem moving skb->tail original position doing this: skb->tail -= sizeof(struct xorhdr);
. when receive package in other side use data put, , return skb->tail original position.
struct xorhdr { int in; int out; }; static unsigned int asnfwd_hook(const struct nf_hook_ops *ops, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { struct iphdr *iph; struct asnfwd_opt *opt; __be32 addr = 0; struct tcphdr *th; struct udphdr *uh; /* sanity check */ if (!skb) goto accept; /* recover ipv4 header */ iph = ip_hdr(skb); if (!iph) goto accept; if (iph->protocol == 17) { uh = (struct udphdr *) skb_transport_header(skb); if ((unsigned int) ntohs(uh->source) == xor_port && (unsigned int) ntohs(uh->dest) == xor_port) { printk("\n****************************\n"); printk("hook %s\n", (in ? "pre-routing" : "local-out")); printk("(ogirinal) %pi4 %pi4.\n", &iph->saddr, &iph->daddr); printk(kern_info "free:%d", skb_headroom(skb)); if (in) { struct xorhdr *ptr; if (skb->tail + sizeof(struct xorhdr) < skb->end) { unsigned char* tail_ptr = skb_tail_pointer(skb); ptr = (struct xorhdr *)(tail_ptr); printk(kern_info "cbin:%d\n", ptr->in); printk(kern_info "cbout:%d\n", ptr->out); skb->tail -= sizeof(struct xorhdr); // update ip header pointer iph = ip_hdr(skb); // calculate udp checksum uh = udp_hdr(skb); uh->check = 0; uh->check = csum_tcpudp_magic(iph->saddr, iph->daddr, ip_payload_len(iph), ipproto_udp, csum_partial(uh, ip_payload_len(iph), skb->csum)); skb->ip_summed = checksum_none; // calculate ip checksum ip_send_check (iph); } } else { if (skb_headroom(skb) > sizeof(struct xorhdr)) { struct xorhdr *xorh; xorh = kmalloc(sizeof(struct xorhdr), gfp_atomic); unsigned char *new_data; new_data = skb_tail_pointer(skb); if (skb->tail + sizeof(struct xorhdr) < skb->end) { xorh->in = 6; xorh->out = 5; printk(kern_info "cbin:%d\n", xorh->in); printk(kern_info "cbout:%d\n", xorh->out); skb->tail += sizeof(struct xorhdr); skb->len += sizeof(struct xorhdr); memcpy(new_data, xorh, sizeof(struct xorhdr)); } kfree(xorh); // update ip header pointer iph = ip_hdr(skb); // calculate udp checksum uh = udp_hdr(skb); uh->check = 0; uh->check = csum_tcpudp_magic(iph->saddr, iph->daddr, ip_payload_len(iph), ipproto_udp, csum_partial(uh, ip_payload_len(iph), skb->csum)); skb->ip_summed = checksum_none; // calculate ip checksum ip_send_check (iph); } } printk("\n****************************\n\n"); } } accept: return nf_accept; }
Comments
Post a Comment