Linux C/C++ 嗅探数据包并显示流量统计信息

news2025/1/23 21:24:51

嗅探数据包并显示流量统计信息是网络分析中的一种重要技术,常用于网络故障诊断、网络安全监控等方面。具体来说,嗅探器是一种可以捕获网络上传输的数据包,并将其展示给分析人员的软件工具。在嗅探器中,使用pcap库是一种常见的方法,因为它提供了一种跨平台的接口,可以有效地访问操作系统的数据包捕获功能。

数据包捕获函数库(Libpcap)

Libpcap是一种独立于系统的用户层包捕获API接口,为底层网络监测提供了一个可移植的框架。它允许程序员使用简单的C语言编程接口,来捕获和分析网络数据包。要使用libpcap来嗅探数据包并显示流量统计信息,可以按照以下步骤进行:

  • 1.安装libpcap库:首先需要安装libpcap库,可以在大多数Linux发行版中使用包管理器进行安装,例如在Ubuntu中可以使用以下命令:sudo yum install libpcap-dev。
  • 2.创建数据包捕获程序:使用C语言编写程序,并引入libpcap库。在程序中,需要使用libpcap的函数来打开网络接口、捕获数据包、解码数据包等。
  • 3.数据包捕获:使用libpcap的pcap_open_live()函数打开网络接口(如eth0),并获取该接口的原始套接字(raw socket)。然后使用pcap_next()或pcap_next_ex()函数从原始套接字中读取数据包。
  • 4.数据包解码:对捕获到的数据包进行解码,提取协议字段和数据内容。
  • 5.流量统计和分析:对解码后的数据包进行流量统计和分析。例如,可以计算每个数据包的长度、接收到的数据包数量、每个协议的数据流量等。
  • 6.数据包过滤:使用BPF(Berkeley Packet Filter)算法对捕获到的数据包进行过滤。BPF算法的基本思想是在有BPF监听的网络中,网卡驱动将接收到的数据包复制一份交给BPF过滤器,过滤器根据用户定义的规则决定是否接收此数据包以及需要拷贝该数据包的那些内容,然后将过滤后的数据给与过滤器相关联的上层应用程序。
  • 7.数据展示:将分析结果以图形化或文本形式展示给用户。

实现上述功能的需要准备的知识点包括:C语言编程、网络协议知识、libpcap库的使用、BPF算法原理等。同时,需要对底层网络监测技术有一定的了解,以便更好地理解和实现嗅探器程序的功能。

怎样使用Wireshark/tcpdump进行数据包嗅探

嗅探数据包并显示统计信息,可以使用Wireshark这个网络协议分析工具。以下是使用Wireshark进行数据包嗅探的步骤:

  • 1.下载并安装Wireshark:访问Wireshark官网(https://www.wireshark.org/)下载适合你操作系统的版本,然后按照提示进行安装。
  • 2.打开Wireshark:在开始菜单或应用程序列表中找到Wireshark,双击打开。
  • 3.选择网络接口:在Wireshark主界面的顶部,点击“捕获”选项卡,然后选择你想要嗅探的网络接口。如果你不确定应该选择哪个接口,可以查看网络连接详细信息,找到正确的接口名称。
  • 4.开始嗅探:点击“捕获选项”按钮,设置捕获过滤器(可选),然后点击“开始”按钮开始嗅探数据包。
  • 5.停止嗅探:当你完成数据包嗅探后,点击“停止”按钮停止捕获。
  • 6.显示统计信息:在Wireshark主界面的顶部,点击“统计”选项卡,可以看到各种统计信息,如捕获的数据包数量、各层协议的数量等(在“每秒更新”下拉菜单中,选择适当值,例如“1秒”)。
  • 7.分析数据包:在“捕获”选项卡中,你可以看到实时捕获到的数据包。点击一个数据包,可以在右侧面板中查看该数据包的详细信息。你可以根据需要对数据包进行过滤、排序等操作,以便更好地分析网络流量。

使用tcpdump进行数据包嗅探的步骤如下:

  • 1.打开终端窗口并启动tcpdump。
  • 2.指定要嗅探的网络接口,例如:tcpdump -i eth0,其中“-i”后面跟着的是网络接口名称。
  • 3.抓取数据包,例如:tcpdump -i eth0 -w data.pcap,其中“-w”后面跟着的是输出文件的名称。
  • 4.分析和过滤数据包,例如:tcpdump -i eth0 host 192.168.1.101,表示只抓取目标主机为192.168.1.101的数据包。
  • 5.分析数据包的内容,可以使用工具如Wireshark打开刚刚保存的pcap文件进行进一步分析。

请注意,使用tcpdump需要具有管理员权限(sudo)。

对于网络安全人员,需要关注那些点

Sniff数据包实现流量统计的原理是基于网络数据包的捕获和解析。Sniff工具通过监听网络接口上的数据传输,对每个经过的数据包进行截获、分析和解码。然后,根据协议类型、源IP、目标IP、数据包长度等属性对数据包进行分类和统计。

对于网络安全人员,需要关注以下几点:

  • 1.Sniff工具的合法使用:Sniff工具主要用于网络管理、故障排查和程序调试等方面,也可以被黑客用来进行非法活动,如窃取敏感信息、进行网络攻击等。
  • 2.网络隔离和安全措施:为了保护网络安全,需要对网络进行适当的隔离和安全措施。例如,使用VLAN、防火墙等设备来限制网络访问和数据流动,以防止未经授权的访问和恶意攻击。
  • 3.数据包的过滤和分析:Sniff工具虽然可以对网络流量进行全面分析,但在实际应用中,可能需要对数据包进行过滤和筛选,以便更准确地掌握网络流量情况。例如,可以针对特定的协议、IP地址、端口等进行过滤,以排除无关数据包的干扰。
  • 4.警惕ARP欺骗攻击:ARP欺骗是一种常见的网络攻击手段,黑客通过伪造IP地址和MAC地址映射关系,可以截获网络数据包并进行恶意篡改。在使用Sniff工具时,需要防范ARP欺骗攻击,例如通过设置静态ARP映射表、使用ARP欺骗防御软件等措施来保护网络安全。

Linux C/C++ 嗅探数据包并显示流量统计信息

要实现嗅探数据包并根据网卡流量输出 TCP/UDP 流量信息,你可以参考以下步骤进行实现:安装并导入必要的库:首先,你需要安装一些库,如 libpcap(用于捕获和解析数据包)和 sys(用于获取系统时间)。

打开网络接口并捕获数据包:使用 libpcap 库打开网络接口(如 eth0),并设置过滤器(例如,仅捕获 TCP 和 UDP 数据包):

...
/* IP header */
struct sniff_ip {
    u_char  ip_vhl;                 /* version << 4 | header length >> 2 */
    u_char  ip_tos;                 /* type of service */
    u_short ip_len;                 /* total length */
    u_short ip_id;                  /* identification */
    u_short ip_off;                 /* fragment offset field */
#define IP_RF 0x8000            /* reserved fragment flag */
#define IP_DF 0x4000            /* dont fragment flag */
#define IP_MF 0x2000            /* more fragments flag */
#define IP_OFFMASK 0x1fff       /* mask for fragmenting bits */
    u_char  ip_ttl;                 /* time to live */
    u_char  ip_p;                   /* protocol */
    u_short ip_sum;                 /* checksum */
    struct  in_addr ip_src,ip_dst;  /* source and dest address */
};
#define IP_HL(ip)               (((ip)->ip_vhl) & 0x0f)
#define IP_V(ip)                (((ip)->ip_vhl) >> 4)

/* 剩下的TCP和UDP标头结构仅用于学习目的,因为计算ip报头中的总分组长度 */

/* TCP header */
typedef u_int tcp_seq;

struct sniff_tcp {
    u_short th_sport;               /* source port */
    u_short th_dport;               /* destination port */
    tcp_seq th_seq;                 /* sequence number */
    tcp_seq th_ack;                 /* acknowledgement number */
    u_char  th_offx2;               /* data offset, rsvd */
#define TH_OFF(th)      (((th)->th_offx2 & 0xf0) >> 4)
    u_char  th_flags;
#define TH_FIN  0x01
#define TH_SYN  0x02
#define TH_RST  0x04
#define TH_PUSH 0x08
#define TH_ACK  0x10
#define TH_URG  0x20
#define TH_ECE  0x40
#define TH_CWR  0x80
#define TH_FLAGS        (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
    u_short th_win;                 /* window */
    u_short th_sum;                 /* checksum */
    u_short th_urp;                 /* urgent pointer */
};

struct sniff_udp {
    u_short	uh_sport;		/* source port */
    u_short	uh_dport;		/* destination port */
    u_short	uh_ulen;		/* datagram length */
    u_short	uh_sum;			/* datagram checksum */
};
...
int main(int argc, char **argv) 
{
...

    while((argch = getopt(argc, argv, "Bkmgdi:t:")) != -1) {
        switch(argch) {
            case 'B':
                batch_mode = 1;
                break;

            case 'k':
                strncpy(show_suffix, "kByte/s", 32);
                traffic_unit = 1;
                break;

            case 'm':
                strncpy(show_suffix, "MByte/s", 32);
                traffic_unit = 2;
                break;

            case 'g':
                strncpy(show_suffix, "GByte/s", 32);
                traffic_unit = 3;
                break;

            case 't':
                sniff_timeout = atoi(optarg);
                break;

            case 'i':
                strncpy(ifname, optarg, IFNAMSIZ);
                break;

            case 'd':
                dflag = 1;
                break;

            default:
                fprintf(stderr, "Incorrect argument provided\n");
                usage();
                exit(1);

        }
    }

    /* 如果缺少位置筛选器参数,请退出。 */
    if(argc - optind < 1) {
        usage();
        exit(1);
    }

    /* 最后一个参数现在应该是筛选器字符串 */
    filter = argv[optind];

    /* 确定设备ifname的IPv4网络和网络掩码. */
    if(pcap_lookupnet(ifname, &netp, &netmask, errbuf) == -1) {
        fprintf(stderr, "pcap_lookupnet: %s\n", errbuf);
        exit(1);
    }


    if((capture = pcap_open_live(ifname, 65535, 1, 10, errbuf)) == NULL) {
        fprintf(stderr, "pcap_open_live: %s\n", errbuf);
        exit(1);
    }

    if(pcap_compile(capture, &comp_filter, filter, 0, netmask) != 0) {
        fprintf(stderr, "pcap_compile: %s\n", pcap_geterr(capture));
        exit(1);
    }

    if(pcap_setfilter(capture, &comp_filter) == -1) {
        fprintf(stderr, "pcap_setfilter: %s\n", pcap_geterr(capture));
        exit(1);
    }

    /* 清理回调 */
    if(atexit(exit_callback) != 0) {
        perror("atexit: ");
        exit(1);
    }

    /* 发出数据包捕获结束的信号. */
    if(signal(SIGALRM, output_data) == SIG_ERR) {
        perror("signal: failed to capture SIGALRM");
        exit(1);
    }

    /* 捕获中断信号以实现整洁的清理. */
    if(signal(SIGINT, cleanup_capture) == SIG_ERR) {
        perror("signal: failed to capture SIGINT");
        exit(1);
    }

    /* 获取NIC硬件地址以稍后确定数据包流. */
    if((mac_address = get_hw_address(ifname, dflag)) == NULL) {
        fprintf(stderr, "get_hw_address: failed to get hw address from %s\n", ifname);
        exit(1);
    }

    nic_dlt = pcap_datalink(capture);

    /* 选择一个物理层段大小 */
    switch(nic_dlt) {
        case DLT_EN10MB: /* Ethernet */
            phys_size = 14;
            break;

        case DLT_IEEE802: /* WiFi */
            phys_size = 22;
            break;

        case DLT_FDDI: /* Fiber interface */
            phys_size = 21;
            break;

        case DLT_LOOP: /* OpenBSD loop device or RAW device */
            phys_size = 12;
            break;

        case DLT_NULL:
            phys_size = 4;

        default:
            phys_size = 0;
            break;
    }

    if(dflag)
        fprintf(stderr, "phys_size: %d, nic_dlt: %d\n", phys_size, nic_dlt);

    /* 清除计时器结构并设置sniff_timeout秒的超时. */
...

    /* 这将导致发送SIGALARM以输出当前流量统计信息。. */
    if(setitimer(ITIMER_REAL, itvp, &oitv) < 0) {
        fprintf(stderr, "setitimer: failed setting timer\n");
        exit(1);
    }

    if(batch_mode == 0)
        output_header(ifname);

    /* 将捕获缓冲区中数据包的主pcap循环. */
    loop_status = pcap_loop(capture, -1, capture_callback, NULL);
...
}

...
void fprint_data(double in, double out) 
{
    switch(traffic_unit) 
    {
        case 1:
            in /= 1000;
            out /= 1000;
            break;
        case 2:
            in /= 1000000;
            out /= 1000000;
            break;
        case 3:
            in /= 1000000000;
            out /= 1000000000;
            break;
        default:
            in /= 1;
            out /= 1;
            break;
    }

...
}
...
unsigned short get_windowsize(void) {
    struct winsize ws;

    if(ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0) {
        return(-1);
    }

    return(ws.ws_row);
}
...
uint8_t * get_hw_address(char *ifname, int dflag) 
{
...

    ifap = ifa;

    if(sd < 0) 
    {
        freeifaddrs(ifap);
        return(NULL);
    }

    for(;ifa;ifa = ifa->ifa_next) 
    {
        if(ifa->ifa_data != 0) 
        {
            continue;
        }

        /* 查找是否与ifname匹配 */
        if(strncmp(ifname, ifa->ifa_name, sizeof(*ifname)) == 0) 
        {
            strncpy(req.ifr_name, ifa->ifa_name, IFNAMSIZ);
            if(ioctl(sd, SIOCGIFHWADDR, &req ) != -1 ) 
            {
                if((mac = malloc(sizeof(uint8_t)*MAX_ETHER_LEN)) == NULL) 
                {
                    perror("malloc: ");
                    return(NULL);
                }
                memcpy(mac, (uint8_t*)req.ifr_ifru.ifru_hwaddr.sa_data, MAX_ETHER_LEN);
                break;
            }
        }
    }

    freeifaddrs(ifap);
    return mac;
}

If you need the complete source code, please add the WeChat number (c17865354792)

运行结果:

根据字节数和时间计算 TCP 和 UDP 的流量(以字节/秒为单位),将 TCP 和 UDP 的流量信息按照指定的格式(如 k/s、m/s 等)输出到控制台。

总结

嗅探数据包是一种网络抓包技术,可以捕获网络上传输的数据包并进行分析。通过统计流量,可以了解网络的使用情况、发现异常行为和攻击等。

Welcome to follow WeChat official account【程序猿编码

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

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

相关文章

怎么启动MySQL服务

你可能也遇到这样的问题&#xff0c;打开navicat&#xff0c;但是点击数据库连接不上&#xff0c;这就有可能是数据库服务没有启。报错如下图所示 解决方法一win11为例&#xff0c;右键此电脑&#xff0c;找到管理。 找到服务和应用吃程序&#xff0c;点击服务。 往下找到MySQL…

ti am335 RT-LINUX测试

RT-Linux是一个基于Linux内核的实时操作系统&#xff0c;它在满足Linux操作系统的通用性的同时兼顾 实时性能&#xff0c;它的核心是Linux内核的一个实时扩展&#xff0c;它为实时任务提供了必要的调度机制和时间管理。通过采用抢占式调度策略&#xff0c;高优先级的实时任务可…

肉眼无法读懂是二进制独有的浪漫——一篇博客学懂文件操作(C语言)

目录 一、为什么使用文件 二、什么是文件 2.1程序文件 2.2数据文件 2.3文本文件和二进制文件 2.4文件名 三、文件的打开和关闭 3.1 文件指针 3.2 文件的打开和关闭 3.3文件的顺序读写函数 3.3.1流的概念 3.3.2输入输出的概念 3.3.3函数操作 3.4文件的随机读写函…

miniblink学习

1.基本使用 main.cpp #include "webwidget.h" #include <QApplication> #include "wke.h" //工作目录是指当前目录&#xff0c;运行目录是指exe所在路径。 int main(int argc, char *argv[]) {QApplication a(argc, argv);//设置miniblink的全路径文…

C# GFPGAN 图像修复

效果 项目 代码 using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; using OpenCvSharp; using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.Windows.Forms;namespace 图像修复 {pu…

leetcode-62.不同路径

1. 题目 2. 解答 dp[i][j]表示机器人位于第i&#xff0c;j位置的时候&#xff0c;有多少路径 如果i 0&#xff0c;dp[i][j] 1;如果j 0&#xff0c;dp[i][j] 1;其他情况dp[i][j] dp[i-1][j] dp[i][j - 1] #include <stdio.h>int solve(int m, int n) {int dp[m][…

一场直播脚本的策划及话术怎么写?

一场直播脚本的策划及话术参考 直播流程安排示范:120 分钟直播流程设计(过款型) 标准化直播话术单元(单款产品话术模板) I 直播 120 分钟标准化流程 I 分解为 4 个 30 分钟直播单元 I 30 分钟前期介绍 2-3 个款作为起步 每款持续时长 10 分钟,10 分钟的时间里 ①卖点引出 2 …

找不到msvcp100.dll无法继续执行此代码怎么解决,快速修复dll问题的5个方法

电脑已经成为我们生活和工作中不可或缺的一部分&#xff0c;在我们使用电脑的时候&#xff0c;总会遇到一些技术问题&#xff0c;其中之一就是“找不到msvcp100.dll”。msvcp100.dll是一个动态链接库文件&#xff0c;它是Microsoft Visual C 2010 Redistributable Package的一部…

G.711语音编解码器详解

语音编解码利用人听觉上的冗余对语音信息进行压缩从而达到节省带宽的目的。值得注意的是,本文说的是语音编解码器,也就Speech codec,而常用的还有另一种编解码器称作音频编解码器,英文是Audio codec,它们的区别如下。 以前在学校的时候研究了很多VoIP的编解码器从G.723到A…

java.sql.SQLFeatureNotSupportedException解决方法

使用MyBatis访问数据库查询数据时报错&#xff1a; Caused by: java.sql.SQLFeatureNotSupportedExceptionat com.alibaba.druid.pool.DruidPooledResultSet.getObject(DruidPooledResultSet.java:1771)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun…

在node中操作mysql数据库

目录 前言 在node中安装mysql模块 引入绑定数据库 验证mysql模块能否正常工作 增 便捷方式 改 便捷方式 删 查 前言 本文介绍在node中对数据库使用sql语句进行增删改查 在node中安装mysql模块 npm i mysql 引入绑定数据库 导入mysql模块 const mysql require(m…

2、Windows下安装

目录 一.安装 1、双击下载的程序&#xff1a; 2、加载完成后&#xff0c;会进入如下界面&#xff08;选第一个Developer Default&#xff09; 3、然后点击Next 点击Execute 然后Next 4.继续next注意端口为3306 5.继续next&#xff0c;输入账户密码&#xff08;要有大小写…

C# 图解教程 第5版 —— 第4章 类型、存储和变量

文章目录 4.1 C# 程序是一组类型声明4.2 类型是一种模板&#xff08;*&#xff09;4.3 实例化类型4.4 数据成员和函数成员4.5 预定义类型4.6 用户定义类型4.7 堆和栈&#xff08;*&#xff09;4.8 值类型和引用类型4.9 变量4.9.1 变量声明4.9.2 多变量声明&#xff08;*&#x…

“视频剪辑:如何分割与转换视频格式,一探究竟!

如今&#xff0c;视频已成为我们生活中不可或缺的一部分。无论是记录生活点滴、分享兴趣爱好&#xff0c;还是传递信息&#xff0c;视频都已经成为一种非常有效的表达方式。而在视频制作过程中&#xff0c;剪辑是至关重要的一环。通过剪辑&#xff0c;我们可以去掉不需要的内容…

[23] T^3Bench: Benchmarking Current Progress in Text-to-3D Generation

3D生成蓬勃发展&#xff0c;主流方法通过事例比较和用户调查来评价方法好坏&#xff0c;缺少客观比较指标&#xff1b;本文提出Bench&#xff0c;首次综合比较了不同生成方法&#xff1b;具体来说&#xff0c;本文设计了质量评估&#xff08;Quality Assessment&#xff09;和对…

nginx优化和防盗链

nginx优化 1.nginx隐藏版本号 因为是一个高性能&#xff0c;轻量级的工具吗&#xff0c;更新版本速度很快&#xff0c;功能很强大但是BUG很多&#xff0c;很容易被攻破&#xff0c;所以需要隐藏版本号来减少服务器被攻击的威胁。 隐藏版本号的第一步就是如何查看版本号 curl …

蓝桥杯每日一题2023.10.15

数列求值 - 蓝桥云课 (lanqiao.cn) 题目描述 题目分析 我们发现如果一项一项相加会造成结果过大从而答案错误&#xff0c;所以我们每次只需要取后四位经行计算即可 #include<bits/stdc.h> using namespace std; int a[20190329]; int main() {a[1] 1, a[2] 1, a[3]…

Flutter 剪裁(Clip)

&#x1f525; ClipOval &#x1f525; 子组件为正方形时剪裁成内贴圆形&#xff1b;为矩形时&#xff0c;剪裁成内贴椭圆 裁剪纯色背景 ClipOval(child: Container(width: 300.w,height: 300.w,decoration: const BoxDecoration(color: Colors.red),),), 裁剪背景图片 裁剪前…

17.SpringBoot前后端分离项目之简要配置二

如何配置前端请求和后端响应&#xff08;2&#xff09; 登录接口 前端&#xff1a; 后端控制器&#xff1a; 在My3Controller RequestMapping("/login") public ResponseBody RestObject login(RequestBody UserUI userUI){System.out.println("login方法&…

Linux第六章-Vi和Vim编辑器

vi和vim的基本介绍 Linux系统会内置vi文本编辑器 vim具有程序编辑的能力&#xff0c;可以看做是vi的增强版本。 vi和vim的三种模式 正常模式 以vim打开一个档案就直接进入一般模式了&#xff08;这是默认的模式&#xff09;。在这个模式中&#xff0c;可以使用上下键来移动…