diff --git a/server/params.cpp b/server/params.cpp index 11541cb..2337bc3 100644 --- a/server/params.cpp +++ b/server/params.cpp @@ -18,6 +18,7 @@ along with this program. If not, see */ #include "params.h" +#include "pcapextra.h" #include @@ -46,6 +47,11 @@ int Params::parseCommandLine(int argc, char* argv[]) break; case 'v': printf("Ostinato Drone %s rev %s\n", version, revision); + printf("PCAP Lib: %s\n", pcap_lib_version()); +#ifdef Q_OS_WIN32 + printf("Service npf status %s\n", pcapServiceStatus(L"npf")); + printf("Service npcap status %s\n", pcapServiceStatus(L"npcap")); +#endif exit(0); case 'h': default: diff --git a/server/pcapextra.cpp b/server/pcapextra.cpp index 4acbda9..fc459a2 100644 --- a/server/pcapextra.cpp +++ b/server/pcapextra.cpp @@ -24,7 +24,66 @@ along with this program. If not, see /* NOTE: All code borrowed from WinPcap */ -#ifndef Q_OS_WIN32 +#ifdef Q_OS_WIN32 + +const char* pcapServiceStatus(const wchar_t* name) +{ + SC_HANDLE scm, svc; + SERVICE_STATUS_PROCESS svcStatus; + DWORD size; + BOOL result; + const char *status = "unknown"; + + scm = OpenSCManager(nullptr, nullptr, SC_MANAGER_ENUMERATE_SERVICE); + if(!scm) + goto _exit; + + svc = OpenService(scm, name, SERVICE_QUERY_STATUS); + if(!svc) + goto _close_exit; + + result = QueryServiceStatusEx(svc, SC_STATUS_PROCESS_INFO, + reinterpret_cast(&svcStatus), sizeof(svcStatus), + &size); + + if(result == 0) + goto _close_exit; + + switch(svcStatus.dwCurrentState) { + case SERVICE_CONTINUE_PENDING: + status = "continue pending"; + break; + case SERVICE_PAUSE_PENDING: + status = "pause pending"; + break; + case SERVICE_PAUSED: + status = "paused"; + break; + case SERVICE_RUNNING: + status = "running"; + break; + case SERVICE_START_PENDING: + status = "start pending"; + break; + case SERVICE_STOP_PENDING: + status = "stop pending"; + break; + case SERVICE_STOPPED: + status = "stopped"; + break; + } + +_close_exit: + if (svc) + CloseServiceHandle(svc); + if (scm) + CloseServiceHandle(scm); +_exit: + return status; +} + +#else // non-Windows + pcap_send_queue* pcap_sendqueue_alloc (u_int memsize) { pcap_send_queue *tqueue; diff --git a/server/pcapextra.h b/server/pcapextra.h index 415fe3e..6d6168e 100644 --- a/server/pcapextra.h +++ b/server/pcapextra.h @@ -23,7 +23,11 @@ along with this program. If not, see #include #include -#ifndef Q_OS_WIN32 +#ifdef Q_OS_WIN32 + +const char* pcapServiceStatus(const wchar_t *name); + +#else // non-windows #define PCAP_OPENFLAG_PROMISCUOUS 1 diff --git a/server/pcapport.cpp b/server/pcapport.cpp index fbb9c84..136813a 100644 --- a/server/pcapport.cpp +++ b/server/pcapport.cpp @@ -342,7 +342,8 @@ void PcapPort::PortMonitor::run() void PcapPort::PortMonitor::stop() { stop_ = true; - pcap_breakloop(handle()); + if (handle()) + pcap_breakloop(handle()); } /* @@ -404,6 +405,11 @@ _retry: } dumpHandle_ = pcap_dump_open(handle_, qPrintable(capFile_.fileName())); + if (!dumpHandle_) { + qDebug("failed to start capture: %s", pcap_geterr(handle_)); + goto _exit; + } + PcapSession::preRun(); state_ = kRunning; while (1) diff --git a/server/portmanager.cpp b/server/portmanager.cpp index cca4e90..0ca37de 100644 --- a/server/portmanager.cpp +++ b/server/portmanager.cpp @@ -51,6 +51,11 @@ PortManager::PortManager() AbstractPort::Accuracy txRateAccuracy; qDebug("PCAP Lib: %s", pcap_lib_version()); +#ifdef Q_OS_WIN32 + qDebug("Service npf status %s\n", pcapServiceStatus(L"npf")); + qDebug("Service npcap status %s\n", pcapServiceStatus(L"npcap")); +#endif + qDebug("Retrieving the device list from the local machine\n"); #if defined(Q_OS_WIN32) diff --git a/server/winpcapport.cpp b/server/winpcapport.cpp index 1f3b2b3..39ade84 100644 --- a/server/winpcapport.cpp +++ b/server/winpcapport.cpp @@ -26,10 +26,10 @@ along with this program. If not, see #ifdef Q_OS_WIN32 +#include #include PIP_ADAPTER_ADDRESSES WinPcapPort::adapterList_ = NULL; -const uint OID_GEN_MEDIA_CONNECT_STATUS = 0x00010114; WinPcapPort::WinPcapPort(int id, const char *device, const char *description) : PcapPort(id, device) @@ -53,7 +53,7 @@ WinPcapPort::WinPcapPort(int id, const char *device, const char *description) if (!adapter_) qFatal("Unable to open adapter %s", device); linkStateOid_ = (PPACKET_OID_DATA) malloc(sizeof(PACKET_OID_DATA) + - sizeof(uint)); + sizeof(NDIS_LINK_STATE)); if (!linkStateOid_) qFatal("failed to alloc oidData"); @@ -67,27 +67,39 @@ WinPcapPort::~WinPcapPort() OstProto::LinkState WinPcapPort::linkState() { - memset(linkStateOid_, 0, sizeof(PACKET_OID_DATA) + sizeof(uint)); + memset(linkStateOid_, 0, sizeof(PACKET_OID_DATA) + sizeof(NDIS_LINK_STATE)); - linkStateOid_->Oid = OID_GEN_MEDIA_CONNECT_STATUS; - linkStateOid_->Length = sizeof(uint); + linkStateOid_->Oid = OID_GEN_LINK_STATE; + linkStateOid_->Length = sizeof(NDIS_LINK_STATE); + // TODO: migrate to the npcap-only pcap_oid_get_request() when Ostinato + // stops supporting WinPcap if (PacketRequest(adapter_, 0, linkStateOid_)) { uint state; - if (linkStateOid_->Length == sizeof(state)) + if (linkStateOid_->Length == sizeof(NDIS_LINK_STATE)) { - memcpy((void*)&state, (void*)linkStateOid_->Data, - linkStateOid_->Length); + memcpy((void*)&state, + (void*)(linkStateOid_->Data+sizeof(NDIS_OBJECT_HEADER)), + sizeof(state)); + //qDebug("%s: state = %d", data_.description().c_str(), state); if (state == 0) - linkState_ = OstProto::LinkStateUp; + linkState_ = OstProto::LinkStateUnknown; else if (state == 1) + linkState_ = OstProto::LinkStateUp; + else if (state == 2) linkState_ = OstProto::LinkStateDown; } + else { + //qDebug("%s: link state fail", data_.description().c_str()); + } + } + else { + //qDebug("%s: link state request fail", data_.description().c_str()); } - return linkState_; + return linkState_; } bool WinPcapPort::hasExclusiveControl()