用C语言中的popen捕获tshark标准输出

用C语言中的popen捕获tshark标准输出,c,pipe,stdout,popen,tshark,C,Pipe,Stdout,Popen,Tshark,我试图通过一个C语言的程序从tshark获取标准输出。 为此,我使用popen调用打开tshark进程并读取返回的文件流 代码示例: #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_

我试图通过一个C语言的程序从tshark获取标准输出。 为此,我使用popen调用打开tshark进程并读取返回的文件流

代码示例:

#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;
}
但是如果我在C程序中用lsof改变'tshark'命令参数,我就可以得到标准输出

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处理打印包计数和信息的方式不同的另一个线索

问候,,
Tom

好吧,即使我最终没有使用这种与tshark合作的方式,我想我还是找到了使用它的选项,以便popen tshark。从手册页面的选项-l:

打印每个数据包的信息后刷新标准输出。严格地说,如果-V为 明确规定;但是,如果不使用-V,则它与缓存线相同 指定,因为每个数据包只打印一行,并且 通常在将实时捕获传输到程序或脚本时使用,因此 数据包的输出会在看到数据包后立即显示,并且 仔细分析,它应该和真正的行缓冲一样有效。是的 这是微软Visual C++中的一个缺陷。 图书馆

这在将TShark的输出管道连接到另一个时可能很有用 程序,因为它意味着输出通过管道传输到的程序 TShark一看到数据包,就会看到数据包的解析数据 并生成该输出,而不是仅在 包含该数据的标准输出缓冲区已满

我测试了它,它似乎有效。
以防万一有人需要它。

你为什么想要popen tshark?捕获实际数据并离线分析,或者使用libpcap或其他方法不是更好吗?这似乎有点奇怪。您知道,这是出现在一个规范文档中的先决条件。如果不可能这样做,我想我必须弄清楚。先决条件是什么?我的意思是所有这些的输出都必须去某个地方,我很好奇这是为了什么。好奇害死了猫。。。某处是指通过rsyslogd配置的远程机器。虽然我开始认为这条路对我来说毫无意义……好吧,所以你尝试使用tshark捕获一些网络流量,并将其发送到syslog。与所有这些不同的是,也许您可以将以太网交换机配置为进行端口镜像,并将实际数据发送到目标计算机并在那里进行处理。只是个主意。
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