У меня есть следующая проблема. Я строю программу на C ++ с двумя потоками.
В родительском потоке я отправляю несколько необработанных кадров Ethernet, а в дочернем потоке все содержимое 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);
}
strcpy()
не работает так, как вы думаете.
Оно делает не выделить достаточно большой буфер для хранения результата копии; это предполагает, что буфер уже существует и, если он слишком мал, он просто перезапишет данные после конца буфера. Вы, кажется, не устанавливаете значение finalSaveFileName
который вы бы иметь сделать, прежде чем передать его в качестве первого аргумента strcpy()
,
Это также не необходимо в этом случае; c_str
Метод String возвращает строку C, и вы можете передать эту строку C pcap_dump_open()
,
Если вы не устанавливали значение finalSaveFileName
где-то в коде, который вы не показывали нам, то тот факт, что ваша программа работала без вызова pcap_stats()
Удачи. Возможно, например, какое бы случайное значение не было в регистре или ячейке памяти, оно содержало значение finalSaveFileName
случилось, чтобы указать на то, что, когда перезаписано strcpy()
, не вызвало немедленной проблемы, но произошло совпадение struct pcap_stat ps
, так что если вы позвоните pcap_stats()
, строка перезаписывается и, возможно, больше не имеет завершающего \0
, так что ссылка на строку не удалась.
Что нужно сделать, чтобы открыть выходной файл, это
fdescr = pcap_dump_open(descr, saveFileName.c_str());
или, если вам нужно finalSaveFileName
указать на копию значения C-строки saveFileName
, делать
finalSaveFileName = strdup(saveFileName.c_str());
fdescr = pcap_dump_open(descr, finalSaveFileName);
Других решений пока нет …