我试图通过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程序,那么&#39; tshark&#39;通过&#39; lsof&#39;命令参数,我得到标准输出就好了。
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。
当我将stdout重定向到文件时,它不会发送计数:
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处理打印数据包计数和信息的另一个线索。
此致 汤姆
答案 0 :(得分:0)
好吧,即使我最终没有使用这种使用tshark的方式,我想我找到了使用这个选项来 popen tshark。在手册页中,选项-l :
打印每个数据包的信息后,刷新标准输出。 (严格来说,如果-V是,那么这不是行缓冲的 规定;但是,如果-V不是,它与行缓冲相同 指定,因为每个数据包只打印一行,并且,如-l所示 通常在将实时捕获传递给程序或脚本时使用,所以 一旦看到数据包,数据包的输出就会显示出来 解剖,它应该像真正的线缓冲一样工作。我们的确是 这是Microsoft Visual C ++ C中缺陷的解决方法 库)。
将TShark的输出传递给另一个时,这可能很有用 程序,因为它意味着输出管道的程序 一旦TShark看到,就会看到数据包的解剖数据 数据包并生成该输出,而不是只在它时才看到它 包含该数据的标准输出缓冲区填满。
我测试了它,它似乎工作。 以防任何人需要它。