Udpcap est une émulation UDP-Socket en réception uniquement basée sur Npcap. Il utilise le pilote de capture de paquets Npcap pour capturer le trafic Ethernet, analyser tous les en-têtes nécessaires et renvoyer la charge utile UDP. Avec Udpcap, vous pouvez ouvrir un Socket UDP et recevoir des données sans réellement ouvrir un Socket !
Le projet concerne uniquement Windows, car Npcap ne cible également que Windows.
Udpcap peut :
Udpcap ne peut pas :
Toutes les dépendances sont facilement récupérées par CMake. Cependant, pour utiliser réellement Udpcap, le pilote Npcap doit être installé. Gardez à l'esprit que la licence Npcap est propriétaire.
Utiliser un pilote de capture de paquets pour émuler un socket UDP semble être une très mauvaise idée, alors que vous pourriez simplement utiliser un socket UDP approprié ? Eh bien, c'est probablement le cas. Mais attendez, il existe un problème Windows très spécifique que ce projet peut contourner.
Par rapport à Windows 7, Windows 10 dispose d'un Windows Defender (le service MpsSvc) plus agressif. Lors de la réception de nombreux paquets de multidiffusion UDP avec un socket standard sous Windows 10, Windows Defender provoque une charge CPU massive, ce qui rend l'ensemble du système lent. Le problème semble être pire lorsque la machine Windows est connectée à un domaine Windows, comme cela se fait habituellement dans les réseaux des grandes entreprises. En examinant le système avec Process Hacker, on peut voir que le processus System
(le noyau Windows) occupe autant qu'un cœur de processeur entier. C'est toujours un thread à l'intérieur du noyau qui utilise tous les cycles CPU et il a tcpip.sys
dans sa pile d'appels :
Le pare-feu Defender ne peut plus être désactivé dans Windows 10. Le service MpsSvc continuera même à fonctionner lorsqu'il est temporairement désactivé, car il offre des fonctionnalités de sécurité supplémentaires en plus du pare-feu Defender.
Sous Windows, chaque accès réseau (initié par l'espace utilisateur) utilise l'API Winsocks/2. Cette API utilise le pilote de système de fichiers en mode noyau Afd.sys
, qui utilise ensuite le pilote de protocole de transport tcpip.sys
. Le pilote tcpip.sys est l'endroit où toute la magie du protocole se produit dans Windows. C'est également à ce moment-là que le pare-feu Windows Defender analyse le trafic. Microsoft a créé une API complète uniquement à cet effet : la plate-forme de filtrage Windows (WFP). Cette API est disponible sous Windows Vista et versions ultérieures. Ci-dessous tcpip.sys
se trouvent uniquement le NDIS.sys
(Network Driver Interface Spécification) et les pilotes NIC Ethernet réels. Ainsi, pour contourner le problème de charge CPU du Defender Firewall, nous devons contourner l’intégralité du pilote tcpip.sys
et tout ce qui se trouve au-dessus. Référez-vous à l'image ci-dessous (lignes noires) pour avoir un aperçu. Lors de l'utilisation de Npcap, Windows Defender ne voit aucun socket ouvert et n'analyse pas le trafic. Cela signifie cependant que la pile de protocoles UDP doit être réimplémentée dans l'espace utilisateur (c'est là que Udpcap s'avère utile !) .
Udpcap possède une API très simple avec de fortes similitudes avec d'autres API de socket bien connues :
# 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 ;
}
Vous aurez besoin de git-for-windows, de Visual Studio 2015 ou plus récent et de CMake 3.13 ou plus récent pour compiler Udpcap.
Cloner ce dépôt
(Vous pouvez également télécharger ce dépôt sous forme d'archive. Il n'y a pas de sous-modules.)
git clone https://github.com/eclipse-ecal/udpcap.git
cd udpcap
Appelez CMakeWindows.bat
Cela téléchargera également les dépendances suivantes :
.lib
).lib
) Ouvrez _build/udpcap.sln
avec Visual Studio et compilez udpcap
et les exemples
Pour voir certains résultats des échantillons, vous devrez évidemment toujours exécuter à la fois l'échantillon sender et udpcap_reciever.
Vous pouvez définir les options CMake suivantes pour contrôler la façon dont Udpcap est censé être construit :
Option | Taper | Défaut | Explication |
---|---|---|---|
UDPCAP_BUILD_SAMPLES | BOOL | ON | Créez les exemples Udpcap (et asio) pour envoyer et recevoir des données factices |
UDPCAP_BUILD_TESTS | BOOL | OFF | Créez les GTests udpcap. Nécessite que GTest::GTest soit disponible. |
UDPCAP_THIRDPARTY_ENABLED | BOOL | ON | Activer / Désactiver l'utilisation des dépendances intégrées. |
UDPCAP_THIRDPARTY_USE_BUILTIN_NPCAP | BOOL | ON | Récupérez et construisez avec une version intégrée du SDK npcap. Disponible uniquement si UDPCAP_THIRDPARTY_ENABLED=ON |
UDPCAP_THIRDPARTY_USE_BUILTIN_PCAPPLUSPLUS | BOOL | ON | Récupérez et construisez avec une version intégrée de Pcap++. Disponible uniquement si UDPCAP_THIRDPARTY_ENABLED=ON |
UDPCAP_THIRDPARTY_USE_BUILTIN_ASIO | BOOL | ON | Récupérez et construisez avec une version intégrée d'asio. Disponible uniquement si UDPCAP_THIRDPARTY_ENABLED=ON |
UDPCAP_THIRDPARTY_USE_BUILTIN_GTEST | BOOL | ON | Récupérez et créez des tests sur une version prédéfinie de GTest. Si désactivé, les cibles doivent être fournies en externe. Disponible uniquement si UDPCAP_THIRDPARTY_ENABLED=ON et UDPCAP_BUILD_TESTS=ON |
UDPCAP_LIBRARY_TYPE | STRING | Contrôle le type de bibliothèque d'Udpcap en injectant la chaîne dans l'appel add_library . Peut être réglé sur STATIQUE / PARTAGÉ / OBJET. Si défini, cela remplacera l’option CMake BUILD_SHARED_LIBS standard. S'il n'est pas défini, CMake utilisera le paramètre par défaut, qui est contrôlé par BUILD_SHARED_LIBS . |
Intégrer en binaire :
Téléchargez une version udpcap ou construisez-la comme décrit précédemment. Si vous créez vous-même, assurez-vous de créer et d'installer à la fois une version de débogage et une version finale.
Si vous avez choisi la bibliothèque udpcap partagée (-> .dll
), elle sera autonome et il vous suffira de copier le udpcap.dll
/ udpcapd.dll
dans le répertoire de votre application.
Si vous avez choisi la bibliothèque statique udpcap (-> .lib
), vous devez également rendre les cibles suivantes disponibles pour CMake :
pcapplusplus::pcapplusplus
npcap::npcap
Consultez l'exemple d'intégration Udpcap pour une suggestion sur la façon de procéder. Vous pouvez trouver les scripts et modules pour récupérer et trouver Npcap et Pcap++ ici :
Ajoutez le répertoire udpcap à votre CMAKE_PREFIX_PATH
:
cmake your_command_line -DCMAKE_PREFIX_PATH=path/to/udpcap/install/dir
Intégrer comme source
Rendez la source udpcap disponible dans tous les cas. Vous pouvez par exemple le télécharger manuellement, utiliser un sous-module git ou utiliser CMake FetchContent.
Ajoutez ce qui suit à votre CMakeLists.txt
:
# 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" )
Vous pouvez maintenant établir un lien avec udpcap::udpcap