Linux C/C++ 分析网络流量(十六进制TCP数据包分析)

news2025/1/31 8:11:50

在分析TCP数据包时,理解TCP协议的工作原理和报文格式是关键。TCP是一种面向连接的、提供可靠的、端到端的字节流传输服务。其头部结构包括源端口、目标端口、序列号、确认应答号等字段。序列号是在建立连接时由计算机生成的随机数作为初始值,每发送一次数据,就累加一次该数据字节数的大小,而确认应答号是指下一次期望收到的数据的序列号。

抓包和分析数据包是理解TCP/IP协议的重要手段。Wireshark是最知名的网络通讯抓包分析工具,可以截取各种网络封包并显示详细信息。通过抓包和分析数据包,我们可以深入理解TCP帧格式及“TCP三次握手”,进一步提高理论联系实践的能力。

例如,我们选择一个TCP数据包进行分析,在数据包详细信息面板中,我们可以看到TCP协议的详细信息,包括TCP标志位、序号、确认号、窗口大小等信息。此外,我们还可以查看数据包的十六进制数据。

总的来说,TCP数据包的分析原理主要涉及对TCP协议的理解、使用相关工具进行数据包抓取和分析以及理解TCP头部结构等方面。处理细节则包括如何从大量的数据包中筛选出需要的信息,如何理解和解析TCP协议的各种字段等。

理解TCP协议工作原理和报文

TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。它在互联网协议(IP)网络上通过TCP/IP协议栈进行工作。
TCP的工作原理可以概括为以下几个方面:

1.建立连接:在源主机和目标主机之间建立连接,以便进行数据传输。
2.编号和排序数据段:在连接建立后,源主机按顺序发送数据段,每个数据段都有一个编号,以便目标主机重新排序。
3.确认和重传:目标主机对接收到的数据段进行确认,如果数据段丢失或损坏,则发送请求重传的信号。
4.流量控制:TCP使用窗口机制来控制数据的流量,以避免因接收方缓冲区满而造成的数据丢失。
5.关闭连接:当数据传输完成时,连接将被关闭。

TCP的报文格式包括以下几个部分:

1.源端口和目标端口:指示数据从哪个进程来,到哪个进程去。
2.序号:表示从TCP源端向TCP目标端发送的数据字节流中的第一个数据字节。
3.确认号:包含目标端所期望收到源端的下一个数据字节的序号。
4.TCP首部长度:表示该TCP头部有多少个32位(以4个字节为单位)。
5.标志位:包括紧急标志(URG)、确认标志(ACK)、推送标志(PSH)、可重用标志(RST)、同步标志(SYN)和终止标志(FIN)等。
6.窗口大小:表示接收方可以接收的最大数据量。
7.校验和:用于校验数据的有效性。
8.紧急指针:当URG标志位为1时,表示紧急数据的位置。
9.数据部分:包含实际传输的数据。

TCP的报文格式根据不同的用途和选项可能会有所不同,但以上是基本组成部分。理解TCP报文格式对于理解TCP协议的工作原理和实现可靠传输至关重要。

TCP怎么实现可靠传输

TCP通过以下几种机制来实现可靠传输:

  1. 序列号和确认机制:每个TCP包都有一个序列号,接收方通过发送端的确认信息来确认收到的数据,并告知发送方下一个期望接收的数据序号。

  2. 超时重传:发送方在发送数据后启动一个计时器,如果在规定时间内没有收到接收方的确认信息,就会认为数据丢失,然后重新发送数据。

  3. 滑动窗口协议:接收方使用滑动窗口来控制数据的流量和接收速度。滑动窗口可以指定接收方现在能够接受的最大数据量,发送方需要确保在窗口范围内发送数据。

  4. 流量控制:TCP使用基于接收方通告的窗口大小来控制数据发送速率,确保发送方不会以过快的速度发送数据,使接收方无法处理。

  5. 拥塞控制:TCP通过调整发送方的发送速率来避免网络拥塞。通过监测网络的拥塞程度并及时降低发送速率,使得整个网络能够维持在一个合理的状态。

以上是TCP实现可靠传输的主要机制,通过这些机制,TCP可以在不可靠的网络环境下实现可靠的数据传输。

tcpflow - 分析网络流量

tcpflow是一个功能强大的、基于命令行的免费开源工具,用于在Unix之类的系统(如Linux)上分析网络流量。它可以捕获通过TCP连接接收或传输的数据,并存储在文件中供以后分析,采用的格式便于协议分析和调试。

tcpflow的工作原理是基于LBL Packet Capture Library,支持丰富的过滤条件,能够捕获网络或存储文件中的数据包,并按照正常顺序重建数据流。每一条TCP流都会被存储到独立的文件中,方便以后分析。与tcpdump相比,tcpflow会重新构建真实的数据流,并且会分开存储。

当你想要使用tcpflow命令来捕获和输出TCP流量时,以下是一些相关的例子:

  1. 基本使用:
    tcpflow -r pcap_file.pcap
    
    这个命令将读取一个PCAP文件(例如Wireshark捕获到的网络数据包),并将TCP流量保存到相应的文件或屏幕上。

默认情况下,tcpflow将所有捕获的数据存储在表单中具有名称的文件中(如果使用某些选项(如时间戳 ),这可能会有所不同)。现在让我们做一个目录列表,看看是否在任何文件中捕获了tcp流。

还生成了一个XML报告,含有关于该程序的信息,比如它是如何编译的、它在哪台计算机上运行以及每条TCP连接的记录。

  1. 指定输出目录:

    tcpflow -o output_directory -r pcap_file.pcap
    

    这个命令将指定TCP流量的输出目录。每个流将被保存为单独的文件,文件名由IP地址和端口组成。

  2. 只显示请求或响应:

    tcpflow -r pcap_file.pcap 'src host X.X.X.X'
    tcpflow -r pcap_file.pcap 'dst host X.X.X.X'
    

    这两个命令将只捕获某个特定源IP地址或目标IP地址的请求或响应流量。

  3. 过滤特定端口:

    tcpflow -r pcap_file.pcap 'tcp port 80'
    

    这个命令将只捕获TCP端口为80的流量。

  4. 高亮显示输出:

    tcpflow -C -r pcap_file.pcap
    

    这个命令将以彩色高亮的方式显示输出结果,以便更容易阅读和理解。

  5. 指定接口名称
    要从特定网络接口捕获数据包,请使用-i标志指定接口名称。

    tcpflow -i eth0 port 80
    

有关更多信息和用法选项,请参见tcpflow手册页。

man tcpflow

Linux C/C++ 分析网络流量(十六进制TCP数据包分析)

编写主要目的是旧的tcpflow不提供十六进制控制台输出。Simson L.Garfinkel的新tcpflow需要一个libcairo-dev,这需要对我的服务器系统有很大的x11依赖性。我认为tcpflow是一个命令行工具,我真的不需要pdf报告。编译新的tcpflow很困难,而且根本不能禁用libcairo。

...
void hexdump(const char *buffer, size_t size)
{
...

    for (;;) {
        const char *line_end = line_start + LINE_CHAR_COUNT > buffer_end
                             ? buffer_end
                             : line_start + LINE_CHAR_COUNT;

        if (line_start == line_end) {
            break;
        }   
...

        // hex part
...

        // blank
        count += snprintf(output + count, sizeof(output), "    ");

        // acsii part
        for (const char *p = line_start; p < line_end; ++p) {
            count += snprintf(output + count, sizeof(output), "%c",
                              isprint(*p) ? *p : '.');
        }   

        printf("%s\n", output);

        line_start = line_end;
    }   
}

void process_ip_packet(const struct timeval *ts,
                       const char *buffer, size_t size)
{
    if (size < sizeof(struct ip)) {
        die("invalid ip packet length");
    }

...

    process_tcp_packet(ts,
                       ntohl(ip_header->ip_src.s_addr),
                       ntohl(ip_header->ip_dst.s_addr),
                       buffer + ip_header_len,
                       ip_len - ip_header_len);
}

void process_tcp_packet(const struct timeval *ts,
                        u_int32_t src_addr, u_int32_t dst_addr,
                        const char *buffer, size_t size)
{
...

    if (size < sizeof(struct tcphdr)) {
        die("invalid tcp packet length");
    }

...
    if (tcp_header_len >= size) {
        return;
    }

    if (g_option_color) {
        if (src_addr != last_src_addr || dst_addr != last_dst_addr ||
            src_port != last_src_port || dst_port != last_dst_port) {
            last_src_addr = src_addr;
            last_dst_addr = dst_addr;
            last_src_port = src_port;
            last_dst_port = dst_port;
            current_color = !current_color;
        }
        printf("%s", colors[current_color]);
    }

    if (g_option_display_header) {
...
        strftime(format_time, sizeof(format_time), "%Y-%m-%d %H:%M:%S", &tm);
        printf("%s.%ld %d.%d.%d.%d:%d => %d.%d.%d.%d:%d\n",
               format_time, ts->tv_usec / 1000,
               (src_addr & 0xff000000) >> 24,
               (src_addr & 0x00ff0000) >> 16,
               (src_addr & 0x0000ff00) >> 8,
               src_addr & 0x000000ff,
               src_port,
               (dst_addr & 0xff000000) >> 24,
               (dst_addr & 0x00ff0000) >> 16,
               (dst_addr & 0x0000ff00) >> 8,
               dst_addr & 0x000000ff,
               dst_port);
    }

    // print hex data
    hexdump(buffer + tcp_header_len, size - tcp_header_len);

    if (g_option_color) {
        printf("%s", "\033[0m");
    }

    printf("\n");
}


...
void print_usage(const char *prog_name)
{
    fprintf(stderr, "usage: %s [-Ce] <pcap_file> \n", prog_name);
    fprintf(stderr, "   -C do not display packet description\n");
    fprintf(stderr, "   -e output in alternating colors\n");
}

void packet_handler(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes)
{
    if (h->len <= g_datalink_header_length) {
        die("invalid datalink packet length");
    }

    process_ip_packet(&h->ts, (const char *)bytes + g_datalink_header_length,
                      h->len - g_datalink_header_length);
}

int main(int argc, char *argv[])
{
...

    while ((opt = getopt(argc, argv, "Ce")) != -1) {
        switch (opt) {
        case 'C':
            g_option_display_header = false;
            break;
        case 'e':
            g_option_color = true;
            break;
        default:
            print_usage(argv[0]);
            exit(1);
        }
    }

    if (optind >= argc) {
        print_usage(argv[0]);
        exit(1);
    }

    const char *pcap_file_name = argv[optind];
    pcap_t *pd = pcap_open_offline(pcap_file_name, errbuf);
    if (NULL == pd) {
        die("%s", errbuf);
    }

    int dlt = pcap_datalink(pd);
    if (DLT_NULL == dlt) {
        g_datalink_header_length = 4;
    } else if (DLT_RAW == dlt) {
        g_datalink_header_length = 0;
    } else if (DLT_EN10MB == dlt || DLT_IEEE802 == dlt) {
        g_datalink_header_length = 14;
    } else if (DLT_PPP == dlt) {
        g_datalink_header_length = 4;
    } else if (DLT_LINUX_SLL == dlt) {
        g_datalink_header_length = 16;
    } else {
        fprintf(stderr, "unknown datalink type\n");
        return -1;
    }

    struct bpf_program filter;
    if (pcap_compile(pd, &filter, "tcp", 1, 0) != 0) {
        die("%s", pcap_geterr(pd));
    }
    if (pcap_setfilter(pd, &filter) != 0) {
        die("%s", pcap_geterr(pd));
    }
    
    if (pcap_loop(pd, -1, packet_handler, NULL) != 0) {
        die("%s", pcap_geterr(pd));
    }

...
}

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

运行结果:

在这里插入图片描述Wireshark抓包展示效果:

总结

在进行十六进制TCP数据包分析时,我们首先需要捕获网络流量,获取TCP数据包。这可以通过网络抓包工具(如Wireshark)实现。然后,对捕获到的数据包进行解析,提取出TCP头部的各个字段和数据部分。

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

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

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

相关文章

人工智能学习4(特征选择)

编译工具&#xff1a;PyCharm 有些编译工具在绘图的时候不需要写plt.show()或者是print就可以显示绘图结果或者是显示打印结果&#xff0c;pycharm需要&#xff08;matplotlib.pyplot&#xff09; 文章目录 编译工具&#xff1a;PyCharm 特征选择嵌入法特征选择练习&#xff…

K8S客户端二 使用Rancher部署服务

Rancher容器云管理平台 本博客中使用了四台服务器&#xff0c;如下 rancher服务器k8s-masterk8s-worker01k8s-worker02 一、主机硬件说明 序号硬件操作及内核1CPU 4 Memory 4G Disk 100GCentOS72CPU 4 Memory 4G Disk 100GCentOS73CPU 4 Memory 4G Disk 100GCentOS74CPU 4 …

如何确定短线的买入卖出时机?

短线投资制胜的一个关键能力&#xff0c;就是精准地找到买入卖出时机。那么&#xff0c;怎么样才能获得这种关键能力呢&#xff1f; 在这节课里&#xff0c;我们将给大家梳理一下常见的短线买入卖出时机&#xff0c;并通过案例讲解帮助大家理解。话不多说&#xff0c;赶紧进入主…

[论文阅读]Generalized Attention——空间注意力机制

Generalized Attention An Empirical Study of Spatial Attention Mechanisms in Deep Networks 论文网址&#xff1a;Generalized Attention 论文代码&#xff1a;文章最后有GeneralizedAttention的实现代码 简读论文 本文主要研究了深度学习网络中的注意力机制。作者们从不…

VR 实现 Splash Screen 效果

文章目录 背景官方实现逆向分析 背景 手机 App 在实现 Splash Screen 的时候&#xff0c;目前都有成熟的方案可以参考&#xff0c;但是在做 VR 开发时&#xff0c;要如何实现一个 App 自己的 Splash Screen &#xff0c;下面是我们基于 PICO & OCULUS 进行业务开发时经过探…

Postman被低估的功能 — 自动化接口测试

| 背景 该篇文章针对已经掌握 Postman 基本用法的读者&#xff0c;即对接口相关概念有一定了解、已经会使用 Postman 进行模拟请求的操作。 当前环境&#xff1a; Window 7 - 64 Postman 版本&#xff08;免费版&#xff09;&#xff1a;Chrome App v5.5.3 不同版本页面 U…

Hdoop学习笔记(HDP)-Part.17 安装Spark2

目录 Part.01 关于HDP Part.02 核心组件原理 Part.03 资源规划 Part.04 基础环境配置 Part.05 Yum源配置 Part.06 安装OracleJDK Part.07 安装MySQL Part.08 部署Ambari集群 Part.09 安装OpenLDAP Part.10 创建集群 Part.11 安装Kerberos Part.12 安装HDFS Part.13 安装Ranger …

Mac卸载、安装Python

卸载 说明 对于删除 Python&#xff0c;我们首先要知道其具体都安装了什么&#xff0c;实际上&#xff0c;在安装 Python 时&#xff0c;其自动生成&#xff1a; Python framework&#xff0c;即 Python 框架&#xff1b;Python 应用目录&#xff1b;指向 Python 的连接。 …

node.js-连接SQLserver数据库

1.在自己的项目JS文件夹中建文件&#xff1a;config.js、mssql.js和server.js以及api文件夹下的user.js 2.在config.js中封装数据库信息 let app {user: sa, //这里写你的数据库的用户名password: ,//这里写数据库的密码server: localhost,database: medicineSystem, // 数据…

Vue + Element ui 实现动态表单,包括新增行/删除行/动态表单验证/提交功能

原创/朱季谦 最近通过Vue Element ui实现了动态表单功能&#xff0c;该功能还包括了动态表单新增行、删除行、动态表单验证、动态表单提交功能&#xff0c;趁热打铁&#xff0c;将开发心得记录下来&#xff0c;方便以后再遇到类似功能时&#xff0c;直接拿来应用。 简化的页…

C-语言每日刷题

目录 [蓝桥杯 2015 省 A] 饮料换购 题目描述 输入格式 输出格式 输入输出样例 # [蓝桥杯 2023 省 A] 平方差 题目描述 输入格式 输出格式 输入输出样例 说明/提示 【样例说明】 [NOIP2001 普及组] 数的计算 题目描述 输入格式 输出格式 输入输出样例 说明/提示 样例 1 解释 数据…

Halcon tiff 点云读取以及平面矫正

一、读取tiff 图 dev_close_window () dev_open_window (0, 0, 512, 512, black, WindowHandle)xResolution:0.0025 yResolution:0.0025 zResolution:0.001 read_image (IntputImage, C:/Users/alber/Desktop/2023-08-15_16-38-24-982_/Sta5_002.tif) zoom_image_factor (Intpu…

Ext4文件系统解析(二)

1、前言 想要了解EXT文件系统的工作原理&#xff0c;那了解文件系统在磁盘上的分布就是必不可少的。这一节主要介绍EXT文件系统硬盘存储的物理结构。 由于当前主流的CPU架构均采用小端模式&#xff0c;因此下文介绍均已小端模式为准。 2、超级块 2.1 属性 下表列举出超级块…

docker-速通

1.命令-镜像操作 docker pull nginx #下载最新版 docker pull nginx:1.20.1 #下载指定版本 镜像名:版本名&#xff08;标签&#xff09; docker images #查看所有镜像 # 如果只写镜像名实际就是redis redis:latest 记住这个不是命令 docker rmi 镜像名:版本号/镜像id…

Java Throwable

如图展示了 Java 整个异常体系的关系。 Throwable 的 Java 异常体系的基类, 他的直接子类有 Error 和 Exception 2 个。 1 Error Error 表示的是由于系统错误, Java 虚拟机抛出的异常, 例如 Java 虚拟机崩溃, 内存不够等, 这种情况仅凭程序自身是无法处理的, 在程序中也不会…

第十一节HarmonyOS 常用容器组件1-Row与Column

Column&Row组件的使用 1、概述 容器组件是一种比较特殊的组件&#xff0c;它可以包含其他的组件&#xff0c;而且按照一定的规律布局&#xff0c;帮助开发者生成精美的页面。容器组件除了放置基础组件外&#xff0c;也可以放置容器组件&#xff0c;通过多层布局的嵌套&am…

详解Spring工厂是如何获取Aop中的代理对象的

&#x1f609;&#x1f609; 学习交流群&#xff1a; ✅✅1&#xff1a;这是孙哥suns给大家的福利&#xff01; ✨✨2&#xff1a;我们免费分享Netty、Dubbo、k8s、Mybatis、Spring...应用和源码级别的视频资料 &#x1f96d;&#x1f96d;3&#xff1a;QQ群&#xff1a;583783…

如何选择适合的光电传感器与 STM32 微控制器进行接口设计

本文介绍了如何选择适合的光电传感器与 STM32 微控制器进行接口设计的方法。首先我们将介绍一些选择光电传感器的关键因素&#xff0c;包括测量范围、响应时间、分辨率和输出类型。然后我们将介绍如何根据所选传感器的特性进行硬件连接和接口设计。最后&#xff0c;我们将提供示…

区间合并笔记

文章目录 什么是区间合并怎么做区间合并AcWing 803. 区间合并思路解析my - CODEdalao の CODE 什么是区间合并 区间合并是指给定多个区间&#xff0c;让你将重合的区间合并为一个区间 怎么做区间合并 区间合并类问题大多三个办法&#xff1a; 按左端点排序按右端点排序按左右…

计算机组成原理,硬件组成,存储器,控制器,控制器的任务, 运算器,中央处理器CPU,主存

计算机组成原理 课程需求 前导课程&#xff1a; 后继课程 汇编 操作系统 数逻 组成 系统结构 数电 微机原理 课程结构 计算机特性 1 从外部角度来看计算机的特性 快速 通用 准确 逻辑 2从外部特性与内部特性的关系 计算机组成 一 硬件组成 运算器 主要功能是进行算术…