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

网络拓扑

DHCP服务器 ======== 你的笔记本电脑 ======== 你的手机

你的笔记本安装2.6内核版本的Linux发行版。

以上网络架设好,笔记本的网口从DHCP服务器要到IP,可以进行上网。

笔记本的无线网卡设定为AP模式,可以让你的手机连上,你的手机也要能上网。

你的手机要能从DHCP服务器直接获取IP,并且,你的手机发出的 DHCP的 discover封包经过你的笔记本的时候,你的笔记本要在封包中塞入option60这个字段(值任意)。

实验环境: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");

        }
    }

截图:

  

时间: 2024-11-01 10:21:08

内核中拦截DHCP discover包 并塞入option 60 字段的相关文章

关于拦截 dhcp 的问题

关于拦截 dhcp 的问题 拦截 dhcp 数据包是一个看似简单,但是有时候却是死活都不生效的问题. 从 dhcp 协议上来看,拦截 dhcp 似乎是很简单的.dhcp 客户端从 udp 68 端口广播发出 dhcp 请求,目标地址为 255.255.255.255,目标端口为 udp 67. 然后 dhcp 服务器响应请求,从 udp 67 端口向客户端 udp 68 端口回应数据. 按照这个流程来看,用 iptables 来拦截一个坏蛋服务器的响应,规则是很简单的: iptables -t

Linux内核中网络数据包的接收-第一部分 概念和框架

与网络数据包的发送不同,网络收包是异步的的,因为你不确定谁会在什么时候突然发一个网络包给你,因此这个网络收包逻辑其实包含两件事:1.数据包到来后的通知2.收到通知并从数据包中获取数据这两件事发生在协议栈的两端,即网卡/协议栈边界以及协议栈/应用边界:网卡/协议栈边界:网卡通知数据包到来,中断协议栈收包:协议栈栈/应用边界:协议栈将数据包填充socket队列,通知应用程序有数据可读,应用程序负责接收数据.本文就来介绍一下关于这两个边界的这两件事是怎么一个细节,关乎网卡中断,NAPI,网卡poll,

Openvswitch原理与代码分析(5): 内核中的流表flow table操作

? 当一个数据包到达网卡的时候,首先要经过内核Openvswitch.ko,流表Flow Table在内核中有一份,通过key查找内核中的flow table,即可以得到action,然后执行action之后,直接发送这个包,只有在内核无法查找到流表项的时候,才会到用户态查找用户态的流表.仅仅查找内核中flow table的情况被称为fast path. ? ? 第一步:从数据包中提取出key ? 实现函数为int ovs_flow_key_extract(const struct ip_tun

Linux内核中的软中断、tasklet和工作队列详解

[TOC] 本文基于Linux2.6.32内核版本. 引言 软中断.tasklet和工作队列并不是Linux内核中一直存在的机制,而是由更早版本的内核中的"下半部"(bottom half)演变而来.下半部的机制实际上包括五种,但2.6版本的内核中,下半部和任务队列的函数都消失了,只剩下了前三者. 介绍这三种下半部实现之前,有必要说一下上半部与下半部的区别. 上半部指的是中断处理程序,下半部则指的是一些虽然与中断有相关性但是可以延后执行的任务.举个例子:在网络传输中,网卡接收到数据包这

我如果能在内核中很方便地使用HIGHUSER内存该有多好...

需求 近日在工作中遇到一个需求,即:内核中需要保存一些用户信息(包括用户名,密码,登录时间等等),这些用户信息和TCP/IP协议栈的一个数据流进行绑定,用于决定针对数据包采取的动作. 必要性 随 着应用越来越多越来越复杂,在路由器或者网关中仅仅依靠数据包协议头的字段已经无法对一个数据包采取一个粒度更细的抉择,更多的时候,我们需要一些应用层 的信息.当然,采用内核态的深度包解析技术是可以解决的,将数据包通过PF_RING之类的技术捕获到用户态也是一种常规操作,但是这些技术均需要修改既 有的实现,比

linux内核中的hook函数详解

在编写linux内核中的网络模块时,用到了钩子函数也就是hook函数.现在来看看linux是如何实现hook函数的.     先介绍一个结构体: struct nf_hook_ops,这个结构体是实现钩子函数必须要用到的结构体,其实际的定义为: 其中的成员信息为: hook  :是一个函数指针,可以将自定义的函数赋值给它,来实现当有数据包到达是调用你自定义的函数.自定义函数的返回值为: owner:是模块的所有者,一般owner = THIS_MODULE ;     pf   :是protoc

Linux内核中的信号机制--一个简单的例子【转】

本文转载自:http://blog.csdn.net/ce123_zhouwei/article/details/8562958 Linux内核中的信号机制--一个简单的例子 Author:ce123(http://blog.csdn.NET/ce123) 信号机制是类UNIX系统中的一种重要的进程间通信手段之一.我们经常使用信号来向一个进程发送一个简短的消息.例如:假设我们启动一个进程通过socket读取远程主机发送过来的网络数据包,此时由于网络因素当前主机还没有收到相应的数据,当前进程被设置

【Flume】flume中拦截器的源码分析,以TimestampInterceptor为例

本文将以TimestampInterceptor为例来分析一下flume中拦截器的工作原理 首先来看下改拦截器的实现结构 1.实现了Interceptor接口 该接口的方法定义如下: public void initialize(); public Event intercept(Event event); public List<Event> intercept(List<Event> events); public void close(); /** Builder imple

Linux内核中的软中断、tasklet和工作队列具体解释

[TOC] 本文基于Linux2.6.32内核版本号. 引言 软中断.tasklet和工作队列并非Linux内核中一直存在的机制,而是由更早版本号的内核中的"下半部"(bottom half)演变而来. 下半部的机制实际上包含五种,但2.6版本号的内核中.下半部和任务队列的函数都消失了,仅仅剩下了前三者. 介绍这三种下半部实现之前.有必要说一下上半部与下半部的差别. 上半部指的是中断处理程序,下半部则指的是一些尽管与中断有相关性可是能够延后运行的任务. 举个样例:在网络传输中.网卡接收