0

次の問題があります。2 つのスレッドで C++ プログラムを作成します。親スレッドでは生のイーサネット フレームをいくつか送信し、子スレッドではすべての libpcap が実行されています。

出力には ncurses を使用します。

今、私は次の問題を抱えています。pcap_stats または pcap_dump_open しか使用できません。

すべての pcap_stats をコメントアウトすると、プログラムは定期的に実行されます。すべてのパッケージがキャプチャされ、ファイルに保存されます。

ファイルへの保存をすべてコメントアウトすると、プログラムは通常どおり実行されます。

両方を使用するとすぐに、pcap_dump_open でセグメンテーション違反が発生します。私は何かを逃しましたか?

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);
}
4

1 に答える 1

1

strcpy()あなたが思うようには機能しません。

コピーの結果を保持するのに十分な大きさのバッファーを割り当てません。バッファーが既に存在すると想定し、小さすぎる場合は、バッファーの末尾を過ぎたデータを上書きするだけです。の値を設定しているようには見えませんこれは、最初の引数として に渡す前に行うfinalSaveFileName必要があります。strcpy()

この場合も必要ありません。Stringのc_strメソッドは C 文字列を返し、その C 文字列を に渡すことができますpcap_dump_open()

finalSaveFileName表示されていないコードのどこかにの値を設定していなかった場合、 を呼び出さなくてもプログラムが動作しているように見えたのpcap_stats()は、まったくの幸運によるものです。おそらく、たとえば、レジ​​スタまたはメモリの場所にたまたまあったランダムな値は、によって上書きされたときに、すぐに問題を引き起こさなかったがたまたまオーバーラップfinalSaveFileNameした何かを指していたの値を保持していたので、を呼び出すと、文字列が上書きされ、おそらく終端の がなくなったため、文字列への参照が失敗しました。strcpy()struct pcap_stat pspcap_stats()\0

出力ファイルを開くために必要なことは、

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

finalSaveFileNameまたは、の C 文字列値のコピーを指す必要がある場合はsaveFileName、次のようにします。

finalSaveFileName = strdup(saveFileName.c_str());
fdescr = pcap_dump_open(descr, finalSaveFileName);
于 2013-02-23T23:02:58.920 に答える