From d017d267959de46a2dcaeafee41b3a14a55bc5e7 Mon Sep 17 00:00:00 2001 From: Paul Hollinsky Date: Mon, 6 May 2019 16:54:18 -0400 Subject: [PATCH] POSIX PCAP: Speed improvements --- platform/posix/pcap.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/platform/posix/pcap.cpp b/platform/posix/pcap.cpp index 5933161..eeea6ba 100644 --- a/platform/posix/pcap.cpp +++ b/platform/posix/pcap.cpp @@ -24,7 +24,7 @@ std::vector PCAP::FindAll() { char errbuf[PCAP_ERRBUF_SIZE] = { 0 }; bool success = false; // Calling pcap_findalldevs too quickly can cause various errors. Retry a few times in this case. - for(auto retry = 0; retry < 10; retry++) { + for(auto retry = 0; retry < 3; retry++) { auto ret = pcap_findalldevs(&alldevs, errbuf); if(ret == 0) { success = true; @@ -81,20 +81,27 @@ std::vector PCAP::FindAll() { auto& interface = knownInterfaces[i]; errbuf[0] = '\0'; - interface.fp = pcap_open_live(interface.nameFromPCAP.c_str(), UINT16_MAX, 1, 0, errbuf); + interface.fp = pcap_create(interface.nameFromPCAP.c_str(), errbuf); if(interface.fp == nullptr) { // TODO Flag error that interface could not be opened? // This can happen if, on Linux, you are not running as root continue; } + pcap_set_snaplen(interface.fp, UINT16_MAX); + pcap_set_timeout(interface.fp, 1); + pcap_set_immediate_mode(interface.fp, 1); + pcap_setnonblock(interface.fp, 1, errbuf); + if(pcap_activate(interface.fp)) { + // TODO Flag error that interface could not be opened? + // This can happen if, on Linux, you are not running as root + continue; + } // TODO Propagate this up // if(strlen(errbuf) != 0) { // The open succeeded but we got a warning // std::cout << "Warning for " << interface.nameFromPCAP << " " << errbuf << std::endl; // } - pcap_setnonblock(interface.fp, 1, errbuf); - EthernetPacket requestPacket; requestPacket.payload.reserve(4); requestPacket.payload = { @@ -107,7 +114,7 @@ std::vector PCAP::FindAll() { auto bs = requestPacket.getBytestream(); pcap_sendpacket(interface.fp, bs.data(), (int)bs.size()); - auto timeout = std::chrono::high_resolution_clock::now() + std::chrono::milliseconds(50); + auto timeout = std::chrono::high_resolution_clock::now() + std::chrono::milliseconds(5); while(std::chrono::high_resolution_clock::now() <= timeout) { // Wait up to 5ms for the response struct pcap_pkthdr* header; const uint8_t* data; @@ -157,7 +164,6 @@ std::vector PCAP::FindAll() { pcap_close(interface.fp); interface.fp = nullptr; } - return foundDevices; }