网络嗅探器(Sniffer)的原理与实现(1)

本文深入介绍了TCP/IP协议的四个层次结构及其功能,包括网络协议层、互联协议层、传输层和应用层。同时,详细解释了关键协议如ARP、RARP、TCP、UDP等的工作原理及数据包在网络中的传输方式。

.背景

为了使不同体系结构的计算机网络都能进行互联,国际标准化组织ISO1997年成立了专门的结构研究这个问题。不久他们就提出了一个试图使各种计算机在世界范围内都能互联的成网的标准框架,即著名的OSI/RM(Open Systems Interconnection Reference Model , 开放系统互联基本参考模型),简称为OSI。它的主要目标是:只要遵循OSI标准,一个系统就可以和位于世界任何地方的,也遵循同一标准的其他任何系统进行通信。

OSI采用分层结构,每一层完成不同的功能,较好地从理论上解决了不同系统之间互联的难题。但是由于OSI模型归于复杂以及种种原因,当它被制定出来时,TCP/IP已经成为事实上的国际标准。

 

二.TCP/IP 4层结构

通常意义上的TCP/IP结构共有4层协议,从下到上依次是网络协议层,互联协议层,传输层和应用层,不同的层次上运行的协议也不同。

1.网络协议层

网络协议层工作在TCP/IP模型的最底层,它负责将数据通过电缆传送出去,并将接收到的信号通过网卡驱动转换成计算机能够识别的数据。主要是管理网络数据包的接收很发送,在操作系统中主要体现在设备驱动程序和网络接口。对应各种网络通信介质,不同的通信网络有其不同的访问协议,例如通常用的以太网和PPP等。

运行至这一层的协议主要有:Ethernet 802.3等等。

 

2.互联协议层

互联协议层是十分重要的一层,网卡驱动将解析后的数据递交给互联协议层,互联协议层的工作主要就是对这些混乱的数据进行解析,然后分门别类地传递给不同的上层协议。

运行在这一层的协议主要由:IP( Internet Protocol )ICMP( Internet Control Message Protocol ),ARP( Address Resolution Protocol , 地址转换协议),RARP( Reverse Address Resolution Protocol .反向地址解析协议)

 

3.传输层协议

传输层协议有两个具有代表性的协议,分别是TCP( Transmission Control Protocol , 传输控制协议UDP( User Datagram Protocol ,用户数据报协议)。

TCP的面向连接的通信协议,通过三次握手建立连接,通信完后要断开连接。由于它是面向连接的协议,那么它只能用于点对点之间的通信。TCP是一种可靠的数据流服务,采用“重传”和“肯定确认”机制来实现传输的可靠性。TCP还采用一种滑动窗口的方式进行流量的控制。所谓的窗口表示的是接收能力,用于限制发送方的发送速度。

UDP是面向无连接的通信协议,UDP数据包括目的端口号和源端口号信息,由于通信不需要连接,所以它可以实现广播发送。UDP通信时不需要接收方的确认,属于不可靠的传输,可能会出现丢包的现象,实际应用中要求在程序员编程验证。

 

4.应用层协议

应用层协议一般是面向用户的服务,如FTPTelnet,DNSSMTPPOP3等。

 

四.相关概念详解

1.ARP/RARP

 

ARP/RARP协议是进行IP地址和MAC地址相互转换的协议。在网络数据通信中,链路层使用MAC地址进行实际的数据通信,而在网络层使用IP地址进行机器定位寻址。ARP协议把IP地址映射为MAC地址,而RARP协议是通过MAC地址映射为IP地址。

 

ARP请求应答报文是一种比较常用的数据包,它的主要目的是找到IP地址对应的MAC地址。利用ARP请求报文来获得其MAC地址。这个过程是这样的:

首先发送ARP请求报文,它是以广播的方式发送到网络上的,每一台机器都会收到这个ARP请求报文,它是以广播方式发送到网络上的,每个机器都会收到这个ARP请求报文。在这个ARP请求报文中,发送端以太网地址字段是发送ARP请求报文机器的MAC地址,而且发送端IP字段内容是要查询的MAC的主机的IP地址。当某个主机检查到自己的IP地址是目的IP地址时,它会返回一个ARP应答报文,在此应答报文中,其发送端以太网地址字段内容就是要查询的MAC地址。

一个主机里面一般有ARP缓存,里面存储了IP地址和MAC地址对。

 

2.交换网络

 

在共享网络中,把网卡设为混杂模式就可以监听所有的网络数据包,但是在交换网络中,情况就发生了变化。

以太网分为共享式以太网和交换式以太网,共享式以太网通常以集线器作为网络设备,交换式以太网通常使用交换机作为网络连接设备。共享式以太网中数据帧以广播方式传送到每个以太网端口,网内每台主机的网卡能接收到网内的所有数据帧。因此只要把网卡设置成为混杂模式就可以获取到这本地网卡的所有数据帧。

最典型的交换网络使用交换机连接,在交换机中可以设为一个端口一个MAC地址,形成一个端口一个MAc地址对。这样当网络数据包到达端口时,而不是转发给所有的端口,只是转发MAC对应的端口。这样,其他端口的通讯不受干扰,所以其他端口上的主机就无法接收到网络上的数据包了。

可以利用ARP重定向技术来实现交换网络的数据包捕获,其主要原理用到了ARP欺骗技术,但此方法有一定的危险性。另外有的交换机上有一个用于调试的端口,任何其他端口的通信数据都会出现在此端口上,所以也可以在此端口上进行网络数据包的监听工作。

 

3.数据包在局域网内的传输方式

 

众所周知,数据包在互联网上的传播是根据IP地址进行寻址的,但是完整的过程并非如此。数据包通过IP地址可以达到的最远的地点就是目标主机所在的子网,而在该子网内的寻址却是使用物理地址的,即MAC地址。

数据包被传送到目标主机所在的子网时,它将被交给路由器,路由器在该子网内使用广播方式传播出去,这意味着该子网内的虽有主机都可以接收到该数据包。不过主机接收到数据包后通常会先检查其目的地址,如果目的地址不是自己,那么就是丢弃,只有目的地址为自己的数据包才会将其交付给上一层处理。

Sniffer将网卡设置为混杂模式,这样就可以接收到所有的数据包了,达到了嗅探了目的。

网卡对接收到的数据包经过一步步的解析之后就得到了最终的应用程序报文,此时就可以清晰易懂地看出它所包含的内容。

 

四. 网络抓包用到的技术

1.原始套接字编程

2.Winpcap编程

使用Winpcap来生成数据包比使用原始套接字更加灵活,功能更加丰富。在基于原始套接字方法中,由于原始套接字的某些限制,其构造的数据包最底层协议的数据包只能是IP数据包不能够构造IP层以下的协议数据包,例如链路层数据包就不能构造,而使用Winpcap可以构造基于链路层的数据包。

使用WinPcap构造数据包与使用原始套接字构造数据包是不同的。在原始套接字里面构造的数据包是从IP层开始的,而在WinPcap中是从链路层开始构造的。也就是说,在WinPcap中药构造一个Ip数据包,需要先构造链路层首部,在这里是以太网首部,然后再构造Ip首部,最后才是IP负载数据。而在原始套接字中直接从IP层开始构造,所以只需要构造IP首部和负载数据就可以了。

五.简单嗅探器的具体实现解析

 

定义一个IP

 

typedef  struct IPHEAD

{

    unsigned char h_len:4;          //4位首部长度+4IP版本号

    unsigned char ver:4;

    unsigned char tos;              //8位服务类型TOS

    unsigned short total_len;        //16位总长度(字节)

    unsigned short ident;           //16位标识

    unsigned short frag_and_flags;   //3位标志位

    unsigned char ttl;              //8位生存时间 TTL

    unsigned char proto;           //8位协议 (TCP, UDP 或其他)

    unsigned short checksum;       //16IP首部校验和

    unsigned int sourceip;          //32位源IP地址

    unsigned int destip;            //32位目的IP地址

}IPHEAD;

 

 

 

 

 

 

 

 

 

 

定义TCP头部

 

typedef  struct TCPHEAD 

{

USHORT th_sport;            //16位源端口

USHORT th_dport;            //16位目的端口

unsigned int th_seq;            //32位序列号

unsigned int th_ack;            //32位确认号

unsigned char th_lenres;         //4位首部长度/6位保留字

unsigned char th_flag;           //6位标志位

USHORT th_win;               //16位窗口大小

USHORT th_sum;              //16位校验和

USHORT th_urp;              //16位紧急数据偏移量

}TCPHEAD ;

 

接收数据信息:

 

IPHEAD  piphd=(struct IPHEAD *)cbuf;                 //取得IP头数据的地址

int iIphLen = sizeof(unsigned long) * (piphd->h_len  & 0xf);

TCPHEAD  ptcphd=(struct TCPHEAD *)(cbuf+iIphLen);   //取得TCP头数据的地址

 

得到头部中的信息,直接引用即可:

 

printf("From:%s\tport%d\t",inet_ntoa(*(structin_addr*)&piphd->sourceip),ntohs(ptcphd->th_sport) );

   

printf("To:%s\tport%d",inet_ntoa(*(structin_addr*)&piphd->destip),ntohs(ptcphd->th_dport));

 

 

判断协议类型:

 

switch(piphd->proto)       //根据IP头的协议判断数据包协议类型

        {

        case 1:

            printf("ICMP\n");

            break;

        case 2:

            printf("IGMP\n");

            break;

        case 6:

            printf("TCP\n");

            break;

        case 17:

            printf("UDP\n");

            break;

        default:

            printf("unknow:%d\n",piphd->proto);

        }

}

 

<think>好的,我现在需要帮助用户解决在RK3568平台上找不到rockchip_drm_vop文件的问题。根据用户之前的提问和我的回答,用户已经尝试了一些排查步骤,但问题仍然存在。现在用户明确询问如何在Buildroot系统中启用特定的内核配置选项(CONFIG_DEBUG_FS、CONFIG_DRM_ROCKCHIP和CONFIG_ROCKCHIP_VOP),并确认rockchip_drm_vop的存在。 首先,我需要回忆一下Buildroot系统中如何配置内核选项。Buildroot通常通过menuconfig或者手动修改配置文件来设置内核选项。用户可能需要进入内核配置菜单,找到相关的调试和DRM驱动选项,确保它们被启用。同时,用户提供的引用中提到了GPIO冲突和Buildroot系统的一些问题,这可能影响到驱动的加载,但用户现在的问题更侧重于配置选项的启用,所以需要先解决配置问题。 接下来,用户提到的CONFIG_DEBUG_FS是必须的,因为debugfs是内核调试文件系统,没有它的话,/sys/kernel/debug目录下的内容可能无法正确生成。另外,CONFIG_DRM_ROCKCHIP和CONFIG_ROCKCHIP_VOP是Rockchip DRM驱动和VOP(显示输出处理器)的配置选项,必须启用才能加载相应的驱动模块。 然后,我需要考虑用户可能遇到的常见问题。例如,用户是否正确进入了内核的配置界面?是否保存了配置更改?编译后是否重新部署了内核映像?此外,用户可能在Buildroot中配置内核时,没有正确选择这些选项,或者配置后没有重新编译和安装内核。 另外,用户提供的引用中提到了GPIO复用冲突的问题,这可能导致VOP驱动无法正常初始化。虽然用户现在的问题是关于配置选项,但GPIO冲突也可能是一个潜在原因,需要后续排查。 现在需要分步骤指导用户如何启用这些配置选项,并验证是否生效。首先,进入Buildroot的内核配置,确保相关选项被选中。然后,重新编译内核并部署到设备上。之后,检查内核启动日志,确认驱动是否加载,以及debugfs是否正确挂载。 同时,用户可能需要检查编译后的内核配置文件(.config),确认选项是否确实被启用。如果配置正确但问题依旧,可能需要进一步检查硬件兼容性或其他内核参数。 最后,需要提醒用户在修改配置后,清理旧的编译结果,确保新配置被应用。此外,可能还需要检查设备树配置,确保VOP相关的节点正确无误。 总结来说,回答需要详细步骤:如何配置内核选项,编译,部署,验证,以及后续的故障排查建议。同时,结合用户之前提到的GPIO冲突问题,可能需要建议用户检查引脚复用情况,但这可能属于后续步骤,如果基本配置正确但问题依旧存在的话。</think>### 在Buildroot系统中启用DRM_VOP调试功能的完整方案 --- #### 一、内核配置修正步骤 1. **进入内核配置界面** ```bash # 在Buildroot工程目录执行 make linux-menuconfig # 进入内核配置界面 ``` 2. **关键配置项定位** 使用快捷键定位: - **CONFIG_DEBUG_FS**:按`/`搜索`DEBUG_FS`,路径为: ``` Kernel hacking -> Debug Filesystem (DEBUG_FS) ``` - **CONFIG_DRM_ROCKCHIP**:按`/`搜索`DRM_ROCKCHIP`,路径为: ``` Device Drivers -> Graphics support -> DRM Support for Rockchip ``` - **CONFIG_ROCKCHIP_VOP**:按`/`搜索`ROCKCHIP_VOP`,路径为: ``` Device Drivers -> Graphics support -> Rockchip VOP Driver ``` 3. **配置选项验证** 确保以下选项状态: | 配置项 | 正确状态 | 验证方法 | |-------|---------|----------| | CONFIG_DEBUG_FS | `[*]` | 检查`.config`文件第1876行 | | CONFIG_DRM_ROCKCHIP | `<*>` | 检查`.config`文件第4892行 | | CONFIG_ROCKCHIP_VOP | `<*>` | 检查`.config`文件第4901行 | --- #### 二、Buildroot工程配置验证 1. **内核编译配置继承** 修改`buildroot/configs/rockchip_rk3568_defconfig`文件,增加: ```makefile BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="$(BR2_EXTERNAL_ROCKCHIP_PATH)/configs/kernel_debug.config" ``` 2. **创建内核调试配置片段** 在`configs/kernel_debug.config`文件中写入: ```config # DRM调试配置 CONFIG_DEBUG_FS=y CONFIG_DRM_ROCKCHIP=y CONFIG_ROCKCHIP_VOP=y CONFIG_DRM_DEBUG_MODESET=y ``` --- #### 三、编译验证流程 1. **完整编译部署** ```bash make clean && make linux-rebuild all -j$(nproc) ``` 2. **烧录验证** ```bash # 查看新生成的内核镜像 ls output/images/Image -lh # 烧录到开发rkdeveloptool write-partition 0x20000 output/images/Image ``` --- #### 四、系统级验证方法 1. **内核启动日志检查** ```bash dmesg | grep -E "drm|vop|rockchip" ``` 关键日志应显示: ``` [drm] Initialized rockchip 3.0.0 20140818 rockchip-drm display-subsystem: bound ff600000.vop (ops vop_component_ops) ``` 2. **debugfs文件树验证** ```bash # 确认debugfs挂载状态 mount | grep debugfs # 查看VOP调试节点 ls /sys/kernel/debug/dri/0/rockchip_drm_vop ``` 正常应显示: ``` enable fifo_level format state ``` --- #### 五、GPIO冲突解决方案(参考引用[1]) 1. **引脚复用状态检查** ```bash # 检查GPIO3A3复用状态 io -4 0xfe770000+0xA0 # GRF_GPIO3A_IOMUX_L ``` 正常值应为`0x00040000`(对应lcd0-rst-gpio) 2. **设备树修正** 在`arch/arm64/boot/dts/rockchip/rk3568.dtsi`中修改: ```diff &vop { status = "okay"; + assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>; + assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>; }; ``` --- ### 关键配置验证表 | 验证项目 | 成功标志 | 失败处理 | |---------|----------|----------| | DEBUG_FS状态 | `/sys/kernel/debug`目录存在 | 检查内核`Kernel hacking`配置 | | VOP驱动加载 | `dmesg`显示VOP绑定成功 | 验证设备树时钟配置 | | GPIO复用 | `io`命令显示正确复用值 | 修改设备树iomux节点 | [^1]: RK3568技术参考手册第7.3节GPIO复用配置要求 [^2]: Linux内核文档Documentation/gpu/rockchip-drm.rst
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值