IcmpSendEcho 함수는 Windows 운영 체제에서 ICMP 에코 요청을 보내고 응답을 받는 데 사용되는 함수로 주로 네트워크 연결 상태를 확인하거나 호스트의 응답 시간을 측정하는 데 사용됩니다.
📝 ICMP (Internet Control Message Protocol) : 네트워크에서 발생하는 여러 상태 및 오류 메시지를 전송하는 데 사용되는 프로토콜
DWORD IcmpSendEcho(
HANDLE IcmpHandle,
IPAddr DestinationAddress,
LPVOID RequestData,
WORD RequestSize,
PIP_OPTION_INFORMATION RequestOptions,
LPVOID ReplyBuffer,
DWORD ReplySize,
DWORD Timeout
);
- IcmpHandle: ICMP 핸들, IcmpCreateFile 함수를 사용하여 얻을 수 있다.
- DestinationAddress: 응답을 받고자 하는 호스트의 IP 주소
- RequestData: ICMP 에코 요청에 포함되는 데이터를
- RequestSize: RequestData의 크기(바이트)
- RequestOptions: ICMP 요청의 옵션 정보를 나타내는 포인터
- ReplyBuffer: 응답 데이터를 저장할 버퍼
- ReplySize: ReplyBuffer의 크기(바이트)
- Timeout: 응답을 기다리는 최대 시간(밀리초)
- 반환값 : 성공적으로 에코 요청이 전송된 경우 응답의 수. 실패한 경우에는 0이 반환
사용 예시.
ICMP 에코 응답이 내가 요청한 특정 호스트가 아니라 로컬 루프백 인터페이스를 통해서 응답이 오거나 게이트웨이가 응답할 수도 있으므로 응답을 받은 경우 ReplyBuffer를 PICMP_ECHO_REPLY로 캐스팅해서 내가 ICMP 요청을 보낸 호스트로부터 응답이 온게 맞는지 확인할 필요가 있다.
그 외 Status나 DataSize, RoundTripTime 등의 멤버변수를 확인해 네트워크 연결 상태를 확인한다. Status는 정상인 경우 IP_SUCCESS(0)으로 정의되어 있다.
#include <winsock2.h>
#include <iphlpapi.h>
#include <icmpapi.h>
#include <stdio.h>
#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")
int main(int argc, char** argv) {
// Declare and initialize variables
HANDLE hIcmpFile;
unsigned long ipaddr = INADDR_NONE;
DWORD dwRetVal = 0;
char SendData[32] = "Data Buffer";
LPVOID ReplyBuffer = NULL;
DWORD ReplySize = 0;
const char* ip = "192.168.0.11";
ipaddr = inet_addr(ip);
hIcmpFile = IcmpCreateFile();
if (hIcmpFile == INVALID_HANDLE_VALUE) {
printf("Unable to open handle.\n");
printf("IcmpCreatefile returned error: %ld\n", GetLastError());
return 1;
}
// ReplySize >= sizeof(ICMP_ECHO_REPLY) + sizeof(SendData) + 8 이어야 한다.
ReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(SendData) + 8;
ReplyBuffer = (VOID*)malloc(ReplySize);
if (ReplyBuffer == NULL) {
printf("Unable to allocate memory\n");
return 1;
}
dwRetVal = IcmpSendEcho(hIcmpFile, ipaddr, SendData, sizeof(SendData), NULL, ReplyBuffer, ReplySize, 1000);
if (dwRetVal != 0) {
PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer;
struct in_addr ReplyAddr;
ReplyAddr.S_un.S_addr = pEchoReply->Address;
printf("Sent icmp message to %s\n", ip);
printf("Received %ld icmp message responses\n", dwRetVal);
printf("Received %d bytes from %s\n", pEchoReply->DataSize, inet_ntoa(ReplyAddr));
printf("Status = %ld\n", pEchoReply->Status);
printf("Roundtrip time = %ld ms\n", pEchoReply->RoundTripTime);
}
else {
printf("Call to IcmpSendEcho failed.\n");
printf("IcmpSendEcho returned error: %ld\n", GetLastError());
return 1;
}
return 0;
}
IcmpSendEcho 함수의 확장된 버전인 IcmpSendEcho2, IcmpSendEcho2Ex 함수도 있다. 추가적인 기능과 옵션을 제공하며 IcmpSendEcho 함수와의 주된 차이는 비동기 작업을 지원하는 데 있다.
출처 :
https://learn.microsoft.com/en-us/windows/win32/api/icmpapi/nf-icmpapi-icmpsendecho
'프로그래밍 > C' 카테고리의 다른 글
윈도우 소켓 ] connect() 함수의 타임아웃은 21초 (0) | 2023.12.25 |
---|---|
윈도우 소켓 ] blocking / non-blocking 소켓 사용 시 소켓함수의 리턴 조건 (0) | 2023.12.24 |
strchr, strrchr (0) | 2023.12.22 |
strpbrk (0) | 2023.12.21 |
strcspn (0) | 2023.12.20 |