3
votes

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

2
Can you use boost process or you need raw windows API without any wrappers on top ? You actually need to pipe "child process" output, open a file stream and write result into file.Victor Gubin

2 Answers

1
votes

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

You can't use the redirection operations with CreateProcess - the redirections are handled by the command processor cmd.exe which is bypassed when you use CreateProcess.

You may want to simply use the system command from C, which uses the system shell (cmd.exe on Windows):

system("C:\\Program Files\\Wireshark\\tshark.exe -r \"C:\\Users\\raymond\\Documents\\Ethernet_9.cap\" > \"C:\\Users\\raymond\\Documents\\Ethernet_9.txt\"");

As @RossJacobs also mentions, you need to use -r instead of -i to read from a file.