【发布时间】:2014-11-28 10:00:06
【问题描述】:
我正在尝试通过 C 中的程序从 tshark 捕获标准输出。 为此,我使用 popen() 调用打开 tshark 进程并从返回的 FILE 流中读取。
代码示例:
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE* pipe_fd = popen("tshark -i eth0 -R icmp -2 -T fields -e icmp.checksum -e icmp.seq", "r");
//FILE* pipe_fd = popen("lsof", "r");
if (!pipe_fd) {
fprintf(stderr, "popen failed.\n");
return EXIT_FAILURE;
}
char buffer[2048];
while (NULL != fgets(buffer, sizeof(buffer), pipe_fd)) {
fprintf(stdout, "SO: %s", buffer);
}
pclose(pipe_fd);
printf("tdr FINISHED!\n");
return 0;
}
当我运行它时,我只得到数据包编号计数,即,我没有得到数据包字段信息,只有数据包计数,每个数字在同一个地方覆盖前面的数字(没有行滚动发生)。
像这样,我猜是 4 个数据包:
tomas@ubuntu64:~$ sudo ./main
tshark: Lua: Error during loading:
[string "/usr/share/wireshark/init.lua"]:46: dofile has been disabled due to running Wireshark as superuser. See http://wiki.wireshark.org/CaptureSetup/CapturePrivileges for help in running Wireshark as an unprivileged user.
Running as user "root" and group "root". This could be dangerous.
Capturing on 'eth0'
4
但是,如果我在 C 程序中将“tshark”命令参数更改为“lsof”,则可以得到标准输出。
tomas@ubuntu64:~$ sudo ./main
lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs
Output information may be incomplete.
SO: COMMAND PID TID USER FD TYPE DEVICE SIZE/OFF NODE NAME
SO: init 1 root cwd DIR 8,1 4096 2 /
SO: init 1 root rtd DIR 8,1 4096 2 /
SO: init 1 root txt REG 8,1 265848 791529 /sbin/init
SO: init 1 root mem REG 8,1 47712 824514 /lib/x86_64-linux-gnu/libnss_files-2.19.so
...
有了这个结果,我假设 tshark 将信息发送到标准输出的方式有些特殊。有人知道这种行为吗? 我去查一下tshark源码,看看能不能说清楚。
最后一点。
当我通过 shell 运行 tshark 时,我经常会丢失数据包编号,例如:
tomas@ubuntu64:~$ sudo tshark -i eth0 -R icmp -2 -T fields -e icmp.checksum -e icmp.seq
tshark: Lua: Error during loading:
[string "/usr/share/wireshark/init.lua"]:46: dofile has been disabled due to running Wireshark as superuser. See http://wiki.wireshark.org/CaptureSetup/CapturePrivileges for help in running Wireshark as an unprivileged user.
Running as user "root" and group "root". This could be dangerous.
Capturing on 'eth0'
0x0ee5 63045
1 0x8ae3 63046
2 0xcfdf 63047
3 0xe4d9 63048
4 0x9db7 63049
5 0x6798 63050
6 0x0175 63051
7 0x9e54 63052
0xa654 63052
9 0xe050 63053
0xe850 63053
11 0x8389 63054
0x8b89 63054
13 0x9b81 63055
0xa381 63055
缺少打印的数据包编号 8、10、12、14。
当我将标准输出重定向到文件时,它不会发送计数:
tomas@ubuntu64:~$ sudo tshark -i eth0 -R icmp -2 -T fields -e icmp.checksum -e icmp.seq > kk
tomas@ubuntu64:~$ cat kk
0x2073 63321
0x2873 63321
0x7c6a 63322
另一个线索表明 tshark 以不同方式处理打印的数据包计数和信息。
问候, 汤姆
【问题讨论】:
-
为什么要popen tshark?捕获实际数据并离线分析,或者使用 libpcap 之类的不是更好吗?这似乎有点奇怪。
-
你知道,这是出现在一份规范文档中的先决条件。如果不能那样做,我想我必须弄清楚。
-
先决条件是什么?我的意思是,这一切的输出必须去某处,我很好奇它的用途。
-
好奇心害死猫... Somewhere 是通过 rsyslogd 配置的远程机器。虽然我开始认为这条路让我无处可去...
-
好的,所以您正在尝试使用 tshark 捕获(发送到文本)一些网络流量,并将其发送到 syslog。而不是所有这些,也许您可以只配置您的以太网交换机来进行端口镜像并将实际数据发送到目标机器并在那里处理它。只是一个想法。
标签: c pipe stdout popen tshark