网络报文分析程序的设计与实现(2024)

1.题目描述

在上一题的基础上,参照教材中各层报文的头部结构,结合使用 wireshark 软件(下载地址 https://www.wireshark.org/download.html#releases)观察网络各层报文捕获,解析和分析的过程(如下 图所示),尝试编写一个网络报文的解析程序。


2.演示Demo

设备选择


3.导入WinPcap三方库到项目

(博主用的是Clion,若是VC,CodeBlocks,Dev-C等导入方式大同小异)

首先下载: 文件https://www.winpcap.org/install/bin/WpdPack_4_1_2.zip

解压到项目路径下:

在CMakeLists.txt修改成下面代码:(连接第三方库WinPcap):

cmake_minimum_required(VERSION 3.27)
project(Problem08)
set(CMAKE_CXX_STANDARD 17)

include_directories("./Include")  #导入.h头文件

link_directories("./Lib/x64")     #导入.a库文件(./Lib/x64是64位  ./Lib 是32位机器使用)

link_libraries(Packet wpcap  ws2_32)  #导入wpcap,ws2_32库文件

add_executable(Problem08 main.cpp)

target_link_libraries(Problem08 Packet wpcap) #连接wpcap,ws2_32库文件

刷新项目 :

成功运行 


4.参考代码

#define HAVE_REMOTE
#define LINE_LEN 16
#define IPPROTO_ICMP 1 /* control message protocol */
#define IPPROTO_TCP  6 /* tcp */
#define IPPROTO_UDP 17 /* user datagram protocol */

#include <WinSock2.h>
#include <algorithm>
#include <string>
#include <cstdio>
#include <pcap.h>
#include <sys/time.h>
#include <iostream>
#pragma comment(lib, "ws2_32.lib")

using namespace std;


typedef struct ip_address { //ip地址
    u_char b1;
    u_char b2;
    u_char b3;
    u_char b4;
} ip_address;

typedef struct mac_address {//mac地址
    u_char b1;
    u_char b2;
    u_char b3;
    u_char b4;
    u_char b5;
    u_char b6;
} mac_address;

typedef struct ethe_header { //mac帧首部
    mac_address mac_dest_address;
    mac_address mac_source_address;
    u_short ether_type;
} ethe_header;

typedef struct ip_header { //ip地址首部
    u_char ver_ihl;
    u_char tos;
    u_short tlen;
    u_short identification;
    u_short flags_fo;
    u_char ttl;
    u_char proto;
    u_short crc;
    ip_address saddr;
    ip_address daddr;
    u_int op_pad;
} ip_header;

typedef struct udp_header { //UPD首部
    u_short sport;
    u_short dport;
    u_short len;
    u_short crc;
} udp_header;

typedef struct tcp_header { //TCP首部
    u_short sport;
    u_short dport;
    u_int num;
    u_int ack;
    u_short sum;
    u_short windonw;
    u_short crc;
    u_short ugr;
} tcp_header;

//------------------------------------------------
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);

void cls();

void Sync_NetData();
void GotoXY(int x, int y) ; // 移动
//-----------------------------------------------
char judge;
int length;
long NeedPacket = 999;
long NowPacket = 0;
//变量--------------------------------------------

long Now_Y=10;

long Tcp_Num = 0;
long Udp_Num = 0;
long ICMP_Num = 0;
long Tcp_Size = 0;
long ICMP_Size = 0;
long Udp_Size = 0;

//-----------------------------------------------
int main() {
    cout << " *============网络报文分析程序的设计与实现Demo============*" << endl << endl;
    pcap_if_t *alldevs, *device;
    int i = 0;
    int iNum;
    u_int netmask;
    struct bpf_program fcode;
    pcap_t *adhandle;
    char errbuf[PCAP_ERRBUF_SIZE];
    //修改这里可以更改捕获的数据包使用的协议类型
    char packet_filter[] = "(ip and udp) or (ip and tcp) or (ip and icmp)";
    //获取设备列表
    if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) {
        fprintf(stderr, "无法打开网络设备:%s\n", errbuf);
        return 1;
    }
    for (device = alldevs; device != NULL; device = device->next) { //打印列表
        if (i == 0) {
            printf("------------------------------网络设备-------------------------------\n");
        }
        if (device->description)
            printf(" 序号:%d (%s)\n", ++i, device->description);
        else {
            i++;
            printf("没有设备描述信息!");
        }
    }
    printf("-------------------------------------------------------------------\n");
    if (i == 0) {
        printf("\n请先安装WinPcap!");
        return -1;
    }
    printf("\n #请选择网络设备接口:(1 - %d):", i);
    scanf("%d", &iNum);
    getchar();
    if (iNum < 1 || iNum > i) {
        printf("设备不存在!\n");
        pcap_freealldevs(alldevs);
        return -1;
    }
    //跳转到已选设备
    for (device = alldevs, i = 0; i < iNum - 1; device = device->next, i++);

    // 打开适配器
    if ((adhandle = pcap_open(device->name,  // 设备名
                              65536,     // 要捕捉的数据包的部分
            // 65535保证能捕获到不同数据链路层上的每个数据包的全部内容
                              PCAP_OPENFLAG_PROMISCUOUS,         // 混杂模式
                              1000,      // 读取超时时间
                              NULL,      // 远程机器验证
                              errbuf     // 错误缓冲池
    )) == NULL) {
        fprintf(stderr, "\n不能打开适配器!\n");
        /* 释放设备列表 */
        pcap_freealldevs(alldevs);
        return -1;
    }

    if (pcap_datalink(adhandle) != DLT_EN10MB) { //检查数据链路层,为了简单,只考虑以太网
        fprintf(stderr, "\n系统网卡链路出错!\n");
        pcap_freealldevs(alldevs); //释放设备列表
        return -1;
    }

    if (device->addresses != NULL) //获得接口第一个地址的掩码
        netmask = ((struct sockaddr_in *) (device->addresses->netmask))->sin_addr.S_un.S_addr;
    else //如果接口没有地址,那么我们假设一个C类的掩码
        netmask = 0xffff00;
    if (pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) < 0) { //编译过滤器
        fprintf(stderr, "不能监听过滤该数据报!\n");
        pcap_freealldevs(alldevs);
        return -1;
    }

    if (pcap_setfilter(adhandle, &fcode) < 0) { //设置过滤器
        fprintf(stderr, "过滤设置错误!\n");
        pcap_freealldevs(alldevs);
        return -1;
    }
    cout << " #请输入抓包数量:";
    cin >> NeedPacket;
    printf("\n\n 正在监听%s的数据报...\n\n", device->description);
    pcap_freealldevs(alldevs); //释放设备列表
    system("cls");
    pcap_loop(adhandle, NeedPacket, packet_handler, NULL); //开始捕捉
    GotoXY(0,Now_Y);
    cout << endl << " * 嗅探结束 " << endl << endl;
    system("pause");
    return 0;
}

void packet_handler(u_char *dumpfile, const struct pcap_pkthdr *header,
                    const u_char *pkt_data) { //回调函数,当收到每一个数据包时会被libpcap所调用
    if (header->caplen > 400) return;
    int len;
    struct tm *ltime;
    char timestr[16];
    ip_header *ip_hd,ip_hd_ok;
    udp_header *udp_hd;
    tcp_header *tcp_hd;
    ethe_header *ethe_hd;
    int ip_len, tcp_len, start;
    u_short sport, dport;
    string  Type_net;
    char now[64];
    struct tm *ttime;
    time_t tt;
    tt = header->ts.tv_sec;
    ttime = localtime(&tt);
    strftime(now, 64, "%Y-%m-%d %H:%M:%S", ttime);
    // printf("时间:%s\n", now);

    ethe_hd = (ethe_header *) pkt_data;
    ip_hd = (ip_header *) (pkt_data + 14);
    ip_hd_ok=*ip_hd;
    ip_len = (ip_hd_ok.ver_ihl & 0xf) * 4; //ip首部长度
    udp_hd = (udp_header *) ((u_char *) ip_hd + ip_len);
    sport = ntohs(udp_hd->sport);
    dport = ntohs(udp_hd->dport);

    if (ip_hd_ok.proto == IPPROTO_UDP) {
        Type_net="UDP";
        start = ip_len + 8;
        Udp_Num++;
        Udp_Size += header->caplen;
    } else if (ip_hd_ok.proto == IPPROTO_TCP) {
        Type_net="TCP";
        Tcp_Num++;
        Tcp_Size += header->caplen;
        tcp_hd = (tcp_header *) ((u_char *) ip_hd + ip_len);
        tcp_len = ntohs(tcp_hd->sum) >> 12;
        start = ip_len + tcp_len * 4;
    } else if (ip_hd_ok.proto == IPPROTO_ICMP) {
        Type_net="ICMP";
        start = ip_len + 23;
        ICMP_Num++;
        ICMP_Size += header->caplen;
    }

    GotoXY(0,Now_Y);
    printf("数据类型: %s\t"
           "源IP地址: %d.%d.%d.%d:%d\t"
           "目的IP地址: %d.%d.%d.%d:%d\t"
           "目的物理地址: %x-%x-%x-%x-%x-%x\n",
           Type_net.c_str(),
           ip_hd->saddr.b1, ip_hd->saddr.b2, ip_hd->saddr.b3, ip_hd->saddr.b4,sport,
           ip_hd->daddr.b1, ip_hd->daddr.b2, ip_hd->daddr.b3, ip_hd->daddr.b4, dport,
           ethe_hd->mac_dest_address.b1, ethe_hd->mac_dest_address.b2, ethe_hd->mac_dest_address.b3,
           ethe_hd->mac_dest_address.b4, ethe_hd->mac_dest_address.b5, ethe_hd->mac_dest_address.b6);
    Now_Y++;
    Sync_NetData();//更新网络
}

//更新数据
void Sync_NetData() {
    cls();
    cout << " *==========网络报文分析程序的设计与实现Demo==========*" << endl;
    cout << endl << " 捕获网络报文分析:------------------------" << endl;
    cout << "\tTCP包数量:" << Tcp_Num << " 个" << endl;
    cout << "\tUDP包数量:" << Udp_Num << " 个" << endl;
    cout << "\tICMP包数量:" << ICMP_Num << " 个" << endl;
    cout << "\t捕获TCP包的总大小:" << Tcp_Size / 1024 << "KB" << endl;
    cout << "\t捕获UDP包的总大小:" << Udp_Size / 1024 << "KB" << endl;
    cout << "\t捕获ICMP包的总大小:" << ICMP_Size / 1024 << "KB" << endl;
    cout << " -------------------------------------" << endl;

}

//清屏函数
void cls() {
    COORD pos;
    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
    pos.Y = pos.X = 0;
    SetConsoleCursorPosition(hOut, pos);
}
void GotoXY(int x, int y)  // 移动
{
    COORD pos;
    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
    pos.Y =y; pos.X = x;
    SetConsoleCursorPosition(hOut, pos);
}

 2024 HNUST计算机网络课程设计-(ᕑᗢᓫ∗)˒芒果酱-参考文章

代码可以参考,૮₍ ˃ ⤙ ˂ ₎ა 但同学们要认真编写哦
-------------------------------------------------------------------------
1、网络聊天程序的设计与实现
C++ Socket 多线程 网络聊天室 支持用户端双向交流(2023)-CSDN博客
2、Tracert 与 Ping 程序设计与实现
Tracert 与 Ping 程序设计与实现(2024)-CSDN博客
3、滑动窗口协议仿真
滑动窗口协议仿真(2024)-CSDN博客
4、OSPF 路由协议原型系统设计与实现
OSPF 路由协议原型系统设计与实现-CSDN博客
5、基于 IP 多播的网络会议程序
基于 IP 多播的网络会议程序(2024)-CSDN博客
6、编程模拟 NAT 网络地址转换
编程模拟 NAT 网络地址转换(2024)-CSDN博客
7、网络嗅探器的设计与实现
网络嗅探器的设计与实现(2024)-转载-CSDN博客
8、网络报文分析程序的设计与实现
网络报文分析程序的设计与实现(2024)-CSDN博客
9、简单 Web Server 程序的设计与实现
简单 Web Server 程序的设计与实现 (2024)-CSDN博客
10、路由器查表过程模拟

计算机网络 - 路由器查表过程模拟 C++(2024)-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/299332.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot+Redis实现接口防刷功能

场景描述&#xff1a; 在实际开发中&#xff0c;当前端请求后台时&#xff0c;如果后端处理比较慢&#xff0c;但是用户是不知情的&#xff0c;此时后端仍在处理&#xff0c;但是前端用户以为没点到&#xff0c;那么再次点击又发起请求&#xff0c;就会导致在短时间内有很多请求…

FCN-8s源码理解

FCN网络用于对图像进行分割&#xff0c;由于是全卷积网络&#xff0c;所以对输入图像的分辨率没有要求。本文重点对fcn8s.py中图像降采样和上采样后图像分辨率的变换进行理解。 相关知识 为准确理解图像分辨率的变换&#xff0c;对网络结构中影响图像分辨率变换的几个函数进行…

leetcode:3. 无重复字符的最长子串

一、题目 二、函数原型 int lengthOfLongestSubstring(char* s) 三、思路 本题就是找最长的无重复字符子串。 两层循环&#xff0c;外层循环控制字串的起始位置&#xff0c;内层循环控制字串的长度。 设置一个长度为256且初始为0的hash表&#xff08;因为一共有256个字符…

windows----Vmware虚拟机安装ubuntu

双系统来回切有点麻烦&#xff0c;还是安装虚拟机先整个简单的。 1 安装Vmware17虚拟机 虚拟机下载网址&#xff0c;一直下一步就行&#xff0c;更新和加入计划关闭 秘钥&#xff1a;MC60H-DWHD5-H80U9-6V85M-8280D 2 下载ubantu镜像 浙大镜像&#xff0c;自己选择版本吧&a…

灰色关联分析

&#xff08;相关性分析&#xff09;反映关系有多么紧密 “在系统发展过程中&#xff0c;若两个因素变化的趋势具有一致性&#xff0c;即同步变化程度较高&#xff0c;即可谓二者关联程度较高&#xff1b;反之&#xff0c;则较低。因此&#xff0c;灰色关联分析方法&#xff0…

STM32 ADC采样调试笔记

最近在搞STM32L051系列一个小MCU&#xff0c;要用这个去采集两路ADC作为输入。期间也碰到过一些问题&#xff0c;顺便记录下。 ADC采集原理不说了&#xff0c;主要采集电压&#xff0c;用数字进行细分&#xff0c;这样就可以知道输入电压多少了&#xff0c;网上也有很多相关文…

Spark中的二分类与多分类问题的解决

机器学习中的分类问题是数据科学中的一个重要领域&#xff0c;而在大数据环境中使用Apache Spark来解决二分类和多分类问题可以更好地处理大规模数据。本文将深入探讨如何使用Spark来解决二分类和多分类问题&#xff0c;包括数据准备、模型选择和性能评估等方面。 二分类问题 …

dnSpy调试工具二次开发1-新增菜单

测试环境&#xff1a; window 10 visual studio 2019 版本号&#xff1a;16.11.15 .net framework 4.8 开发者工具包 下载 .NET Framework 4.8 | 免费官方下载 .net 5开发者工具包 下载 .NET 5.0 (Linux、macOS 和 Windows) 利用git拉取代码(源码地址&#xff1a;Gi…

入库和出库的成本对不上如果如何解决

入库是前期手工录入的车价是对的&#xff0c;出库是根据销售出库单生成的 入库成本和出库成本不一致的解决方法 解决方法&#xff1a; 整车管理——正车库存——库存核算——整车出库 成本核算

Marvelous Designer 各版本安装指南

Marvelous Designer下载链接 https://pan.baidu.com/s/1ZZCraq6w2Z4JPisND8q0jA?pwd0531 1.鼠标右击【Marvelous Designer 12(64bit)】压缩包&#xff08;win11及以上系统需先点击“显示更多选项”&#xff09;选择【解压到 Marvelous Designer 12(64bit)】。 2.打开解压后的…

深入了解 RDD

深入了解 RDD 案例 明确需求&#xff1a; 在访问日志中&#xff0c;统计独立IP数量 TOP10 查看数据结构&#xff1a; IP&#xff0c;时间戳&#xff0c;Http&#xff0c;Method&#xff0c;Url…… 明确编码步骤 取出IP&#xff0c;生成一个只有IP的数据集简单清洗统计IP出现…

【小沐学CAD】开源Assimp库导入三维模型(C++、Python)

文章目录 1、简介2、下载编译3、代码测试3.1 C3.2 pyassimp&#xff08;Python&#xff09; 结语 1、简介 https://github.com/assimp/assimp Open Asset Import Library 是一个库&#xff0c;用于将各种 3D 文件格式加载为共享的内存格式。它支持 40 多种用于导入的文件格式和…

openssl3.2 - 编译

文章目录 openssl3.2 - 编译概述OpenSSL源码下载编译目标如何编译前置环境 - perl前置环境 - VS前置环境 - NASM快速编译步骤编译 - Quick startInstall PerlInstall NASMUse Visual Studio Developer Command Prompt with administrative privilegesFrom the root of the Open…

I.MX6ULL开发笔记(二)——硬件外设操作

0x01 点亮第一个RGB灯 在文章http://t.csdnimg.cn/EGWt9中有介绍Linux下文件目录&#xff0c;那么在Linux系统下&#xff0c;RGB灯也是一个设备&#xff0c;所以我们需要到/sys目录下去操作这个设备。 之后&#xff0c;我们进入到class目录&#xff0c;这里挂载着开发板上的外…

关于一个热成像仪的总结(一)硬件篇电源电路

1、电源部分 电源部分电路原理是这样的通过3.7V的锂电池供电&#xff0c;用Type-C选用TP4056作为充电电路给电池充电。使用MP2161开关电源作为5转3.3V 电源为MCU供电。 1-1电池 待定 1-2充电管理芯片TP4056 参考datasheet&#xff1a;https://atta.szlcsc.com/upload/publi…

[蓝桥杯学习] 线段树

学习blibli 定义 线段树是一种特殊的平衡二叉查找树&#xff0c;使用线段树&#xff0c;可以实现数据的添加、查找和删除。 树的根结点表示了一个完整的单元区间&#xff0c;左右孩子的区间是将父结点的区间进行二分&#xff0c;左右孩子的区间之和&#xff0c;就是他们的根…

studio3T mongodb 根据查询条件更新字段 或 删除数据

1. mongodb 等于、不等于$ne、不包含 $nin 以及批量更新数据的使用。 业务场景&#xff1a; 在集合中&#xff0c;根据查询条件&#xff0c;更新数据状态。 实现代码&#xff1a; 1. 部门名称为XXX、状态不等于“完好”的、并且不包含这些编码的数据先查询出来2. 再把状态更…

基于Java+SSM+JSP实现全功能电子商城

&#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩项目推荐订阅&#x1f447;&#x1f3fb; 不然下次找不到哟 基于SpringBoot的旅游网站 基于SpringBoot的MusiQ音乐网站 感兴趣的可以先收藏起来&#xff0c;还有大家在毕设选题&#xff0c;项目以及…

解决Android AAPT: error: resource android:attr/lStar not found. 问题

错误信息 /xxx/gjc/.gradle/caches/transforms-2/files-2.1/930c42acd29d295ce5bc495c3b84423e/core-1.9.0/res/values/values.xml:104:5-113:25: AAPT: error: resource android:attr/lStar not found. not found 资源位置 场景 原Android studio中的项目都是在git上面拉的老项…

react-hooks-kit v1 正式发布

evanpatchouli/react-hooks-kit - (npmjs.com) v1.0.0 正式发布&#xff01; 下载安装 npm i evanpatchouli/react-hooks-it -S官方文档 在 Gitee 阅读在 Github 阅读 概览 这是一个无依赖的轻量级 React Hooks 库&#xff0c;总共有 60 hooks。 它包含了一系列易于使用…