Udpcap은 Npcap을 기반으로 한 수신 전용 UDP 소켓 에뮬레이션입니다. Npcap 패킷 캡처 드라이버를 활용하여 이더넷 트래픽을 캡처하고 필요한 모든 헤더를 구문 분석하고 UDP 페이로드를 반환합니다. Udpcap을 사용하면 실제로 소켓을 열지 않고도 UDP 소켓을 열고 데이터를 수신할 수 있습니다!
Npcap은 Windows만 대상으로 하므로 프로젝트는 Windows 전용입니다.
Udpcap은 다음을 수행할 수 있습니다 .
Udpcap은 다음을 수행할 수 없습니다 .
모든 종속성은 CMake에서 편리하게 가져옵니다. 그러나 실제로 Udpcap을 사용하려면 Npcap 드라이버를 설치해야 합니다. Npcap 라이센스는 독점적이라는 점을 명심하십시오.
적절한 UDP 소켓을 사용할 수 있는데 UDP 소켓을 에뮬레이트하기 위해 패킷 캡처 드라이버를 사용하는 것은 끔찍한 생각처럼 들리나요? 글쎄, 아마도 그럴 것이다. 하지만 잠깐만요. 이 프로젝트에서 해결할 수 있는 매우 구체적인 Windows 문제가 있습니다.
Windows 7에 비해 Windows 10에는 더욱 공격적인 Windows Defender(MpsSvc 서비스)가 있습니다. Windows 10에서 일반 소켓을 사용하여 많은 UDP 멀티캐스트 패킷을 수신할 때 Windows Defender는 막대한 CPU 로드를 발생시켜 전체 시스템을 지연시킵니다. 일반적으로 대기업 네트워크에서 수행되는 것처럼 Windows 컴퓨터가 Windows 도메인에 연결되어 있으면 문제가 더 악화되는 것 같습니다. Process Hacker를 사용하여 시스템을 조사하면 System
프로세스(Windows 커널)가 전체 CPU 코어만큼 차지하는 것을 볼 수 있습니다. 모든 CPU 주기를 사용하는 커널 내부의 스레드는 항상 하나이며 호출 스택에 tcpip.sys
있습니다.
Windows 10에서는 더 이상 Defender 방화벽을 비활성화할 수 없습니다. MpsSvc 서비스는 Defender 방화벽 외에 추가 보안 기능을 제공하므로 일시적으로 비활성화된 경우에도 계속 실행됩니다.
Windows에서는 모든(사용자 공간 시작) 네트워크 액세스가 Winsocks/2 API를 사용합니다. 해당 API는 커널 모드 파일 시스템 드라이버 Afd.sys
를 사용한 다음 전송 프로토콜 드라이버 tcpip.sys
를 사용합니다. tcpip.sys 드라이버는 Windows에서 모든 프로토콜 마법이 발생하는 곳입니다. 이는 Windows Defender 방화벽이 트래픽을 분석하는 지점이기도 합니다. Microsoft는 해당 목적만을 위해 WFP(Windows 필터링 플랫폼)라는 전체 API를 만들었습니다. 이 API는 Windows Vista 이상에서 사용할 수 있습니다. tcpip.sys
아래에는 NDIS.sys
(네트워크 드라이버 인터페이스 사양)와 실제 이더넷 NIC 드라이버만 있습니다. 따라서 Defender Firewall CPU 로드 문제를 해결하려면 전체 tcpip.sys
드라이버와 그 위의 모든 항목을 우회해야 합니다. 개요를 보려면 아래 이미지(검은색 선)를 참조하세요. Npcap을 사용할 때 Windows Defender는 열린 소켓을 확인하지 않으며 트래픽을 분석하지 않습니다. 그러나 이는 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
파일) Visual Studio에서 _build/udpcap.sln
열고 udpcap
및 샘플을 컴파일합니다.
샘플의 일부 출력을 보려면 항상 송신자 및 udpcap_reciever 샘플을 모두 실행해야 합니다.
다음 CMake 옵션을 설정하여 Udpcap의 빌드 방법을 제어할 수 있습니다.
옵션 | 유형 | 기본 | 설명 |
---|---|---|---|
UDPCAP_BUILD_SAMPLES | BOOL | ON | 더미 데이터 전송 및 수신을 위한 Udpcap(및 asio) 샘플 빌드 |
UDPCAP_BUILD_TESTS | BOOL | OFF | udpcap GTest를 빌드합니다. 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 | add_library 호출에 문자열을 삽입하여 Udpcap의 라이브러리 유형을 제어합니다. STATIC / SHARED / OBJECT로 설정할 수 있습니다. 설정된 경우 일반 BUILD_SHARED_LIBS CMake 옵션을 재정의합니다. 설정하지 않으면 CMake는 BUILD_SHARED_LIBS 에 의해 제어되는 기본 설정을 사용합니다. |
바이너리로 통합 :
udpcap 릴리스를 다운로드하거나 앞에서 설명한 대로 빌드하십시오. 직접 빌드하는 경우 디버그 버전과 릴리스 버전을 모두 빌드하고 설치해야 합니다.
공유 udpcap 라이브러리(-> .dll
)를 선택한 경우 자체 포함되며 udpcap.dll
/ udpcapd.dll
만 응용 프로그램 디렉터리에 복사하면 됩니다.
정적 udpcap 라이브러리(-> .lib
)를 선택한 경우 CMake에서도 다음 대상을 사용할 수 있도록 설정해야 합니다.
pcapplusplus::pcapplusplus
npcap::npcap
이를 수행하는 방법에 대한 제안은 Udpcap 통합 샘플을 확인하세요. Npcap 및 Pcap++를 가져오고 찾기 위한 스크립트와 모듈은 여기에서 찾을 수 있습니다.
CMAKE_PREFIX_PATH
에 udpcap 디렉터리를 추가합니다.
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
에 연결할 수 있습니다.