[英]Add data to packet of a specific protocol
我正在實現一個稱為XOR的新協議。 首先,在用戶空間中創建數據包並將其發送到網絡。 之后,數據包將正常到達網絡中的其他節點。 現在,我需要創建一個模塊來攔截發送的每個模塊,並添加標頭或一些數據。 我創建了一個將一些數據放入數據包的模塊,但沒有成功。
我嘗試了一些操作,但是當激活我的模塊時,數據包被丟棄。 這是我的模塊正在執行的操作:
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 the 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 is %s\n", (in ? "pre-routing" : "local-out"));
printk("(Ogirinal) From %pI4 to %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;
}
我做錯了什么?
我這樣做解決了將skb-> tail移回原始位置的問題: skb->tail -= sizeof(struct xorhdr);
。 因此,當我在另一側收到包裹時,我將使用放入的數據,並將skb-> tail返回原始位置。
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 the 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 is %s\n", (in ? "pre-routing" : "local-out"));
printk("(Ogirinal) From %pI4 to %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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.