static void* packetPollLoop(void* ptr) { PcapInterface *iface = (PcapInterface*)ptr; pcap_t *pd; FILE *pcap_list = iface->get_pcap_list(); /* Wait until the initialization completes */ while(!iface->isRunning()) sleep(1); do { if(pcap_list != NULL) { char path[256], *fname; pcap_t *pcap_handle; while((fname = fgets(path, sizeof(path), pcap_list)) != NULL) { char pcap_error_buffer[PCAP_ERRBUF_SIZE]; int l = (int)strlen(path)-1; if((l <= 1) || (path[0] == '#')) continue; path[l--] = '\0'; /* Remove trailer white spaces */ while((l > 0) && (path[l] == ' ')) path[l--] = '\0'; if((pcap_handle = pcap_open_offline(path, pcap_error_buffer)) == NULL) { ntop->getTrace()->traceEvent(TRACE_ERROR, "Unable to open file '%s': %s", path, pcap_error_buffer); } else { ntop->getTrace()->traceEvent(TRACE_NORMAL, "Reading packes from pcap file %s", path); iface->set_pcap_handle(pcap_handle); break; } } if(fname == NULL) { ntop->getTrace()->traceEvent(TRACE_NORMAL, "No more pcap files to read"); fclose(pcap_list); return(NULL); } else iface->set_datalink(pcap_datalink(pcap_handle)); } pd = iface->get_pcap_handle(); while((pd != NULL) && iface->isRunning() && (!ntop->getGlobals()->isShutdown())) { const u_char *pkt; struct pcap_pkthdr *hdr; int rc; while(iface->idle()) { iface->purgeIdle(time(NULL)); sleep(1); } if((rc = pcap_next_ex(pd, &hdr, &pkt)) > 0) { if((rc > 0) && (pkt != NULL) && (hdr->caplen > 0)) { int a, b; #ifdef WIN32 /* For some unknown reason, on Windows winpcap gets crazy with specific packets and so ntopng crashes. Copying the packet memory onto a local buffer prevents that, as specified in https://github.com/ntop/ntopng/issues/194 */ u_char pkt_copy[1600]; struct pcap_pkthdr hdr_copy; memcpy(&hdr_copy, hdr, sizeof(hdr_copy)); hdr_copy.len = min(hdr->len, sizeof(pkt_copy) - 1); hdr_copy.caplen = min(hdr_copy.len, hdr_copy.caplen); memcpy(pkt_copy, pkt, hdr_copy.len); iface->packet_dissector(&hdr_copy, (const u_char*)pkt_copy, &a, &b); #else hdr->caplen = min_val(hdr->caplen, iface->getMTU()); iface->packet_dissector(hdr, pkt, &a, &b); #endif } } else if(rc < 0) { if(iface->read_from_pcap_dump()) break; } else { /* No packet received before the timeout */ iface->purgeIdle(time(NULL)); } } /* while */ } while(pcap_list != NULL); ntop->getTrace()->traceEvent(TRACE_NORMAL, "Terminated packet polling for %s", iface->get_name()); if(ntop->getPrefs()->shutdownWhenDone()) ntop->getGlobals()->shutdown(); return(NULL); }
static void* packetPollLoop(void* ptr) { PcapInterface *iface = (PcapInterface*)ptr; pcap_t *pd; FILE *pcap_list = iface->get_pcap_list(); /* Wait until the initialization completes */ while(!iface->isRunning()) sleep(1); do { if(pcap_list != NULL) { char path[256], *fname; pcap_t *pcap_handle; while((fname = fgets(path, sizeof(path), pcap_list)) != NULL) { char pcap_error_buffer[PCAP_ERRBUF_SIZE]; int l = (int)strlen(path)-1; if((l <= 1) || (path[0] == '#')) continue; path[l--] = '\0'; /* Remove trailer white spaces */ while((l > 0) && (path[l] == ' ')) path[l--] = '\0'; if((pcap_handle = pcap_open_offline(path, pcap_error_buffer)) == NULL) { ntop->getTrace()->traceEvent(TRACE_ERROR, "Unable to open file '%s': %s", path, pcap_error_buffer); } else { ntop->getTrace()->traceEvent(TRACE_NORMAL, "Reading packes from pcap file %s", path); iface->set_pcap_handle(pcap_handle); break; } } if(fname == NULL) { ntop->getTrace()->traceEvent(TRACE_NORMAL, "No more pcap files to read"); fclose(pcap_list); return(NULL); } else iface->set_datalink(pcap_datalink(pcap_handle)); } pd = iface->get_pcap_handle(); while((pd != NULL) && iface->isRunning() && (!ntop->getGlobals()->isShutdown())) { const u_char *pkt; struct pcap_pkthdr hdr; while(iface->idle()) { iface->purgeIdle(time(NULL)); sleep(1); } if((pkt = pcap_next(pd, &hdr)) != NULL) { if((hdr.caplen > 0) && (hdr.len > 0)) { int a_shaper_id, b_shaper_id; iface->packet_dissector(&hdr, pkt, &a_shaper_id, &b_shaper_id); } } else { if(iface->read_from_pcap_dump()) break; iface->purgeIdle(time(NULL)); } } /* while */ } while(pcap_list != NULL); ntop->getTrace()->traceEvent(TRACE_NORMAL, "Terminated packet polling for %s", iface->get_name()); if(ntop->getPrefs()->shutdownWhenDone()) ntop->getGlobals()->shutdown(); return(NULL); }