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

news2024/11/25 0:29:33

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博客

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机毕业设计——SpringBoot 个人博客管理系统(附源码)

1&#xff0c;绪论 1.1 背景调研 在互联网飞速发展的今天&#xff0c;互联网已经成为人们快速获取、发布和传递信息的重要渠道&#xff0c;它在人们政治、经济、生活等各个方面发挥着重要的作用。互联网上发布信息主要是通过网站来实现的&#xff0c;获取信息也是要在互联网中…

智能网联汽车安全相关标准汇总

目录 1.标准方向分析 2.智能驾驶域相关标准 3.智能座舱域相关标准 3.汽车通用规范 1.标准方向分析 当前汽车行业的内卷态势已经蔓延至项目立项&#xff0c;导致如今开发模式都尽可能地左移&#xff0c;例如瑞萨提出的虚拟ECU开发模式可以极大节省ECU的实车验证资源&#xf…

Open3D 基于统计滤波去除噪点(5)

Open3D 基于统计滤波去除噪点&#xff08;5&#xff09; 一、什么是统计滤波二、具体实现1.代码 一、什么是统计滤波 统计滤波是一种常用的点云滤波方法&#xff0c;用于去除噪声和异常点。在统计滤波中&#xff0c;通过计算每个点邻域内的统计特征&#xff08;如平均值和标准…

院士专家齐聚 京彩未来联合重点研究院创建数字空间联合实验室

1月6日&#xff0c;京彩未来与北京大学数字中国研究院华南分院暨广东省数字广东研究院共同创建的“数字空间共同体联合室验室”正式挂牌运营。 著名经济学家管清友博士、北京大学数字中国研究院华南分院暨广东省数字广东研究院常务副院长李鹰教授&#xff0c;广东省数字广东研…

MFC Socket和合信CTMC M266ES 运动控制型PLC通信进行数据交换

前言 1、前两篇文章通过对Snap7和S7-1200/S7-1500PLC的通信进行了详细的介绍。Snap7的优点开源性强、使用方便易于上手&#xff0c;跨平台和可移植性性强。但是Snap7也有个缺点就是只能访问PLC的DB、MB、I、Q区进行数据读写&#xff0c;不能对V区进行读写,有人说可以读写V区&am…

Spring AOP(详解)

目录 1.AOP概述 2.AOP相关术语 3.Spring AOP的原理机制 3.1JDK动态代理 3.2 CGLIB动态代理 3.3简单代码展示 3.3.1JDK动态代理 3.3.2CGLIB动态代理 4.Spring的AOP配置 4.1pom.xml 4.2增强方法 4.3切点 4.4切面 5.基于注解的AOP配置 5.1.创建工程 5.2.增强 5.3AOP…

抖去推账号矩阵+无人直播+文案引流系统开发搭建--开源

核心技术 1. AI自动直播&#xff1a; 智能系统通过丰富可定制的文案库&#xff0c; 拥有有料有趣的灵魂。不仅能自动语音讲解内容&#xff0c;还可以在直播中和用户灵活互动。直播中可将团购商品同话术自动上下架。 2. AI剪辑 可一键智能批量成片&#xff0c;也可跟着模板剪…

苹果IOS如何支持微信小程序分享

各位同学们好&#xff01;我是咕噜铁蛋&#xff01;&#xff0c;我们经常需要与读者分享有关移动应用的使用方法和技巧。微信小程序是一种便捷的应用形式&#xff0c;可以在微信内部直接使用&#xff0c;而无需下载和安装。本文铁蛋讲详细介绍iOS苹果支持微信小程序类型分享的使…

简单几步,实现餐厅扫码点餐

越来越多的人选择外出就餐&#xff0c;而餐厅的点餐方式也随着科技的发展而不断进步。其中&#xff0c;扫码点餐是最为常见的一种方式&#xff0c;它不仅方便快捷&#xff0c;还能节省人力成本。本文将介绍一种简单易行的餐厅扫码点餐解决方案。 打开乔拓云平台&#xff0c;登录…

【React】02-如何理解React通过对DOM的模拟,最大限度地减少与DOM的交互

如何理解React通过对DOM的模拟&#xff0c;最大限度地减少与DOM的交互 背景分析关于虚拟DOM 背景 在学习React的过程中&#xff0c;发现很多文档上关于React的高效都有这么一句话的描述——React通过对DOM的模拟&#xff0c;最大限度地减少与DOM的交互&#xff0c;对于我这种前…

Spark---RDD算子(单值类型转换算子)

文章目录 1.RDD算子介绍2.转换算子2.1 Value类型2.1.1 map2.1.2 mapPartitions2.1.3 mapPartitionsWithIndex2.1.4 flatMap2.1.5 glom2.1.6 groupBy2.1.7 filter2.1.8 sample2.1.9 distinct2.1.10 coalesce2.1.11 repartition2.1.12 sortBy 1.RDD算子介绍 RDD算子是用于对RDD进…

Redis(三)持久化

文章目录 RDB&#xff08;Redis Database&#xff09;自动触发保存频率修改dump文件保存路径修改文件保存名称dump恢复 手动触发save![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/a56fdff44aee4efa96c2ce3615b69dc1.png)bgsave 优劣优点缺点 检查修复dump文件会触…

算法基础之耍杂技的牛

耍杂技的牛 核心思想&#xff1a; 贪心 推公式&#xff1a; 将 i 和 i1 个奶牛交换位置 比较交换位置后的危险系数最大值若Wi Si > Wi1 Si1 则交换前大 交换后更优 需要交换因此 按照WS从小到大排序 就是最优解 再计算危险系数 #include<iostream>#include<…

Spring学习之——事务控制

Spring中的事务控制 说明&#xff1a; JavaEE体系进行分层开发&#xff0c;事务处理位于业务层&#xff0c;Spring提供了分层设计业务层的事务处理解决方案。 Spring框架为我们提供了一组事务控制的接口。具体在后面的小节介绍。这组接口是在spring-tx.RELEASE.jar中。 spri…

24分+的医药顶刊带你学习表观组学解析超级热点“肿瘤耐药”的机制

对癌症患者采用治疗干预时获得性耐药是转移性癌症复发的主要原因。此前&#xff0c;获得性耐药发展的研究主要集中在识别耐药肿瘤中常见的基因突变。越来越多的证据表明&#xff0c;在永久性获得性耐药出现之前&#xff0c;癌症中存在一种表观遗传调控的可逆耐药状态&#xff0…

[足式机器人]Part3 机构运动学与动力学分析与建模 Ch00-1 坐标系与概念基准

本文仅供学习使用&#xff0c;总结很多本现有讲述运动学或动力学书籍后的总结&#xff0c;从矢量的角度进行分析&#xff0c;方法比较传统&#xff0c;但更易理解&#xff0c;并且现有的看似抽象方法&#xff0c;两者本质上并无不同。 2024年底本人学位论文发表后方可摘抄 若有…

关爱服务 |“冬日暖情”送温暖乐善公益行志愿服务活动(第十七期)

为大力弘扬“学习雷锋、奉献他人、提升自己”的志愿精神&#xff0c;有效整合动员全民志愿服务资源&#xff0c;全面推进清远市志愿服务事业发展。机构将以“三关爱”活动为主题&#xff0c;积极开展关爱他人、关爱自然、关爱社会志愿服务活动&#xff0c;积极宣传、倡导志愿者…

docker swarm 常用命令简介以及使用案例

docker swarm Docker Swarm 是Docker官⽅的跨节点的容器编排⼯具。⽤户只需要在单⼀的管理节点上操作&#xff0c;即可管理集群下的所有节点和容器 解决的问题 解决docker server的集群化管理和部署Swarm通过对Docker宿主机上添加的标签信息来将宿主机资源进⾏细粒度分区&am…

txt文档里筛选出重复数据,并保存到新的txt文档

txt文档里筛选出重复数据&#xff0c;并保存到新的txt文档 input_file rD:\pythonXangmu\quchong\input_file.txt #原始文档 #output_file output.txt#重复内容记录文档 output_file rD:\pythonXangmu\quchong\output.txt#绝对路径&#xff0c;解决报错找不到文件或文件夹 w…

20.Activity跳转时的参数传递

(1).如何传递数据 (2).如何接收数据 (3).如何回传数据