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()