实验目的

  1. 掌握 Wireshark 抓包工具的基本操作,包括网卡选择、数据包捕获启停及协议过滤器的使用方法。
  2. 理解 ARP 协议的工作原理、分层定位(网络层与数据链路层之间)及报文格式,掌握 ARP 请求与响应报文的核心字段含义。
  3. 能够通过 Wireshark 分析 ARP 报文的硬件类型、协议类型、MAC 地址、IP 地址等关键字段,识别 ARP 请求与响应。
  4. 掌握 C++ 语言解析原始 ARP 数据包的编程方法,实现对 ARP 报文各字段的提取与格式化输出,加深对网络协议字节序(大端序)的理解。

实验内容简要描述

实验分为三部分:

  1. Wireshark 使用与 HTTP 协议分析:启动 Wireshark 并选择网卡,捕获访问南京师范大学官网(南京师范大学)的 HTTP 报文,通过 “http” 过滤器筛选流量,分析数据链路层(Ethernet)、网络层(IPv4)、传输层(TCP)及应用层(HTTP)的报文结构,观察源 / 目的 MAC 地址、IP 地址、端口号、TCP 序列号、HTTP 请求头等字段。
  2. ARP 协议分析:在 Wireshark 中使用 “arp” 过滤器筛选 ARP 报文,分析 ARP 报文的分层结构(仅数据链路层与网络层相关字段),识别硬件类型、协议类型、操作码(请求 / 响应)、发送端 / 目标端 MAC 地址与 IP 地址等核心字段。
  3. 解析 ARP 数据包:基于给定的原始 ARP 数据(十六进制字符串),使用 C++ 语言编写解析程序,按照 ARP 数据包格式(28 字节)依次提取硬件类型、协议类型、地址长度、操作码、MAC 地址、IP 地址等字段,并按规范格式输出至文件,重点处理大端序字节序转换及 MAC/IP 地址的格式化。

实验步骤与结果分析

3.1 Wireshark使用与HTTP协议分析

打开终端输入wireshark来启动Wireshark

在界面顶部的网卡选项菜单中选择用户自己的网卡(如eth0)

启动桌面的chrome浏览器。

开始分组捕获。点击工具栏中的“捕获”按钮,开始分组捕获。

当完整的页面加载完成后,单击捕获对话框中的“停止捕获”按钮,停止分组捕获。此时,Wireshark主窗口显示已捕获的本次通信的所有协议报文。

在协议筛选框中输入http,按回车键,分组列表窗口中将只显示HTTP报文。

如图所示wireshark的主窗口由三个部分组成。

      1. 第一部分为数据包列表,此部分简要的展示了wireshark所捕获到的所有数据包的序号、捕获时间戳、源IP信息、目的IP信息、最高层协议类型、数据包长度以及数据包的简要信息。
      2. 第二部分为某个数据包的详细信息,第一行为数据帧的概要信息,从第二行依次往后为各层所使用的协议对应的具体信息。如上图所示,对应展示了数据链路层协议(Ethernet协议)信息、网络层协议(IPv4)信息、传输层协议(TCP)信息以及应用层协议(HTTP)信息。
      3. 第三部分为数据包原始信息,此部分以十六进制和 ASCII 格式显示数据包的原始字节内容。

选中一个数据包,查看数据包具体的数据链路层协议信息,可以看到该数据包对应的目的MAC地址为0a:21:54:48:de:96,MAC地址为ee:ee:ee:ee:ee:ee

选中一个数据包,查看数据包具体的网络层协议信息。

  • 可以看到数据包的源IP地址为232.2.9.124,目的IP地址为100.93.62.220
  • 数据包所使用的IP协议版本为4(即IPv4);
  • 整个IP数据包的总长度为185bytes
  • Identification: 0x606e为此IP数据包的唯一标识;
  • FlagsDon't fragment: 1表示数据包不能被分片。More fragments: 0,表示这是最后一个分片(或无分片);
  • Fragment offset: 0表示数据包的分片偏移量是 0,此处数据包未被分片,故为offset0
  • Time to live: 59此处表示数据包在网络中最多可以经过 59 跳(路由器);
  • Protocol: TCP (6)表示 IP 数据包中承载的上层协议是 TCP
  • Header checksum: 0x5319为数据包头部校验和;

选中一个数据包,查看数据包具体的传输层协议信息。

  • Src Port: 80源端口号,表示数据包的发送方端口;
  • Dst Port: 37106目标端口号,表示数据包的接收方端口(80HTTP 服务的默认端口);
  • Seq: 1429序列号,表示当前数据包在数据流中的位置(相对值);
  • Ack: 329确认号,表示接收方期望接收的下一个字节的序列号(相对值);
  • Len: 133数据部分的长度(Payload),表示该 TCP 段携带了133字节的数据;
  • Header Length: 32 bytes表示 TCP 头部的长度是 32 字节;

选中一个数据包,查看数据包具体的应用层协议信息。

GET /home…js / HTTP/1.1\r\n表示这是一个 HTTP GET 请求;

HostAccept-LanguageHTTP 请求头;

3.2 ARP协议分析

在协议筛选框中输入arp,按回车键,分组列表窗口中将只显示ARP报文。

可以看到ARP报文的数据包详细信息部分仅存在两层(数据链路层协议信息和网络层协议信息),因为ARP工作在网络层和数据链路层之间。

  1. 具体查看数据包的数据链路层协议信息。可以发现数据链路层承载的上层协议名称为ARP。

具体查看数据包的网络层协议信息。

  • Hardware type: Ethernet (1)表示硬件类型是以太网(Ethernet),值为1;
  • Protocol type: IPv4 (0x0800)表示协议类型是 IPv4;
  • Hardware size: 6表示硬件地址(MAC 地址)的长度是 6 字节;
  • Protocol size: 4表示协议地址(IP 地址)的长度是 4 字节;
  • Opcode: request (1)操作码 1 表示 ARP 请求,2 表示 ARP 响应;
  • Sender MAC address: ee:ee:ee:ee:ee:ee (ee:ee:ee:ee:ee:ee)表示发送方的 MAC 地址;
  • Sender IP address: 172.21.229.11表示发送方的 IP 地址;
  • Target MAC address: 00:00:00:00:00:00 (00:00:00:00:00:00)表示目标设备的 MAC 地址;
  • Target IP address: 100.99.174.107表示目标设备的 IP 地址;

3.3解析ARP数据包

  1. 在代码文件中利用C++语言编写代码,实现ARP数据包的解析。
  2. 实验中使用到的ARP数据为0001080006040001eeeeeeeeeeeeac15e50b0000000000006463ae47
  3. 要求程序输出的规范格式为(*为具体的字段值,最终结果不包含每行前的序号):

Hardware Type: *

Protocol Type: *

Hardware Address Length: *

Protocol Address Length: *

Operation: *

Sender MAC: *

Sender IP: *

Target MAC: *

Target IP: *

  1. 代码中相应的头文件包含以及一些必要功能已经给出,不要使用需要额外引入的头文件。
  2. 代码可以在实验环境中通过自行创建文件,并使用g++工具进行编译调试。

实验所用的解析ARP数据包的完整函数如下:

void parseARPPacket(const uint8_t* arpData, const std::string& outputFile)

{

    if (!fileExists(outputFile))

    {

        std::ofstream createFile(outputFile);

        if (!createFile.is_open())

        {

            std::cerr << "Failed to create output file: " << outputFile << std::endl;

            return;

        }

        createFile.close();

    }

    std::ofstream outFile(outputFile, std::ios::out | std::ios::trunc);

    if (!outFile.is_open())

    {

        std::cerr << "Failed to open output file: " << outputFile << std::endl;

        return;

    }



    // 解析ARP数据包

    // ARP数据包格式(28字节):

    // 字节0-1: Hardware Type (2字节)

    // 字节2-3: Protocol Type (2字节)

    // 字节4: Hardware Address Length (1字节)

    // 字节5: Protocol Address Length (1字节)

    // 字节6-7: Operation (2字节)

    // 字节8-13: Sender MAC (6字节)

    // 字节14-17: Sender IP (4字节)

    // 字节18-23: Target MAC (6字节)

    // 字节24-27: Target IP (4字节)



    // 提取Hardware Type (2字节,大端序)

    uint16_t hardwareType = (arpData[0] << 8) | arpData[1];

   

    // 提取Protocol Type (2字节,大端序)

    uint16_t protocolType = (arpData[2] << 8) | arpData[3];

   

    // 提取Hardware Address Length (1字节)

    uint8_t hardwareAddrLen = arpData[4];

   

    // 提取Protocol Address Length (1字节)

    uint8_t protocolAddrLen = arpData[5];

   

    // 提取Operation (2字节,大端序)

    uint16_t operation = (arpData[6] << 8) | arpData[7];

   

    // 提取Sender MAC (6字节)

    std::string senderMAC = formatMAC(&arpData[8]);

   

    // 提取Sender IP (4字节)

    std::string senderIP = formatIP(&arpData[14]);

   

    // 提取Target MAC (6字节)

    std::string targetMAC = formatMAC(&arpData[18]);

   

    // 提取Target IP (4字节)

    std::string targetIP = formatIP(&arpData[24]);



    // 输出格式

    outFile << "Hardware Type: " << hardwareType << std::endl;

    // Protocol Type需添加0x前缀

    outFile << "Protocol Type: 0x" << std::hex << std::setfill('0') << std::setw(4) << protocolType << std::dec << std::endl;

    outFile << "Hardware Address Length: " << static_cast<int>(hardwareAddrLen) << std::endl;

    outFile << "Protocol Address Length: " << static_cast<int>(protocolAddrLen) << std::endl;

    outFile << "Operation: " << operation << std::endl;

    outFile << "Sender MAC: " << senderMAC << std::endl;

    outFile << "Sender IP: " << senderIP << std::endl;

    outFile << "Target MAC: " << targetMAC << std::endl;

    outFile << "Target IP: " << targetIP << std::endl;



    outFile.close();

}

Logo

免费领 150 小时云算力,进群参与显卡、AI PC 幸运抽奖

更多推荐