Пакетный нюхает с pcap Ошибка сегментации - PullRequest
0 голосов
/ 28 января 2020

Я пытаюсь написать программу перехвата пакетов в C, и у меня возникает ошибка сегментации, когда я пытаюсь запустить программу после успешной компиляции. Я попытался определить точную строку кода, которая вызывает ошибку программы, закомментировав часть кода и перекомпилировав программу, а затем повторно запустив уменьшенную версию моей программы. Вот мой код.

void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet)
{
   printf("Got a packet\n");
}

int main()
{
  pcap_t *handle;
  char errbuf[PCAP_ERRBUF_SIZE];
  struct bpf_program fp;
  char filter_exp[] = "ip proto icmp";
  bpf_u_int32 net;

  // Step 1: Open live pcap session on NIC with name eth3
  handle = pcap_open_live("eth3", BUFSIZ, 1, 1000, errbuf); 

  // Step 2: Compile filter_exp into BPF psuedo-code
  pcap_compile(handle, &fp, filter_exp, 0, net);      
  pcap_setfilter(handle, &fp);                             

  // Step 3: Capture packets
  pcap_loop(handle, -1, got_packet, NULL);                

  pcap_close(handle);   //Close the handle 
  return 0;
}

Закомментировав код, перекомпилировав программу и перезапустив программу, я обнаружил, что segfault происходит в строке pcap_compile:

pcap_compile(handle, &fp, filter_exp, 0, net);

Когда я компилирую и запускаю программу со всем после того, как строка handle (Шаг 1) закомментирована, программа запускается без сегментации и ничего не происходит. Как только я включу оператор pcap_compile, сделав его активным в программе, программа перестанет работать. Кто-нибудь знает, в чем может быть проблема, будь то вызов pcap_compile или что-то еще?

1 Ответ

2 голосов
/ 30 января 2020

Steffen Ullrich здесь на 100% правильный.

Если вы собираетесь вызывать любую подпрограмму, которая возвращает pcap_t *, например, pcap_open_live(), вы должны проверить, чтобы убедиться, что она успешна, проверив возвращает ли он нулевой указатель или нет:

handle = pcap_open_live("eth3", BUFSIZ, 1, 1000, errbuf); 
if (handle != NULL) {
    fprintf(stderr, "Can't open eth3: %s\n", errbuf);
    exit(1);
}

Если произойдет сбой и вернется нулевой указатель, то pcap_compile() - и другие процедуры libpcap - обработают sh, если вы передадите ему нулевой указатель в качестве первого аргумента.

Если вы закомментируете вызов pcap_open_live(), то handle не имеет значения, поэтому он содержит неизвестное значение. Если , то это значение случается , указывающее на место в памяти, такое, что , если pcap_compile(), pcap_setfilter() и pcap_loop() не происходит с sh, , затем будет выглядеть так, как если бы программа работала - но это не так.

Так что вы должны проверить, успешно ли pcap_open_live(), как в Пример выше - и . Вы должны проверить, также успешны ли pcap_compile(), pcap_setfilter() и pcap_loop().

...