更改内核中的传出数据包

时间:2015-01-15 11:34:56

标签: c linux-kernel kernel network-protocols kernel-module

在L2,我捕获传出的数据包并尝试在以太网头之后插入新的头。实际上这是SecTAG。但在接收方,我看不到我的新标题(SecTAG标题),我只看到原始数据包。

这是我的代码:

int my_pkt_handling(struct sk_buff *skb, struct net_device *dev, struct packet_type *pkt, struct net_device *org_dev) {
unsigned char dst_addr[] = {0x00, 0x16, 0x41, 0xaa, 0xf8, 0xf0};        // HWaddr of 10.10.2.2
struct ethhdr *eth;
struct SecTag *sectag;

sectag = kmalloc(sizeof(struct SecTag), GFP_ATOMIC);

eth = eth_hdr(skb);
switch (skb->pkt_type) {
    case PACKET_HOST:
        break;
    case PACKET_OUTGOING:

        /* Simdilik sadece diger bilgisayara giden IP packetleriyle oynanacak */
        if ( memcmp(eth->h_dest, dst_addr, ETH_ALEN) == 0 && eth->h_proto == htons(ETH_P_IP) ) {
            unsigned char *temp_ethhdr = kmalloc(ETH_HLEN, GFP_ATOMIC);
            /* Copy the ethernet header to temp_ethhdr */                       
            memcpy(temp_ethhdr, eth, ETH_HLEN);     

            /* Check whether there is enough space in headroom to insert SecTag in the headroom of skb */
            if (skb_headroom(skb) > sizeof(struct SecTag)) {    
                // There is nothing roght now.
            } else {

                /* If there is not enough place in headroom then headroom must be reallocated */
                if (!skb_shared(skb)) {
                    int ret_pskb;
                    ret_pskb =  pskb_expand_head(skb, sizeof(struct SecTag) - skb_headroom(skb), 0 /*tailroom*/, GFP_ATOMIC);                   
                    if (ret_pskb == 0) {
                        unsigned char *eth_payload;

                        /* Remove the Ethernet HDR to insert SecTag */
                        eth_payload = skb_pull(skb, ETH_HLEN);

                        /* Insert the SecTag HDR before ethernet payload */
                        memcpy(skb_push(skb, SECTAG_LEN), sectag, SECTAG_LEN);

                        /* Insert again the original ethernet header */
                        memcpy(skb_push(skb, ETH_HLEN), temp_ethhdr, ETH_HLEN);
                        skb_reset_mac_header(skb);                          

                        eth = eth_hdr(skb);
                        eth->h_proto = htons(ETH_P_MACSEC);
                        print_ethhdr(eth);
                    } else {
                        printk(KERN_ALERT"pskb_expand_head() did not allocate. Err: %d\n", ret_pskb);
                        kfree(temp_ethhdr);
                        return SKB_NOT_EXP;
                    }
                } else {
                    printk(KERN_ALERT"SKB is being shared. User Number: %d\n", atomic_read(&skb->users));
                    kfree(temp_ethhdr);
                    return SKB_SHARED;
                }
            }

            /* Return the temp_ethhdr to kernel */
            kfree(temp_ethhdr);
        }

        break;
    case PACKET_BROADCAST:
        break;
    case PACKET_MULTICAST:
        break;
    case PACKET_OTHERHOST:
        break;
    case PACKET_LOOPBACK:
        break;
    case PACKET_FASTROUTE:
        break;
}
return 0;

}

我的代码出了什么问题?

0 个答案:

没有答案