gatherer
gatherer

Reputation: 155

pcap_stats and pcap_dump_open dont't work together

i have the following problem. I build a c++ program with two threads. On the parent thread i send some raw ethernet frames and in the child thread all the libpcap stuff is running.

For the output i use ncurses.

Now I have the following problem. I can use only pcap_stats or pcap_dump_open.

When I comment out all the pcap_stats stuff the program runs regular. All packages are captured and saved to a file.

When I comment out all the save to file stuff the program runs regular.

As soon as I use both I get an segmentation fault on pcap_dump_open. Did i missed something?

void *pcapFunction(void * arg)
{
  optionList *oLT = (optionList*) arg;
  pcap_t *descr;                                              /* session descriptor */
  pcap_dumper_t *fdescr;                                      /* save file descriptor */
  struct pcap_stat ps;
  char errbuf[PCAP_ERRBUF_SIZE];                              /* error string */
  char *finalSaveFileName;
  std::string saveFileName = std::string("../pcapSaveFiles/pcapSaveFile");
  std::stringstream out;
  int capturedPackages = 0;
  time_t t;                                                   /* time structur */
  t = time(0);                                                /* get time */

  // i set up pcap the following way
  descr = pcap_create(oLT->get_deviceName(), errbuf);
  if(descr == NULL)
  {
     mvwprintw(oLT->getTopWin(), oLT->get_writeTopRow(), oLT->get_writeTopCol(), "ERROR: device could not be opend");
     oLT->refreshTopScreen();
     exit(1);
  }
  pcap_set_promisc(descr, 0);
  pcap_set_snaplen(descr, BUFSIZ);
  pcap_set_timeout(descr, 1000);
  pcap_setnonblock(descr, 0, errbuf);
  pcap_activate(descr);

  // some file name building stuff
  ...
  saveFileName = out.str();
  fdescr = pcap_dump_open(descr, strcpy(finalSaveFileName, saveFileName.c_str()));

  while (!oLT->get_stopCapture())
  {
    capturedPackages += pcap_dispatch(descr, 1, &pcap_dump, (unsigned char*) fdescr);
    // here is the problem
    pcap_stats(descr, &ps);
    // this should be the output from ps an not 
    mvwprintw(oLT->getBotWin(), 2, (oLT->get_windowCol()-18)/2, "number of captured %d packages", capturedPackages);
oLT->refreshBotScreen();
  }

  //
  pcap_dump_close(fdescr);
  pcap_close(descr);
  pthread_exit(NULL);
}

Upvotes: 0

Views: 577

Answers (1)

user862787
user862787

Reputation:

strcpy() doesn't work the way you think it does.

It does not allocate a buffer large enough to hold the result of the copy; it assumes that the buffer already exists and, if it's too small, it will just overwrite the data past the end of the buffer. You do not appear to be setting the value of finalSaveFileName, which you would have to do before passing it as the first argument to strcpy().

It is also not necessary in this case; the c_str method of a String returns a C string, and you can pass that C string to pcap_dump_open().

If you were not setting the value of finalSaveFileName somewhere in code you didn't show us, then the fact that your program appeared to work, without the call to pcap_stats(), was through pure luck. Perhaps, for example, whatever random value happened to be in the register, or memory location, held the value of finalSaveFileName happened to point to something that, when overwritten by strcpy(), didn't cause an immediate problem, but happened to overlap struct pcap_stat ps, so that if you call pcap_stats(), the string is overwritten, and perhaps no longer has a terminating \0, so that the reference to the string failed.

What you need to do, to open the output file, is

fdescr = pcap_dump_open(descr, saveFileName.c_str());

or, if you need finalSaveFileName to point to a copy of the C-string value of saveFileName, do

finalSaveFileName = strdup(saveFileName.c_str());
fdescr = pcap_dump_open(descr, finalSaveFileName);

Upvotes: 1

Related Questions