计算机网络实验报告完整版
计算机网络实验报告
实验一 wireshark 抓包工具使用
一、实验目的
- 学习wireshark抓包工具的使用。
- 了解wireshark抓包工具的功能,明确抓包软件的功能。
- 通过学习,进一步理解协议及网络体系结构思想。
二、实验原理
Wireshark
是网络包分析工具。网络包分析工具的主要作用是尝试捕获网络包,并尝试显示包的尽可能详细的情况。
主要应用:
- 网络管理员用来解决网络问题
- 网络安全工程师用来检测安全隐患
- 开发人员用来测试协议执行情况
- 用来学习网络协议
三、实验内容
下载 WIRESHARK,学习工具的使用和功能。
四、实验过程
1、wireshark 的下载、安装与配置
访问 wireshark 官网:https://www.wireshark.org/
下载并安装 Windows Installer (64-bit) 版本。
2、初识 wireshark
Wireshark 的工作原理是捕获某一网卡的数据包,当配置多块网卡时,需要选择一块网卡进行抓包,此处选择 WLAN,然后双击即可。
3、查看网络环境
控制面板-网络和Internet-网络和共享中心-更改适配器设置-WLAN-状态-详细信息,得到了以下关键信息:
名称 | 地址 |
---|---|
IPv4 地址 | 10.19.128.57 |
子网掩码 | 255.255.248.0 |
默认网关 | 10.19.135.254 |
4、启动抓包
截图显示的是 wireshark 抓到的部分数据包,有 TCP、UDP、ARP、MDNS、ICMPv6 等多种协议的数据包。
名称 | 对应层次 |
---|---|
Frame | 物理层 |
Ethernet Ⅱ | 数据链路层 |
Internet Protocol Version 4 | 网络层 |
Transmission Control Protocol | 传输层 |
Hypertext Transfer Protocol | 应用层 |
5、追踪打开一个网页时,TCP 的三次握手
以访问百度为例,首先,打开浏览器的一个无痕窗口,并确保电脑上的代理处于关闭状态,然后过滤出 DNS 我们可以发现解析百度的包,找到解析后的真实 ip,
然后设置过滤规则:
ip.src == 182.61.200.7 or ip.dst == 182.61.200.7
将过滤出来的包按时间排序,开头的三个包是TCP 的三次握手,
- 第一次握手:客户机(10.19.128.57)主动打开一条TCP连接,从客户机(10.19.128.57)发送报文段至服务器(182.61.200.7):SYN=1,Seq=0,不携带数据,等待服务器确认。
- 第二次握手:服务器(182.61.200.7)返回确认报文至客户机(10.0.0.108):SYN=1,ACK=1,Seq=0,不携带数据。
- 第三次握手:从客户机(10.19.128.57)发送报文段至服务器(182.61.200.7):ACK=1,Seq=1,不携带数据,TCP连接正式建立。
下图为第二次握手的报文段的详细分析:
实验二 winpcap 编程
实验目的
- 了解 winpcap 的架构
- 学习 winpcap 编程
实验原理
WinPcap是一个基于Win32平台的,用于捕获网络数据包并进行分析的开源库。
大多数网络应用程序通过被广泛使用的操作系统元件来访问网络,比如sockets。这是一种简单的实现方式,因为操作系统已经妥善处理了底层具体实现细节(比如协议处理,封装数据包等等),并且提供了一个与读写文件类似的,令人熟悉的接口。
然而,有些时候,这种“简单的方式”并不能满足任务的需求,因为有些应用程序需要直接访问网络中的数据包。也就是说,那些应用程序需要访问原始数据包,即没有被操作系统利用网络协议处理过的数据包。
WinPcap产生的目的,就是为Win32应用程序提供这种访问方式;WinPcap提供了以下功能:
- 捕获原始数据包,无论它是发往某台机器的,还是在其他设备(共享媒介)上进行交换的
- 在数据包发送给某应用程序前,根据用户指定的规则过滤数据包
- 将原始数据包通过网络发送出去
- 收集并统计网络流量信息
以上这些功能需要借助安装在Win32内核中的网络设备驱动程序才能实现,再加上几个动态链接库DLL。
所有这些功能都能通过一个强大的编程接口来表现出来,易于开发,并能在不同的操作系统上使用。
WinPcap可以被用来制作网络分析、监控工具。一些基于WinPcap的典型应用有:
- 网络与协议分析器 (network and protocol analyzers)
- 网络监视器 (network monitors)
- 网络流量记录器 (traffic loggers)
- 网络流量发生器 (traffic generators)
- 用户级网桥及路由 (user-level bridges and routers)
- 网络入侵检测系统 (network intrusion detection systems (NIDS))
- 网络扫描器 (network scanners)
- 安全工具 (security tools)
实验内容
通过学习WINPCAP架构,编写一个网络抓包程序。
实验过程
首先要说明一点,winpcap 官网建议使用 npcap,因为根据官网说明,winpcap 已经不适用于 windows10 和 windows11,有些函数可能会出现意想不到的效果。根据我的实践,发现winpcap无法获取适配器的具体名称,比如我的 wifi6 适配器,使用 winpcap 就只能获取模糊的 "Microsoft" 这个名称,而使用 npcap 就可以获取其完整的名称,而且 winpcap 或识别不了一些适配器,而这一点在 npcap 上得到了很好的改善。
1、npcap 的下载安装与配置
- 访问npcap官网:https://www.winpcap.org/
- 选择npcap的最新版,下载Installer for Windows并安装
- 在VS中导入相应头文件和lib文件
安装配置的详细过程见我的这一篇博客,这里不再赘述。
2、获取设备列表
通常情况下,一个基于Npcap的应用程序所做的第一件事就是获得一个连接的网络适配器的列表。libpcap和Npcap都为这个目的提供了cap_findalldevs_ex()
函数:这个函数返回一个cap_if
结构的链接列表,每个结构都包含一个连接的适配器的全面信息。特别是,字段name
和description
分别包含了相应设备的名称和可读的描述。
下面的代码检索适配器列表并显示在屏幕上,如果没有找到适配器,则打印一个错误。
运行结果:
下面利用控制面板查看到的网络适配器:
注:可以发现,通过程序打印出来的适配器列表和通过 windows 的设备管理器查看到的适配器列表有一些区别,主要是数量上的区别。已经打印出来的部分都可以和设备管理器中的对应得上。
关于这个代码的一些注释如下。
首先,pcap_findalldevs_ex()
和其他libpcap函数一样,有一个errbuf
参数。这个参数指向一个由libpcap填充的字符串,其中包括出错时的错误描述。
其次,请记住,并不是所有的操作系统都由libpcap支持,提供网络接口的描述,因此,如果我们想写一个可移植的应用程序,我们必须考虑描述为空的情况:在这种情况下,我们打印字符串"No description available"。
最后注意,当我们用完这个列表后,我们用pcap_freealldevs()
释放它。
假设我们已经编译了该程序,让我们试着运行它。在我的 Windows10 系统上,我们得到的结果是
3、获取已安装设备的高级信息
上一部分(名为 "获取设备列表
"的部分)演示了如何获取关于可用适配器的基本信息(即设备名称和描述)。实际上,Npcap还提供了其他高级信息。特别是,由pcap_findalldevs_ex()
返回的每个cap_if
结构都包含一个cap_addr
结构的列表,其中包括:
- 该接口的地址列表。
- 一个网络掩码的列表(每个掩码对应于地址列表中的一个条目)。
- 广播地址的列表(每个地址对应于地址列表中的一个条目)。
- 目标地址的列表(每个地址对应于地址列表中的一个条目)。
此外,cap_findalldevs_ex()
还可以返回远程适配器和位于指定本地文件夹中的pcap文件列表。
下面的代码提供了一个 ifprint()
函数,它可以打印
pcap_if
结构的全部内容。程序对
pcap_findalldevs_ex()
返回的每个条目都会调用该函数。
完整代码:
运行结果:
然后我们看一下这个 WIFI6 适配器,发现它的地址和通过 powershell 查看到的 ipv4 地址是一样的:
结果分析:
npcap 获取了 6 块逻辑网卡的高级信息:包含设备描述、IP地址、子网掩码、广播地址等。
4、打开适配器并捕获数据包
现在我们已经看到了如何获得一个适配器来玩(对,play,所谓的 toy programs),让我们开始真正的工作,打开一个适配器并捕获一些流量。在这一课中,我们将编写一个程序,打印出流经适配器的每个数据包的一些信息。
打开一个捕获设备的函数是 pcap_open()
。参数
snaplen
,flags
和 to_ms
值得解释一下。
snaplen
:指定了要捕获的数据包的部分。在一些操作系统上(如xBSD和Win32),数据包驱动可以被配置为只捕获任何数据包的初始部分:这减少了要复制到应用程序的数据量,因此提高了捕获的效率。在这种情况下,我们使用65536这个值,这比我们可能遇到的最大MTU要高。通过这种方式,我们确保应用程序将始终收到整个数据包。
flags
:最重要的标志是指示适配器是否将进入混杂模式的标志。在正常操作中,适配器仅捕获来自网络的发往它的数据包;因此,其他主机交换的数据包将被忽略。相反,当适配器处于混杂模式时,它会捕获所有数据包,无论它们是否发往它。这意味着在共享媒体(如非交换以太网)上,Npcap
将能够捕获其他主机的数据包。混杂模式是大多数捕获应用程序的默认模式,因此我们在以下代码中启用它。
to_ms
:指定读取超时,以毫秒为单位。适配器上的读取(例如,使用
pcap_dispatch()
或 pcap_next_ex()
)将始终在
to_ms
毫秒后返回,即使网络上没有可用的数据包。如果适配器处于统计模式,to_ms
还定义统计报告之间的间隔(有关统计模式的信息,请参阅官网教程
"wpcap_tut9")。将 to_ms
设置为 0
意味着没有超时,如果没有数据包到达,适配器上的读取永远不会返回。另一端的
-1 超时会导致适配器上的读取始终立即返回。
运行结果:
打开适配器后,可以使用 pcap_dispatch()
或
pcap_loop()
开始捕获。这两个函数非常相似,不同之处在于
pcap_dispatch()
在超时到期时返回(尽管不能保证),而
pcap_loop()
在捕获到 cnt
个数据包之前不会返回,因此它可以在下一个任意时间段内阻塞-利用网络。
pcap_loop()
足以满足我们的目的,而
pcap_dispatch()
通常用于更复杂的程序中。
这两个函数都有一个回调参数,packet_handler
,指向一个将接收数据包的函数。这个函数由
libpcap 为来自网络的每个新数据包调用,并接收一个通用状态(对应于
pcap_loop()
和 pcap_dispatch()
的
user
参数),一个包含关于数据包的一些信息的标头,例如时间戳和长度以及数据包的实际数据,包括所有协议头。请注意,帧
CRC
通常不存在,因为它在帧验证后被网络适配器删除。另请注意,大多数适配器会丢弃具有错误
CRC 的数据包,因此 Npcap 通常无法捕获它们。
上面的代码从 pcap_pkthdr
标头中提取每个数据包的时间戳和长度,并将它们打印在屏幕上。
不过要注意,使用 pcap_loop()
可能有一个缺点,主要与抓包驱动程序调用处理程序有关;因此,用户应用程序无法直接控制它。另一种方法(并且具有更易读的程序)是使用
pcap_next_ex()
函数。这里就不再赘述。详情可以参考官方教程。
5、在没有回调的情况下捕获数据包
本节的代码的行为与前面的程序(名为"打开适配器并捕获数据包"的部分)完全一样,但它使用了
pcap_next_ex()
而不是 pcap_loop()
。
pcap_loop()
的基于回调的捕获机制很优雅,在某些情况下它可能是一个很好的选择。然而,处理回调有时并不实用——它常常使程序更加复杂,特别是在多线程应用程序或C++类的情况下。
在这些情况下,pcap_next_ex()
通过直接调用来获取数据包——使用pcap_next_ex()
,数据包只有在程序员想要的时候才会被接收。
这个函数的参数与捕获回调相同。它接收一个适配器描述符和几个指针,这些指针将被初始化并返回给用户(一个指向pcap_pkthdr
结构,另一个指向包含数据包的缓冲区)。
在下面的程序中,我们回收了上一节代码中的回调代码,并将其移到main()
中,紧接着调用pcap_next_ex()
。
为什么我们使用 pcap_next_ex()
而不是以前的
pcap_next()
?因为 pcap_next()
有一些缺点。首先,它的效率很低,因为它隐藏了回调方法,但仍然依赖于
pcap_dispatch()
。其次,它不能检测EOF
,所以当从文件中收集数据包时,它不是很有用。
还请注意,pcap_next_ex()
对成功、超时、错误和EOF
条件返回不同的值。
6、过滤流量
Npcap(以及
libpcap)提供的最强大的功能之一是过滤引擎。它提供了一种非常有效的方式来接收网络流量的子集,并且(通常)与
Npcap 提供的捕获机制集成。用于过滤数据包的函数是
pcap_compile()
和 pcap_setfilter()
。
pcap_compile()
接受一个包含高级布尔(过滤器)表达式的字符串,并生成一个低级别的字节码,该字节码可由数据包驱动程序中的文件过滤器引擎解释。布尔表达式的语法可以在本文档的过滤表达式语法部分中找到。
pcap_setfilter()
在内核驱动中把一个过滤器与一个捕获会话联系起来。一旦调用
pcap_setfilter()
,相关的过滤器将被应用于所有来自网络的数据包,所有符合要求的数据包(即布尔表达式评估为真的数据包)将被实际拷贝到应用程序中。
下面的代码展示了如何编译和设置一个过滤器。注意,我们必须从描述适配器的
pcap_if
结构中获取网络掩码,因为由
pcap_compile()
创建的一些过滤器需要它。
在这个代码片段中传递给 pcap_compile()
的过滤器是“ip and
tcp”,这意味着“只保留 IPv4 和 TCP 的数据包并将它们传递给应用程序”。
上面的代码将会在下面的“解读数据包”这一节种使用到。
7、解读数据包
现在我们能够捕获和过滤网络流量,我们希望将我们的知识用于一个简单的“现实世界”应用程序。
在本节中,我们将从之前的小节中获取代码,并使用这些部分来构建一个更有用的程序。当前程序的主要目的是展示如何解析和解释捕获的数据包的协议头。由此生成的应用程序,称为 UDPdump,打印我们网络上 UDP 流量的摘要。
我们选择了解析和显示UDP协议,因为它比其他协议(如TCP)更容易获得,因此是一个很好的初始例子。让我们看一下代码。
运行如下:
首先,我们将过滤器设置为“ip and udp”。通过这种方式,我们可以确定
packet_handler()
将只接收 IPv4 上的 UDP
数据包:这简化了解析并提高了程序的效率。
我们还创建了几个描述 IP 和 UDP
标头的结构。packet_handler()
使用这些结构来正确定位各种标头字段。
packet_handler()
虽然仅限于单个协议解析器(UDP over
IPv4),但它显示了 tcpdump/WinDump
等复杂的“嗅探器”如何解码网络流量。由于我们对 MAC
标头不感兴趣,因此我们跳过它。为简单起见,在开始捕获之前,我们使用
pcap_datalink()
检查 MAC
层,以确保我们正在处理以太网网络。这样我们就可以确定 MAC 报头正好是 14
个字节。
IP 标头位于 MAC 标头之后。我们将从 IP 标头中提取 IP 源地址和目标地址。
到达 UDP 报头有点复杂,因为 IP 报头没有固定的长度。因此,我们使用 IP 头的长度字段来知道它的大小。一旦我们知道 UDP 标头的位置,我们就提取源端口和目标端口。
习题与思考题
1、WINPCAP(Npcap)是否能实现服务质量的控制?
答:不能。WinPcap可以独立地通过主机协议发送和接受数据,如同TCP-IP。这就意味着WinPcap不能阻止、过滤或操纵同一机器上的其他应用程序的通讯:它仅仅能简单地"监视"在网络上传输的数据包。所以,它不能提供类似网络流量控制、服务质量调度和个人防火墙之类的支持,因而不能实现服务质量的控制。
参考:
1、https://npcap.com/guide/npcap-tutorial.html
实验三 协议分析程序的编写
实验目的
目的:分析IP协议,统计流量。大家可以把流量计做成流量地图,显示不同地点间数据实时发送的量,比如武汉到北京的数据包发送的数据量。 可以用echart画地图,用whois获取IP地址的所属地。
任务:根据IP协议,解析每个数据包的PCI,并对不同IP进行流量统计。
任务的说明:
- 实现的软件能显示每个包的PCI。
- 能显示每个IP地址的流量,即显示接收包的数量。
实验原理
首先解释一下 PCI 的具体含义:
使用分层网络方法,每一层都会“封装”从其上一层向下传递的数据,同时添加自己的信息。然后,该层会将新的 PDU 向下传递到下一层(或者一旦您到达第 1 层,就将其通过物理介质发送)。一旦到达另一端,则采取相反的路径;每一层查看与其相关的标头/尾标,处理它们,并将有效负载向上传递到下一层。 每个封装级别的具体信息取决于协议。例如,TCP 将添加源端口和目标端口、校验和、序列/确认号以及其他一些东西。 IP 添加源/目标地址、数据包长度和其他一些内容。以太网将添加源/目标 MAC、EtherType、FCS 等。
然后就是利用实验二中使用的 npcap 进行抓包。这里主要是抓取 TCP 的数据包,然后将抓取到的每一个数据包解析之后,将它们的源 ip 和目标 ip 都存放到 MySQL 数据库中。然后使用 Python 调用解析 ip 归属地的接口,将每一个 ip 的归属地解析好,然后更新数据库中的相关字段。
之后使用 Spring Boot 搭建一个简单的后台接口,主要是给前端网页提供 json 数据。
前端主要使用 echarts 来绘图,绘图所需要的数据就来自上面 Spring Boot 提供的 json 数据接口。这样就可以实时地绘制我们所需的流量地图了。
实验环境
系统:Windows 10 家庭中文版 21H2
Visual Studio 版本:Visual Studio 2022
Npcap 版本:1.60
Npcap SDK 版本:1.12
MySQL 版本:8.0.28
jdk 版本:openjdk version "17.0.2"
Python 版本:3.10.4
echart 版本:
实验内容
分析IP协议,统计流量。把流量计做成流量地图,显示不同地点间数据实时发送的量,比如武汉到北京的数据包发送的数据量。用echart画地图,用whois获取IP地址的所属地。
实验过程
首先,编写 C++ 程序进行抓包,这个在实验二中已经实现,这里就不再赘述。
这里主要介绍一下将捕获到的源 ip 地址和目标 ip 地址存放到数据库中的过程。
首先,配置环境,步骤如下:
之后,还要将 libmysql.lib 文件添加到项目的根目录下:
然后我们写一个 C++ 的类,从而实现对数据库中数据进行增删改查:
然后在抓包程序的回调函数中增加对数据库的操作即可:
这里的逻辑是每一次启动这个抓包程序时,会自动清空上一次在数据库中存储的数据,然后再将本次抓取到的数据存放到数据库中。
之后就是 Pyhton 实现对 ip 地址的解析,并将解析好的结果更新到数据库中:
再之后,使用 Spring Boot 创建一个 json 接口,主要的逻辑如下:
最后,是前端的逻辑:
实验其中一次的结果如下:
说明:图中的每一条路径上的箭头数量代表了流量包的数量。
习题与思考题
1、应用WINPCAP能实现哪些网络应用?
- 捕获原始数据包。不管这个包是发往本地机,还是其他机器之间的交换包
- 在数据包被发送到应用程序之前,通过用户定义的规则过滤
- 向网络发送原始数据包
- 对网络通信量做出统计
应用 winpcap 实现的典型应用程序如 WireShark。
项目源码地址
https://github.com/FanyFull/ComputerNetworkExperiment
参考:
1、https://www.reddit.com/r/ccna/comments/7mh86d/what_does_protocol_control_information_means/