Udpcap ist eine reine Empfangs-UDP-Socket-Emulation basierend auf Npcap. Es nutzt den Npcap-Paketerfassungstreiber, um den Ethernet-Verkehr zu erfassen, alle erforderlichen Header zu analysieren und die UDP-Nutzlast zurückzugeben. Mit Udpcap können Sie einen UDP-Socket öffnen und Daten empfangen, ohne tatsächlich einen Socket zu öffnen!
Das Projekt ist nur für Windows gedacht, da Npcap auch nur auf Windows abzielt.
Udpcap kann :
Udpcap kann nicht :
Alle Abhängigkeiten werden bequem von CMake abgerufen. Um Udpcap tatsächlich nutzen zu können, muss jedoch der Npcap-Treiber installiert sein. Beachten Sie, dass die Npcap-Lizenz proprietär ist.
Die Verwendung eines Paketerfassungstreibers zum Emulieren eines UDP-Sockets klingt nach einer schrecklichen Idee, wenn Sie einfach einen richtigen UDP-Socket verwenden könnten? Nun ja, das ist es wahrscheinlich. Aber Moment, es gibt ein ganz bestimmtes Windows-Problem, das dieses Projekt umgehen kann.
Im Vergleich zu Windows 7 verfügt Windows 10 über einen aggressiveren Windows Defender (den MpsSvc-Dienst). Beim Empfang vieler UDP-Multicast- Pakete mit einem regulären Socket unter Windows 10 verursacht der Windows Defender eine enorme CPU-Last, wodurch das gesamte System verzögert wird. Das Problem scheint noch schlimmer zu sein, wenn der Windows-Rechner mit einer Windows-Domäne verbunden ist, wie es normalerweise in großen Unternehmensnetzwerken der Fall ist. Wenn man das System mit Process Hacker untersucht, kann man erkennen, dass der System
(der Windows-Kernel) so viel wie einen gesamten CPU-Kern belegt. Es ist immer ein Thread im Kernel, der alle CPU-Zyklen verbraucht und tcpip.sys
in seinem Aufrufstapel hat:
Die Defender Firewall kann in Windows 10 nicht mehr deaktiviert werden. Der MpsSvc-Dienst läuft auch bei vorübergehender Deaktivierung weiter, da er neben der Defender Firewall weitere Sicherheitsfunktionen bietet.
Unter Windows verwendet jeder (vom Benutzerbereich initiierte) Netzwerkzugriff die Winsocks/2-API. Diese API verwendet den Kernel-Mode-Dateisystemtreiber Afd.sys
, der dann den Transport Protocol Driver tcpip.sys
verwendet. Der Treiber tcpip.sys ist der Ort, an dem die gesamte Protokollmagie in Windows stattfindet. An dieser Stelle analysiert auch die Windows Defender Firewall den Datenverkehr. Microsoft hat nur zu diesem Zweck eine vollständige API erstellt: die Windows Filtering Platform (WFP). Diese API ist in Windows Vista und höher verfügbar. Unter tcpip.sys
befinden sich nur die NDIS.sys
(Network Driver Interface Specification) und die eigentlichen Ethernet-NIC-Treiber. Um das CPU-Lastproblem der Defender Firewall zu umgehen, müssen wir den gesamten tcpip.sys
-Treiber und alles darüber umgehen. Sehen Sie sich das Bild unten (schwarze Linien) an, um einen Überblick zu erhalten. Bei Verwendung von Npcap sieht der Windows Defender keine offenen Sockets und analysiert den Datenverkehr nicht. Dies bedeutet jedoch, dass der UDP-Protokollstapel im Benutzerbereich neu implementiert werden muss (hier kommt Udpcap zum Einsatz!) .
Udpcap verfügt über eine sehr einfache API mit starken Ähnlichkeiten zu anderen bekannten Socket-APIs:
# include < iostream >
# include < udpcap/udpcap_socket.h >
int main ()
{
// Create a Udpcap socket and bind it to a port. For this example we want to
// receive data from any local or remote source and therefore not bind to an
// IP address.
Udpcap::UdpcapSocket socket;
socket. bind ( Udpcap::HostAddress::Any (), 14000 );
for (;;)
{
// Allocate a buffer for the received datagram. The size of the buffer
// should be large enough to hold the largest possible datagram.
std::vector< char > datagram ( 65535 );
// Create an error code object to hold the error code if an error occurs.
Udpcap::Error error = Udpcap::Error::OK;
// Receive a datagram from the Socket. This is a blocking
// operation. The operation will return once a datagram has been received,
// the socket was closed by another thread or an error occured.
size_t num_bytes = socket. receiveDatagram (datagram. data (), datagram. size (), error);
// Resize the buffer to the actual size of the received datagram.
datagram. resize (num_bytes);
std::cout << " Received " << datagram. size () << " bytes: "
<< std::string (datagram. data (), datagram. size ())
<< std::endl;
}
return 0 ;
}
Sie benötigen Git-for-Windows, Visual Studio 2015 oder neuer und CMake 3.13 oder neuer, um Udpcap zu kompilieren.
Klonen Sie dieses Repo
(Alternativ können Sie dieses Repo als Archiv herunterladen. Es gibt keine Untermodule.)
git clone https://github.com/eclipse-ecal/udpcap.git
cd udpcap
Rufen Sie CMakeWindows.bat
auf
Dadurch werden auch die folgenden Abhängigkeiten heruntergeladen:
.lib
Dateien).lib
Dateien) Öffnen Sie _build/udpcap.sln
mit Visual Studio und kompilieren Sie udpcap
und die Beispiele
Um einige Ausgaben der Beispiele zu sehen, müssen Sie natürlich immer sowohl das Sender- als auch das udpcap_reciever-Beispiel ausführen.
Sie können die folgenden CMake-Optionen festlegen, um zu steuern, wie Udpcap erstellt werden soll:
Option | Typ | Standard | Erläuterung |
---|---|---|---|
UDPCAP_BUILD_SAMPLES | BOOL | ON | Erstellen Sie die Udpcap- (und ASIO-)Beispiele zum Senden und Empfangen von Dummy-Daten |
UDPCAP_BUILD_TESTS | BOOL | OFF | Erstellen Sie die udpcap-GTests. Erfordert die Verfügbarkeit von GTest::GTest. |
UDPCAP_THIRDPARTY_ENABLED | BOOL | ON | Aktivieren/Deaktivieren Sie die Verwendung integrierter Abhängigkeiten. |
UDPCAP_THIRDPARTY_USE_BUILTIN_NPCAP | BOOL | ON | Rufen Sie eine integrierte Version des npcap SDK ab und erstellen Sie diese. Nur verfügbar, wenn UDPCAP_THIRDPARTY_ENABLED=ON |
UDPCAP_THIRDPARTY_USE_BUILTIN_PCAPPLUSPLUS | BOOL | ON | Abrufen und Erstellen einer integrierten Version von Pcap++. Nur verfügbar, wenn UDPCAP_THIRDPARTY_ENABLED=ON |
UDPCAP_THIRDPARTY_USE_BUILTIN_ASIO | BOOL | ON | Rufen Sie eine integrierte Version von ASIO ab und erstellen Sie sie. Nur verfügbar, wenn UDPCAP_THIRDPARTY_ENABLED=ON |
UDPCAP_THIRDPARTY_USE_BUILTIN_GTEST | BOOL | ON | Rufen Sie Tests anhand einer vordefinierten Version von GTest ab und erstellen Sie sie. Wenn deaktiviert, müssen die Ziele extern bereitgestellt werden. Nur verfügbar, wenn UDPCAP_THIRDPARTY_ENABLED=ON und UDPCAP_BUILD_TESTS=ON |
UDPCAP_LIBRARY_TYPE | STRING | Steuert den Bibliothekstyp von Udpcap, indem die Zeichenfolge in den add_library -Aufruf eingefügt wird. Kann auf STATIC / SHARED / OBJECT eingestellt werden. Wenn diese Option festgelegt ist, wird die reguläre CMake-Option BUILD_SHARED_LIBS überschrieben. Wenn nicht festgelegt, verwendet CMake die Standardeinstellung, die von BUILD_SHARED_LIBS gesteuert wird. |
Als Binärdateien integrieren :
Laden Sie eine udpcap-Version herunter oder erstellen Sie sie wie zuvor beschrieben. Wenn Sie selbst erstellen, stellen Sie sicher, dass Sie sowohl eine Debug- als auch eine Release-Version erstellen und installieren.
Wenn Sie die gemeinsam genutzte udpcap-Bibliothek (-> .dll
) gewählt haben, ist diese eigenständig und Sie müssen nur udpcap.dll
/ udpcapd.dll
in Ihr Anwendungsverzeichnis kopieren.
Wenn Sie die statische udpcap-Bibliothek (-> .lib
) gewählt haben, müssen Sie auch die folgenden Ziele für CMake verfügbar machen:
pcapplusplus::pcapplusplus
npcap::npcap
Schauen Sie sich das Udpcap-Integrationsbeispiel an, um einen Vorschlag dazu zu erhalten. Die Skripte und Module zum Abrufen und Finden von Npcap und Pcap++ finden Sie hier:
Fügen Sie das udpcap-Verzeichnis zu Ihrem CMAKE_PREFIX_PATH
hinzu:
cmake your_command_line -DCMAKE_PREFIX_PATH=path/to/udpcap/install/dir
Als Quelle integrieren
Machen Sie die udpcap-Quelle in beiden Fällen verfügbar. Sie können es beispielsweise manuell herunterladen, ein Git-Submodul verwenden oder CMake FetchContent verwenden.
Fügen Sie Folgendes zu Ihrer CMakeLists.txt
hinzu:
# You will probably not need the samples, so turn them off.
set (UDPCAP_BUILD_SAMPLES OFF )
# Add the top-level directory as cmake subdirectory
add_subdirectory ( "path_to_udpcap" )
# Add the dummy Findudpcap.cmake do the module path to make
# find_package(udpcap) succeed.
list ( APPEND CMAKE_MODULE_PATH "path_to_udpcap/thirdparty/udpcap/Modules" )
Jetzt können Sie gegen udpcap::udpcap
verlinken