Search code examples
c++windowsvisual-studiowiresharktshark

How to call tshark to convert a capture file to txt with CreateProcess


I am trying to call tshark from a c++ program compiled with Visual Studio. Some calls work but others do not. I am able to initiate capture to file:

STARTUPINFO startupInfo={sizeof(startupInfo)};
PROCESS_INFORMATION processInfo;
const char * args = " -i \"Ethernet 9\" -w C:\\Users\\raymond\\Documents\\Debug\\Ethernet_9.cap -b duration:90 -b files:2\"";

CreateProcess("C:\\Program Files\\Wireshark\\tshark.exe", const_cast<char *>(ss.str().c_str()), NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startupInfo, &processInfo);

But i am unable to convert the capture file to text:

STARTUPINFO startupInfo={sizeof(startupInfo)};
PROCESS_INFORMATION processInfo;
const char * args = " -i - < \"C:\\Users\\raymond\\Documents\\Ethernet_9.cap\" > \"C:\\Users\\raymond\\Documents\\Ethernet_9.txt";

CreateProcess("C:\\Program Files\\Wireshark\\tshark.exe", const_cast<char *>(ss.str().c_str()), NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startupInfo, &processInfo);

All that is printed is "Capturing on 'Standard input'", but contrary to running the command on the command line, nothing is output and the number of processed packets is never printed.

Trying something similar with system() also has strange behavior on the same tshark call.

If I try to close the new widow while the program is still running, this is printed: (tshark.exe:8628): CaptureChild-WARNING **: sync_pipe_stop: forcing child to exit


Solution

  • You're using the wrong flag. -i - captures on standard input, where -i captures on an interface. To read from a file, use -r <file> like so:

    const char * args = " -r <src file> > <dest file>";
    

    I highly recommend checking out tshark's manpage.

    Full Example

    In this example, we create a 3 packet capture, use tshark to create a summary file, and print the results. This should be as cross-platform as tshark and > are (Windows, Linux, Macos, BSD, etc.).

    // example.cpp
    #include <iostream>
    #include <fstream>
    
    int main() {
        system("tshark -w source.pcap -c 3");
        system("tshark -r source.pcap > dest.txt");
    
        std::ifstream dest;
        dest.open("dest.txt");
        std::cout << dest.rdbuf();
        dest.close();
    
        return 0;
    }
    

    After compiling, we can see both tshark feedback and the first couple packets.

    rj$ ./example.o
    Capturing on 'Wi-Fi: en0'
    3
        1   0.000000 172.31.99.198 → resolver1.opendns.com DNS  80 Standard...     
        2   0.000026 172.31.99.198 → 217.221.186.35.bc.googleusercontent.co...
        3   0.000026 172.31.99.198 → ec2-3-231-46-251.compute-1.amazonaws.c...