Capturing tshark standard output with popen in C

自古美人都是妖i 提交于 2019-12-25 06:48:16

问题


I'm trying to capture the standard output from tshark through a program in C. For that, I use popen() call to open tshark process and read from the returned FILE stream.

Code sample:

#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;
}

When I run it, I get only the packet number count, i.e., I get no packet fields info, just the count of packets, with each number overriding the previous in the same place (no lines scroll happening).

Something like this, I guess for 4 packets:

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 

But if I change in the C program the 'tshark' command argument by 'lsof', I get the standard output just fine.

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
...

With this result, I'm assuming that there is something special with the way tshark sends the info to the standard output. Does anyone know about this behaviour? I'm gonna check tshark source code, to see if it can clarify it.

Just a final note.

When I run tshark through the shell, I often get missing packet numbers like:

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

Missing printed packet numbers 8, 10, 12, 14.

And when I redirect stdout to file, it does not send the count numbers:

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

Another clue that tshark is handling printed packet count and info differently.

Regards, Tom


回答1:


Well, even if I finally don't use this way of working with tshark, I think I found the option to use in order to popen tshark. From the manual page, option -l:

Flush the standard output after the information for each packet is printed. (This is not, strictly speaking, line-buffered if -V was specified; however, it is the same as line-buffered if -V wasn't specified, as only one line is printed for each packet, and, as -l is normally used when piping a live capture to a program or script, so that output for a packet shows up as soon as the packet is seen and dissected, it should work just as well as true line-buffering. We do this as a workaround for a deficiency in the Microsoft Visual C++ C library.)

This may be useful when piping the output of TShark to another program, as it means that the program to which the output is piped will see the dissected data for a packet as soon as TShark sees the packet and generates that output, rather than seeing it only when the standard output buffer containing that data fills up.

I tested it, and it seems to work. Just in case anyone needs it.



来源:https://stackoverflow.com/questions/26177333/capturing-tshark-standard-output-with-popen-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!