内核中拦截DHCP discover包 并塞入option 60 字段

[转载请注明出处  http://www.cnblogs.com/umbrellary/p/5139988.html ]
实验环境:Linux 2.6.31 openwrt系统代替题中的笔记本 手机
     主要实现思想:在内核/net/core/dev.c源文件的netif_receive_skb函数中篡改数据包实现向DHCP包中插入option 60字段为字符串'dhcp-athx'。因为每个skb的skb->dev->name指示的是收到此数据帧的网卡,所以可以根据此变量的值进行区分不同sta,从而实现不同的sta篡改不同的option 60字段。
if (skb){
        
        char *buf = (char *)(skb->mac_header);
        struct iphdr *iph = (struct iphdr *)(buf + ETH_HLEN);
        struct udphdr *udph = (struct udphdr *)(buf + ETH_HLEN + 20);
        if(((unsigned char *)buf)[6] == 0x64//我的手机的MAC地址第一个字节
            && ((unsigned char *)buf)[12] == 0x08 
            && ((unsigned char *)buf)[13] == 0x00 //以上为IP包关键字
            && ((unsigned char *)buf)[23] == 0x11 //UDP关键字
            && ((unsigned char *)buf)[35] == 0x44 //客户端源端口
            && ((unsigned char *)buf)[37] == 0x43 //服务器目的端口
            && ((unsigned char *)buf)[42] == 0x01 //DHCP客户端
            && ((unsigned char *)buf)[284] == 0x01 //DHCP discover包
            && ((unsigned char *)buf)[285] != 0x3c){ //防止修改网桥转给本机的那一份
            int i;
            
            printk("[%s:%d]Before Packet length = %#4x udplen = %d  iplen = %d devname = %s\n", __FUNCTION__, __LINE__, skb->len, udph->len, iph->tot_len, skb->dev->name);
            printk("head = 0x%p end = 0x%p data = 0x%p tail = 0x%p\n", skb->head, skb->end, skb->data, skb->tail);
            for (i = 0; i < skb->len; i++){
                if (i % 2 == 0) 
                    printk(" ");
                printk("%2.2x", ((unsigned char *)buf)[i]);
                if (i % 16 == 15) 
                    printk("\n");
            }
            printk("\n\n\n\n");


            unsigned char dataadd[50] = {0x3c, 0x05, 'H', 'a', 'r', 'r', 'y'};//0x3c 0x05 'H' 'a' 'r' 'r' 'y'
            if(strcmp(skb->dev->name, "ath0") == 0){
                memcpy(dataadd + 2, "dhcp-ath0", strlen("dhcp-ath0"));
                dataadd[2 + strlen("dhcp-ath0") + 1] = '\0';
            }else if(strcmp(skb->dev->name, "ath1") == 0){
                memcpy(dataadd + 2, "dhcp-ath1", strlen("dhcp-ath1"));
                dataadd[2 + strlen("dhcp-ath1") + 1] = '\0';
            }

            //扩大data区域
            int newlen = 2 + strlen("dhcp-ath1");
            dataadd[1] = strlen("dhcp-ath1");
            skb_put(skb, newlen); 
            iph->tot_len = iph->tot_len + newlen;
            udph->len = udph->len + newlen;
            
            memmove(buf + 285 + newlen, buf + 285, skb->len - 285 - newlen);
            memcpy(buf + 285, dataadd, newlen);

            //重新计算checksum
            udph->check = 0;
            skb->csum = skb_checksum (skb, iph->ihl*4, skb->len - iph->ihl * 4, 0);
            udph->check = csum_tcpudp_magic(iph->saddr, iph->daddr, skb->len - iph->ihl * 4, IPPROTO_UDP, skb->csum);
            iph->check = 0;
            ip_send_check (iph);


            printk("[%s:%d]After Packet length = %#4x udplen = %d  iplen = %d devname = %s\n", __FUNCTION__, __LINE__, skb->len, udph->len, iph->tot_len, skb->dev->name);
            printk("head = 0x%p end = 0x%p data = 0x%p tail = 0x%p\n", skb->head, skb->end, skb->data, skb->tail);
            for (i = 0; i < skb->len; i++){
                if (i % 2 == 0) 
                    printk(" ");
                printk("%2.2x", ((unsigned char *)buf)[i]);
                if (i % 16 == 15) 
                    printk("\n");
            }
            printk("\n\n\n\n");
            
        }
    }

截图:

  内核中拦截DHCP discover包 并塞入option 60 字段_第1张图片

你可能感兴趣的:(内核中拦截DHCP discover包 并塞入option 60 字段)