网络嗅探器的设计与实现(2024)-转载

1.题目描述

参照 raw socket 编程例子,设计一个可以监视网络的状态、数据流动情况以及网络上传输 的信息的网络嗅探器。

2.运行结果

3.导入程序需要的库

请参考下面链接: 

 导入WinPcap到Clion (2024)-CSDN博客

4.参考代码

#define HAVE_REMOTE
#define LINE_LEN 16

#include "winsock.h"
#include <WinSock2.h>
#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);

char judge;
int length;

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("没有设备描述信息!");
        }

    }
    if (i == 0) {
        printf("\n请先安装WinPcap!");
        return -1;
    }
    printf("-------------------------------------------------------------------\n");
    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;
    }
    printf(" 是否要输出报文数据(y/n) : ");
    scanf("%c", &judge);
    if (judge != 'n') {
        printf("请输入要限制要输出报文信息长度(-1不限制) : ");
        scanf("%d", &length);
    }
    printf("\n\n 正在监听通过%s的数据报...\n\n", device->description);
    pcap_freealldevs(alldevs); //释放设备列表
    pcap_loop(adhandle, 0, packet_handler, NULL); //开始捕捉

    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;
    udp_header *udp_hd;
    tcp_header *tcp_hd;
    ethe_header *ethe_hd;
    int ip_len, tcp_len, start;
    u_short sport, dport;

    printf("\n");

    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("\t时间:%s\n", now);


    ethe_hd = (ethe_header *) pkt_data;
    ip_hd = (ip_header *) (pkt_data + 14);
    ip_len = (ip_hd->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->proto == 17) {
        printf("\t协议:UDP");
        start = ip_len + 8;
    } else if (ip_hd->proto == 6) {
        printf("\t协议:TCP");
        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->proto == 1) {
        printf("\t协议:ICMP");
        start = ip_len + 23;
    } else printf("\t协议:其他");
    //printf("start=%d\n",start);

    printf("\t\t\t数据报的长度: %d\n", header->caplen);
    printf("\tIP头的长度: %d"
                 "\t\tIP包存活时间: %d\n", ip_hd->tlen, ip_hd->ttl);
    printf("\t源IP地址: %d.%d.%d.%d:%d"
           "\t目的IP地址: %d.%d.%d.%d:%d\n"
           "\t源端口: %d"
           "\t\t\t目的端口: %d\n"
           "\t源物理地址: %x-%x-%x-%x-%x-%x"
           "\t目的物理地址: %x-%x-%x-%x-%x-%x\n",
           ip_hd->saddr.b1, ip_hd->saddr.b2, ip_hd->saddr.b3, ip_hd->saddr.b4,
           ip_hd->daddr.b1, ip_hd->daddr.b2, ip_hd->daddr.b3, ip_hd->daddr.b4, sport, dport,
           ethe_hd->mac_source_address.b1, ethe_hd->mac_source_address.b2, ethe_hd->mac_source_address.b3,
           ethe_hd->mac_source_address.b4, ethe_hd->mac_source_address.b5, ethe_hd->mac_source_address.b6,
           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);
    //输出数据部分
    if (judge == 'y') {
        printf("\n\t数据部分内容为:\n\t");
        if (length == -1) len = (header->caplen) + 1;
        else len = (length > header->caplen + 1 - start) ? (header->caplen + 1) - start : length;
        for (int i = start; (i < start + len); i++) {
            printf("%2.2x ", pkt_data[i - 1]); //也可以改为 %c 以 ascii码形式输出。
            if ((i % LINE_LEN) == 0) printf("\n\t");
        }
    }
    cout<<endl<<"---------------------------------------------------------------------"<<endl;
}

 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/300571.html

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

相关文章

一起玩儿物联网人工智能小车(ESP32)——24. 变量与函数(二)

摘要&#xff1a;本文介绍变量和函数的基本知识 在前面一篇中了解了变量&#xff0c;接着就来了解一下函数。函数是程序中的一个关键概念&#xff0c;它可以简化程序的编写&#xff0c;使代码更加模块化、可复用&#xff0c;提高程序的可读性。其实在之前已经多次遇到函数了&am…

VELO维乐携手【晓饰记】创始人胡晓,引领潮流新饰界!

不知道大家还记不记得2023年维乐带着自己满满的诚意闪现英伦时尚之都为全世界带来了一场无与伦比的视觉盛宴&#xff01;而依照维乐固有的执念&#xff0c;从不会让自己止步的精神&#xff0c;维乐又带着自己的维乐坐垫找到了CoCo胡晓&#xff0c;【晓饰记】的首饰品牌创始人、…

Video classification with UniFormer基于统一分类器的视频分类

本文主要介绍了UniFormer: Unified Transformer for Efficient Spatial-Temporal Representation Learning 代码&#xff1a;https://github.com/Sense-X/UniFormer/tree/main/video_classification UNIFormer 动机 由于视频具有大量的局部冗余和复杂的全局依赖关系&#xf…

Matplotlib for C++不完全手册

matplotlib-cpp是Matplotlib&#xff08;MPL&#xff09;为C提供的一个用于python的matplotlib绘图库的C包装器。它的构建类似于Matlab和matplotlib使用的绘图API。 However, the function signatures might differ and Matplotlib for C does not support the full functional…

Java学习苦旅(二十六)——反射,枚举和lamda表达式

本篇博客将讲解反射&#xff0c;枚举和lamda表达式。 文章目录 反射定义用途反射基本信息反射相关的类Class类Class类中相关的方法 反射示例反射的优缺点优点缺点 枚举背景及定义常用方法枚举优缺点优点缺点 Lambda表达式背景语法函数式接口定义基本使用 变量捕获Lambda在集合…

在drawio中使用BPMN2.0绘制详细的业务流程图和编排模型

在drawio中使用BPMN2.0绘制详细的业务流程图和编排模型 drawio是一款强大的图表绘制软件&#xff0c;支持在线云端版本以及windows, macOS, linux安装版。 如果想在线直接使用&#xff0c;则直接输入网址draw.io或者使用drawon(桌案), drawon.cn内部完整的集成了drawio的所有功…

Qt pro文件

1. 项目通常结构 2.pri文件 pri文件可定义通用的宏&#xff0c;例如创建一个COMMON.pri文件内容为 COMMON_PATH D:\MyData 然后其它pri或者pro文件如APPTemplate.pro文件中通过添加include(Common.pri) &#xff0c;QtCreator就会自动在项目结构树里面创建对应的节点 3.变量…

如何信任机器学习模型的预测结果?

在本篇中&#xff0c;我将通过一个例子演示在 MATLAB 如何使用 LIME 进行复杂机器学习模型预测结果的解释。 我使用数据集 carbig&#xff08;MATLAB 自带的数据集&#xff09;训练一个回归模型&#xff0c;用于预测汽车的燃油效率。数据集 carbig 是 70 年代到 80 年代生产的汽…

Android AIDL 创建的DEMO

使用AIDL创建一个demo 主要参考文件&#xff0c; 以及其他地址 Android 接口定义语言 (AIDL) | Android 开发者 | Android Developers 绑定服务概览 | Android 开发者 | Android Developers Android 接口定义语言 (AIDL) Android 接口定义语言 (AIDL) 与您可能使用…

倍思科技红海突围要义:紧随新趋势,“实用而美”理念从一而终

移动数码周边市场始终不缺热度。 销售端是业绩的节节高升&#xff0c;如在2023年京东双十一&#xff0c;移动数码周边产品销售成果丰硕&#xff0c;根据京东战报&#xff0c;大功率充电器成交额同比提升 200%&#xff0c;65W以上移动电源成交额同比提升 150%&#xff0c;自带线…

服务器内存不足怎么办?会有什么影响?

服务器内存&#xff0c;也被称为RAM&#xff08;Random Access Memory&#xff09;&#xff0c;是一种临时存储设备&#xff0c;用于临时存放正在运行的程序和数据。它是服务器上的超高速存储介质&#xff0c;可以快速读取和写入数据&#xff0c;提供给CPU进行实时计算和操作。…

Python基础入门第八课笔记(自定义函数 lambda)

什么时候用lambda表达式&#xff1f; 当函数有一个返回值&#xff0c;且只有一句代码&#xff0c;可以用lambda简写。 2、lanbda语法 lambda 形参 : 表达式 注意&#xff1a; 1、形参可以省略&#xff0c;函数的参数在lambda中也适用 2、lambda函数能接收任何数量的参数但只能…

Dockerfile的EXPOSE

文章目录 环境总结测试使用EXPOSE测试1&#xff1a;不做端口映射测试2&#xff1a;-p 8080:80测试3&#xff1a;-P测试4&#xff1a;--networkhost 不使用EXPOSE 参考 环境 RHEL 9.3Docker Community 24.0.7 总结 如果懒得看测试的详细信息&#xff0c;可以直接看结果&#…

MYSQL篇--sql优化高频面试题

sql优化 1 如何定位及优化SQL语句的性能问题&#xff1f;创建的索引有没有被使用到?或者说怎么才可以知道这条语句运行很慢的原因&#xff1f; 其实对于性能比较低的sql语句定位&#xff0c;最重要的也是最有效的方法其实还是看sql的执行计划&#xff0c;而对于mysql来说 它…

228. 汇总区间

给定一个 无重复元素 的 有序 整数数组 nums 。 返回 恰好覆盖数组中所有数字 的 最小有序 区间范围列表 。也就是说&#xff0c;nums 的每个元素都恰好被某个区间范围所覆盖&#xff0c;并且不存在属于某个范围但不属于 nums 的数字 x 。 列表中的每个区间范围 [a,b] 应该按…

[C#]使用onnxruntime部署yolov8-onnx实例分割模型

【官方框架地址】 https://github.com/ultralytics/ultralytics.git 【算法介绍】 YOLOv8 是一个 SOTA 模型&#xff0c;它建立在以前 YOLO 版本的成功基础上&#xff0c;并引入了新的功能和改进&#xff0c;以进一步提升性能和灵活性。具体创新包括一个新的骨干网络、一个新…

OpenCV图像处理|1.1 OpenCV介绍与环境搭建

1.1.1 介绍 OpenCV&#xff08;Open Source Computer Vision Library&#xff09;开放源代码计算机视觉库&#xff0c;主要算法涉及图像处理、计算机视觉和机器学习相关方法。OpenCV 其实就是一堆 C 和 C语言的源代码文件&#xff0c;这些源代码文件中实现了许多常用的计算机视…

智慧医院预约及支付平台—智慧支付

医保支付流程 自费支付流程 智慧医院支付业务介绍 社保卡绑定(身份认证) 认证方案:银行身份已验证客户,可通过本人银行登记的手机号码登录医院APP后,在完善APP注册身份信息时,将相关信息发送苏州银行,由银行核对客户身份信息正确性并将社保卡绑定本人手机。核实后的身份…

Java:File类详解

文章目录 1、概述2、创建File实例3、常用方法3.1 获取功能的方法3.2 绝对路径和相对路径3.3 判断功能的方法3.4 创建删除功能的方法3.5 文件过滤功能的方法 4、文件夹的遍历5、综合练习5.1 创建文件夹5.2 查找文件&#xff08;不考虑子文件夹&#xff09;5.3 查找文件&#xff…

视频剪辑技巧:添加srt字幕,提升视频品质的方法

在视频制作和剪辑过程中&#xff0c;字幕的添加是一项常见的技巧。通过添加srt字幕&#xff0c;可以提升视频的品质和观感&#xff0c;让观众更好地理解视频内容。下面一起来看云炫AI智剪如何批量添加srt字幕的方法&#xff0c;如何通过这些技巧提升视频品质。 原视频画面与添…