簡體   English   中英

將數據添加到特定協議的數據包

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM