You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Libnids进行TCP重组时Payload损坏问题求助

问题:Libnids TCP重组后Payload打印乱码

我尝试使用Libnids库实现TCP重组,希望验证打印的Payload与Wireshark中的内容是否一致,但运行以下代码后,打印的Payload出现损坏:

#include <stdio.h>
#include <nids.h>

void tcp_callback(struct tcp_stream *tcp, void **arg) {
    if (tcp->nids_state == NIDS_JUST_EST) {
        printf("Connection established\n");
        tcp->server.collect++; // 仅收集服务器端数据
    } else if (tcp->nids_state == NIDS_DATA) {
        printf("Packet Payload: %.*s\n", tcp->server.count, tcp->server.data);
    }
}

int main() {
    nids_params.device = "wlo1";
    nids_params.pcap_filter = "host 174.143.201.208";

    if (!nids_init()) {
        fprintf(stderr, "nids_init() failed\n");
        return -1;
    }

    nids_register_tcp(tcp_callback);
    nids_run();

    return 0;
}

打印结果显示大量乱码字符:

Packet Payload: yω!
                   nT$ܫO�Q�F�:��V
� k=��                           g����.�ۅb|}퓈LOy�(�vr��8�S[@���p���CC
�P����у+3rj����7�,��t�+��,YH+�y�b�z���󪎎�}vx�%�xb��K6��^�����F�,��(���)d����r
r.�Y`��@*e.���s��V���ho1�c?V_P����C��'ɯ�/�wt�v��

与Wireshark对比后发现,仅部分非乱码字符正确。我猜测问题可能源于Libnids中Payload以Char指针类型存储,但不确定是否正确。请问该问题的原因是什么?如何获取原始Payload?


问题原因

  • 文本格式打印不兼容二进制数据:%.*s是字符串打印格式符,TCP Payload常包含二进制数据(如空字节、非ASCII控制字符),%s会在遇到第一个空字节时终止打印,且终端无法解析的字节会显示为乱码,导致内容失真。
  • 仅收集单方向数据:代码中只开启了tcp->server.collect++,如果目标主机是发起请求的客户端,会漏掉客户端发送的Payload;同时回调只处理服务器端数据,无法获取完整的双向TCP流内容。
  • 终端编码限制:终端默认使用UTF-8等字符编码,无法解析二进制数据中的特殊字节,会将其显示为乱码符号。

解决方法

1. 以十六进制格式打印原始Payload

十六进制格式能准确展示每个字节的原始值,可直接与Wireshark的十六进制视图对比:

void tcp_callback(struct tcp_stream *tcp, void **arg) {
    if (tcp->nids_state == NIDS_JUST_EST) {
        printf("Connection established\n");
        tcp->server.collect++;
        tcp->client.collect++; // 同时收集双向数据
    } else if (tcp->nids_state == NIDS_DATA) {
        // 打印服务器端Payload(十六进制)
        if (tcp->server.count > 0) {
            printf("Server Payload (hex): ");
            for (int i = 0; i < tcp->server.count; i++) {
                printf("%02x ", (unsigned char)tcp->server.data[i]);
            }
            printf("\n");
        }
        // 打印客户端Payload(十六进制)
        if (tcp->client.count > 0) {
            printf("Client Payload (hex): ");
            for (int i = 0; i < tcp->client.count; i++) {
                printf("%02x ", (unsigned char)tcp->client.data[i]);
            }
            printf("\n");
        }
    }
}

2. 过滤可打印字符查看

如果需要查看文本内容,可过滤出ASCII可打印字符(0x20-0x7E),其余用.代替:

else if (tcp->nids_state == NIDS_DATA) {
    if (tcp->server.count > 0) {
        printf("Server Payload (printable): ");
        for (int i = 0; i < tcp->server.count; i++) {
            unsigned char c = tcp->server.data[i];
            printf("%c", (c >= 0x20 && c <= 0x7E) ? c : '.');
        }
        printf("\n");
    }
}

3. 确保收集双向TCP流数据

在连接建立时,同时开启客户端和服务器端的数据收集,避免遗漏任一方向的Payload:

if (tcp->nids_state == NIDS_JUST_EST) {
    printf("Connection established\n");
    tcp->server.collect++;
    tcp->client.collect++;
}

内容的提问来源于stack exchange,提问作者Radwa Ahmed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 23:59:53