使用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
相关产品推荐
相关产品推荐

