【项目分析】网络嗅探器

系列综述:
💞目的:本系列是个人整理为了秋招项目的,整理期间苛求每个知识点,平衡理解简易度与深入程度。
🥰来源:该项目源于国科大网络攻防基础的课程实验作业
🤭结语:如果有帮到你的地方,就点个赞关注一下呗,谢谢🎈🎄🌷!!!
🌈项目github链接🌈
🌈【C++】秋招&实习面经汇总篇🌈

项目解释
  1. 我们通常的网络数据传输过程实际是,主机上的应用程序数据作为数据部分SDU,再在首部添加应用层的控制部分PCI,然后两个部分合成一个协议数据单元PDU。作为传输层的数据部分,再层层向下传递并包裹各层自己的PCI,最终在物理层形成比特流通过光电信号传输到另一台主机的网卡上。我做的是解析部分,另一台主机收到比特流进行层层解析,最终将数据传输给应用程序。
  2. 具体解析流程
    • 物理层解析:PCI(7字节前同步码+1字节的帧开始定界符)+ SDU(MAC帧)
    • 链路层解析:每一个MAC帧有1518字节,其中前14字节是PCI(6Byte目的MAC地址 + 6Byte源MAC地址 + 2Byte类型),中间是数据部分,最后4字节是循环冗余校验码
    • 网络层解析:根据上层类型字段,进行不同协议的解析,主要包含IP、ARP和RARP
    • 再不断解析,直到应用层将数据部分发送给应用程序
  3. 软件执行流程
    • 在下拉框控件中,选择要捕获的本地网卡
    • 通过模态对话框(完成当前对话框任务才能进行下一步)进行过滤规则的设置,生成BPF过滤规则字符串
    • 在主对话框中解析该字符串获取过滤信息
    • 创建消息处理线程,针对选择的网卡建立嗅探对话,编译集成过滤规则,开始捕获链路层数据帧,并放入消息队列中。
    • 确认控件可以创建线程、并可以中止和重启线程
    • 注册OnMessageWinPcap()可以获取消息队列并对每个消息进行处理
      • AppendPacket()可以将数据包追加到缓存文件中,后面进行调用显示
      • analysisData()进行数据的分析,并显示在listControl控件上
      • ShowStatisticInfo()显示计数到控件组中
实验概述

实验名称:嗅探器设计与实现
操作系统:Windows
实验平台:Visual Stdio 2022
语言:C++

项目设计原理

image-20220330191902976

  1. 传输单位

    • 协议数据单元PDU = PCI(传输控制信息)+SDU(服务数据单元),是对等实体间的数据传送单位
    • PDU在物理层称为比特,在链路层称为帧,在网络层称为分组,在传输层称为报文
    • n-SDU + n-PCI = n-PDU = (n-1)SDU
  2. 垂直方向

    • 原理:发送方将用户数据层层包裹下放,再将数据以透明比特流形式发送,接收方将用户数据层层拆解分析
    • 中间层:中间各层使用其下一层提供的接口,实现自身功能并向上层提供服务
    • 上层和下层:最底层只能向上层提供服务,最高层面向用户进程提供服务
  3. 水平方向

    • 对等实体在逻辑上有一条直接信道
  4. TCP/IP五层网络结构

    • 应用层:添加的首部协议为HTTP、HTTPS、FTP、POP3、SMTP等。
    • 运输层:添加的首部协议为TCP、UDP
    • 网络层:添加的首部协议为IP、ICMP、IGMP、ARP、RARP
    • 链路层:添加MAC帧首部
    • 物理层:常用设备有集线器、中继器、调制解调器、网线、双绞线、同轴电缆。
      在这里插入图片描述
  5. 网络层数据帧组成结构
    image-20220330161900597

  6. MAC帧结构 image-20220330111955352

    • 前同步码:7 byte,用来使接收端的适配器在接收 MAC 帧时能够迅速调整到与发送端相同的时钟频率
    • 帧开始定界符:1 byte,告诉接收端适配器:“帧信息要来了,准备接收”。
    • MAC帧
      • 目的地址: 6 byte, 接收帧的网络适配器的物理地址(MAC 地址)
      • 源地址: 6 byte, 发送帧的网络适配器的物理地址(MAC 地址)
      • 类型:2byte(协议名称 十六进制的表示)
        • IPV4 0x0800
        • IPV6 0x86DD
        • ARP 0x0806
        • RARP 0x8035
        • PPP 0x880B
        • ···
    • IP数据报:长度为46 byte ~ 1500 byte,由前面的MAC的类型字段决定
  7. IP数据报组成
    在这里插入图片描述

    • 版本:4 bits,表明IP协议实现的版本号,当前一般为IPv4,即0100。
    • 报头长度IHL:4 bits,表示IP报文头部按4字节计数的长度,即报文头的长度等于IHL的值乘以4
    • 服务类型:8 bits,前3bits为优先权子字段。中间4bits取1依次表示为最小时延、最大吞吐量、最高可靠性和最小费用,全为0则表示一般服务,第8比特保留未用常置0。
    • 总长度字段:16 byte,指明整个数据报的长度(以字节为单位)。最大长度为65535字节。
    • 标志字段:16 byte,用来唯一地标识主机发送的每一份数据报。通常每发一份报文,它的值会加1。
    • 标志位字段:3 byte,标志数据报是否要求分段。
    • 段偏移字段:13 byte,若该数据报要求分段的话,此字段指明该段偏移距原始数据报开始的位置
    • 生存期TTL:8 byte,用来设置数据报最多可以经过的路由器数。每经过一个路由器,其值减1,直到0时该数据报被丢弃。
    • 协议字段:8 byte,指明IP层所封装的上层协议类型ICMP(1)、IGMP(2) 、TCP(6)、UDP(17)···
    • 头部校验和字段:16 byte,内容是根据IP头部计算得到的校验和码。
    • 源IP地址字段:32 byte,发送IP数据报文的源主机IP地址
    • 目标IP地址字段:32 byte,发送IP数据报文的目的主机IP地址
    • 可选项字段:32 byte,用来定义一些任选项:如记录路径、时间戳等。可选项字段的长度必须是32比特的整数倍,如果不足,必须填充0以达到此长度要求
  8. 0x08DD表示数据帧结构是IPV6的报文格式
    在这里插入图片描述

    • 版本号:4 bits,4表示为IPV4;6表示为IPV6
    • 流量等级:8 bits,以区分业务编码点(DSCP)标记一个IPv6数据包,以此指明数据包应当如何处理
    • 流标签:20 bits,用来标记IP数据包的一个流,当前的标准中没有定义如何管理和处理流标签的细节
    • 数据长度:16 bits,表示有效载荷的长度,指紧跟IPv6基本报头的数据包,包含IPv6扩展报头
    • 下一报头:8 bits,指明了跟随在IPv6基本报头后的扩展报头的信息类型。
    • 跳限制:8 bits,定义了IPv6数据包所能经过的最大跳数
    • 源地址:128 bits,表示该报文的源地址
    • 目的地址:128 bits,表示该报文的目的地址
    • 可变拓展报头
  9. 0x0806表示数据帧结构是ARP的报文格式
    在这里插入图片描述

    • 硬件类型:2 byte,用来定义运行ARP的网络类型
    • 协议类型:2 byte,用来定义使用的协议。
    • 硬件长度:1 byte,用来定义物理地址的长度,以字节为单位。
    • 协议长度:1 byte,用来定义逻辑地址的长度,以字节为单位。
    • 操作码:2 byte,用来定义报文的类型。已定义的分组类型有两种:ARP请求(1),ARP响应(2)。
    • 源硬件地址:对于以太网为6 byte,用来定义发送方的物理地址。
    • 源逻辑地址:对于IP协议为4byte,用来定义发送方的IP地址。
    • 目的硬件地址:对于以太网为6 byte,用来定义发送方的物理地址。ARP请求报文,这个字段为全0
    • 目的逻辑地址:对于IP协议为4byte,用来定义接受方的IP地址。
    • padding字段:真正发包的时为了保证以太网帧的最小帧长为64 bytes,用来填充数据包大小
项目设计
  1. 获取网卡
    • 在下拉框控件中,使用GetAllAdapter()获取本地的网卡信息
    • 获取的网卡信息是pcap_if_t类型的链表,每个元素存储了一个网卡的信息
    • 点击确定控件时 ,会获取下拉框的位号,由于链表头使用的是全局变量,所以根据索引可以得到网卡信息的结构体
    • 获取网卡结构体的name,注意description属性是网卡的型号并不唯一
  2. 设置过滤规则
    • 创建一个模态对话框(完成当前对话框任务才能进行下一步),通过filterName进行过滤规则信息的传递
    • 在主对话框中解析该字符串获取过滤信息
  3. 创建消息处理线程
    • setFilterRule()进行数据帧的处理
      • 使用pcap_findalldevs_ex()获取设备链表
      • 使用pcap_open()建立嗅探会话
      • 使用pcap_compile()编译集成过滤规则
      • 使用pcap_setfilter()关联过滤器和抓包驱动
      • 使用pcap_next_ex()捕获链路层数据帧
      • 使用pcap_findalldevs_ex()获取设备链表
    • packet_handler()每次获取一个网卡的数据封装成消息并放进消息队列中
    • 确认控件会创建线程、并可以中止和重启线程
    • 注册OnMessageWinPcap()可以获取消息队列并对每个消息进行处理
      • AppendPacket()可以将数据包追加到缓存文件中,后面进行调用显示
      • analysisData()进行数据的分析,并显示在listControl控件上
      • ShowStatisticInfo()显示计数到控件组中
问题处理
  1. List Control控件加载数据出现错行问题

    一开始我以为是,因为多线程出现数据的不同步问题,但是通过对于analysisData函数,进行加锁的处理,并没有解决问题。后来发现是控件的绘制属性问题,如果进行绘制属性为倒序排列,则会出现每次刷新的绘制错乱问题。

  2. List Control控件一直出现闪烁

    对控件的属性进行调整,打开控件的双缓冲即可

  3. 获取的是网卡的名称编码一直乱码

    解决:实际获取网卡结构体中name属性是网卡的编码,网卡的型号名称应该是describtion属性

  4. “char *” 类型的实参与 “LPCTSTR” 类型的形参不兼容

解决:因为编辑器默认编码是Unicode字符集,因此只需要在 项目 - 属性 - 常规 中把字符集修改为**“未设置”**即可。后面又出现了list Control控件的时间乱码问题,需要使用Unicode字符集合,再使用其他转化函数转换其他字符集。

  1. 以上记录了几个比较棘手的bugs,当然还有其他已经解决的问题···
参考文档
  1. C/C++ Npcap包实现数据嗅探
    https://www.cnblogs.com/LyShark/p/12989949.html)https://www.cnblogs.com/LyShark/p/12989949.html

  2. WinPcap笔记(7)
    https://blog.csdn.net/u012877472/category_5949949.html?spm=1001.2014.3001.5482

  3. wincap获取数据包的两种方式

    https://www.cnblogs.com/codergeek/p/3479890.html

  4. mac帧结构

    https://www.cnblogs.com/cs-lcy/p/7462072.html

    http://c.biancheng.net/view/6391.html

    https://blog.csdn.net/eydwyz/article/details/65446328

  5. HTTP协议详解
    https://blog.csdn.net/weixin_33594195/article/details/113078806

  6. MFC+WinPcap编写一个嗅探器之零(目录)

    https://www.cnblogs.com/raichen/p/4135384.html

  7. MFC教程
    https://www.bilibili.com/video/BV1JW41147NX?p=6&spm_id_from=pageDriver

  8. 过滤规则

    https://blog.csdn.net/a714804968/article/details/107299742?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_baidulandingword~default-0.pc_relevant_default&spm=1001.2101.3001.4242.1&utm_relevant_index=3

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逆羽飘扬

如果有用,请支持一下。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值