Udpcap — это эмуляция UDP-сокета только для приема, основанная на Npcap. Он использует драйвер захвата пакетов Npcap для захвата Ethernet-трафика, анализа всех необходимых заголовков и возврата полезной нагрузки UDP. С помощью Udpcap вы можете открыть UDP-сокет и получать данные, фактически не открывая сокет!
Проект предназначен только для Windows, поскольку Npcap также предназначен только для Windows.
Udpcap может :
Udpcap не может :
Все зависимости удобно извлекаются с помощью CMake. Однако для фактического использования Udpcap необходимо установить драйвер Npcap. Имейте в виду, что лицензия Npcap является частной.
Использование драйвера захвата пакетов для эмуляции сокета UDP кажется ужасной идеей, тогда как можно просто использовать правильный сокет UDP? Ну, это, вероятно, так. Но подождите, есть очень специфическая проблема Windows, которую этот проект может обойти.
По сравнению с Windows 7, Windows 10 имеет более агрессивный Защитник Windows (службу MpsSvc). При получении большого количества многоадресных пакетов UDP через обычный сокет в Windows 10 Защитник Windows вызывает огромную загрузку процессора, что приводит к задержке всей системы. Проблема усугубляется, когда компьютер с Windows подключен к домену Windows, как это обычно делается в сетях крупных корпораций. При исследовании системы с помощью Process Hacker можно увидеть, что System
процесс (ядро Windows) занимает целое ядро ЦП. Внутри ядра всегда есть один поток, который использует все циклы ЦП, и в его стеке вызовов есть tcpip.sys
:
Брандмауэр Защитника больше нельзя деактивировать в Windows 10. Служба MpsSvc будет продолжать работать даже в случае временной деактивации, поскольку помимо брандмауэра Defender она предлагает дополнительные функции безопасности.
В Windows каждый доступ к сети (инициируемый пользовательским пространством) использует Winsocks/2 API. Этот API использует драйвер файловой системы режима ядра Afd.sys
, который затем использует драйвер транспортного протокола tcpip.sys
. Драйвер tcpip.sys — это то место, где происходит вся магия протокола в Windows. Это также момент, когда брандмауэр Защитника Windows анализирует трафик. Только для этой цели Microsoft создала целый API: платформу фильтрации Windows (WFP). Этот API доступен в Windows Vista и более поздних версиях. Ниже tcpip.sys
находится только NDIS.sys
(спецификация интерфейса сетевого драйвера) и фактические драйверы сетевого адаптера Ethernet. Поэтому, чтобы обойти проблему загрузки ЦП брандмауэра Defender, нам нужно обойти весь драйвер tcpip.sys
и все, что над ним. Обратитесь к изображению ниже (черные линии), чтобы получить общее представление. При использовании Npcap Защитник Windows не видит открытых сокетов и не анализирует трафик. Однако это означает, что стек протоколов UDP необходимо повторно реализовать в пользовательском пространстве (вот тут-то и пригодится Udpcap!) .
Udpcap имеет очень простой API, очень похожий на другие известные API сокетов:
# 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 ;
}
Для компиляции Udpcap вам понадобится git for windows, Visual Studio 2015 или новее и CMake 3.13 или новее.
Клонировать этот репозиторий
(В качестве альтернативы вы можете скачать этот репозиторий в виде архива. Подмодулей нет.)
git clone https://github.com/eclipse-ecal/udpcap.git
cd udpcap
Вызов CMakeWindows.bat
Это также загрузит следующие зависимости:
.lib
).lib
) Откройте _build/udpcap.sln
с помощью Visual Studio и скомпилируйте udpcap
и примеры.
Чтобы увидеть некоторые выходные данные образцов, вам, очевидно, придется всегда выполнять как образец sender, так и udpcap_reciever.
Вы можете установить следующие параметры CMake, чтобы контролировать способ сборки Udpcap:
Вариант | Тип | По умолчанию | Объяснение |
---|---|---|---|
UDPCAP_BUILD_SAMPLES | BOOL | ON | Создайте образцы Udpcap (и asio) для отправки и получения фиктивных данных. |
UDPCAP_BUILD_TESTS | BOOL | OFF | Создайте GTests udpcap. Требуется, чтобы GTest::GTest был доступен. |
UDPCAP_THIRDPARTY_ENABLED | BOOL | ON | Активируйте/деактивируйте использование интегрированных зависимостей. |
UDPCAP_THIRDPARTY_USE_BUILTIN_NPCAP | BOOL | ON | Получите и создайте интегрированную версию npcap SDK. Доступно только в том случае, если UDPCAP_THIRDPARTY_ENABLED=ON |
UDPCAP_THIRDPARTY_USE_BUILTIN_PCAPPLUSPLUS | BOOL | ON | Извлеките и создайте интегрированную версию Pcap++. Доступно только в том случае, если UDPCAP_THIRDPARTY_ENABLED=ON |
UDPCAP_THIRDPARTY_USE_BUILTIN_ASIO | BOOL | ON | Получите и создайте интегрированную версию asio. Доступно только в том случае, если UDPCAP_THIRDPARTY_ENABLED=ON |
UDPCAP_THIRDPARTY_USE_BUILTIN_GTEST | BOOL | ON | Получите и создайте тесты для предопределенной версии GTest. Если отключено, цели должны быть предоставлены извне. Доступно только в том случае, если UDPCAP_THIRDPARTY_ENABLED=ON и UDPCAP_BUILD_TESTS=ON |
UDPCAP_LIBRARY_TYPE | STRING | Управляет типом библиотеки Udpcap, вводя строку в вызов add_library . Можно установить СТАТИЧЕСКИЙ / ОБЩИЙ / ОБЪЕКТ. Если установлено, это переопределит обычный параметр CMake BUILD_SHARED_LIBS . Если этот параметр не установлен, CMake будет использовать настройку по умолчанию, которая контролируется BUILD_SHARED_LIBS . |
Интегрировать как двоичные файлы :
Загрузите выпуск udpcap или создайте его, как описано ранее. Если вы собираете самостоятельно, обязательно создайте и установите как отладочную, так и релизную версию.
Если вы выбрали общую библиотеку udpcap (-> .dll
), она будет автономной, и вам нужно будет только скопировать udpcap.dll
/ udpcapd.dll
в каталог вашего приложения.
Если вы выбрали статическую библиотеку udpcap (-> .lib
), вам также необходимо сделать следующие цели доступными для CMake:
pcapplusplus::pcapplusplus
npcap::npcap
Ознакомьтесь с примером интеграции Udpcap, чтобы узнать, как это сделать. Вы можете найти скрипты и модули для получения и поиска Npcap и Pcap++ здесь:
Добавьте каталог udpcap в свой CMAKE_PREFIX_PATH
:
cmake your_command_line -DCMAKE_PREFIX_PATH=path/to/udpcap/install/dir
Интегрировать как источник
В любом случае сделайте источник udpcap доступным. Вы можете, например, загрузить его вручную, использовать подмодуль git или использовать CMake FetchContent.
Добавьте следующее в свой 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" )
Теперь вы можете ссылаться на udpcap::udpcap