I met the same problem and solved it.
You need to
- create a new socket using ICMP protocol
- bind to a specific port like 33434
- receive ICMP reply.
I will show my code.
// ......create sending socket and fill the udp data...
// create socket to receive ICMP reply
SOCKET sock = WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0,
WSA_FLAG_OVERLAPPED);
// from for receiving data about routing server
SOCKADDR_IN server_addr, from;
int fromlen = sizeof(from);
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(33434);
// Set the receive and send timeout values to a second
timeout = 1000;
ret = setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,
sizeof(timeout));
if (ret == SOCKET_ERROR) {
printf("setsockopt(SO_RCVTIMEO) failed: %d\n", WSAGetLastError());
return -1;
}
timeout = 1000;
ret = setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout,
sizeof(timeout));
if (ret == SOCKET_ERROR) {
printf("setsockopt(SO_SNDTIMEO) failed: %d\n", WSAGetLastError());
return -1;
}
// bind to the port 33434
int err = bind(sock, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
if (err != 0) {
fprintf(stderr, "bind with error: %d\n", WSAGetLastError());
return 3;
}
for (ttl = 1; ((ttl < maxhops) && (!done)); ttl++) {
int bwrote;
// Set the time to live option on the socket
set_ttl(sockRaw, ttl);
// Fill in some more data in the UDP header
((UdpHeader *)udp_data)->length = 8;
((UdpHeader *)udp_data)->dest_port = htons(33434);
((UdpHeader *)udp_data)->source_port = htons(33434);
((UdpHeader *)udp_data)->checksum =
checksum((USHORT *)udp_data, datasize);
// Send the UDP packet to the destination
bwrote = sendto(sockRaw, udp_data, datasize, 0, (SOCKADDR *)&dest,
sizeof(dest));
if (bwrote == SOCKET_ERROR) {
if (WSAGetLastError() == WSAETIMEDOUT) {
printf("%2d Send request timed out.\n", ttl);
continue;
}
printf("sendto() failed: %d\n", WSAGetLastError());
return -1;
}
// Read a packet back from the destination or a router along the way.
ret = recvfrom(sock, recvbuf, MAX_PACKET, 0, (struct sockaddr *)&from,
&fromlen);
if (ret == SOCKET_ERROR) {
if (WSAGetLastError() == WSAETIMEDOUT) {
printf("%2d Receive Request timed out.\n", ttl);
continue;
}
printf("recvfrom() failed: %d\n", WSAGetLastError());
return -1;
}
/* Decode the response to see if the ICMP response is from a router
* along the way or whether it has reached the destination. */
done = decode_resp(recvbuf, ret, &from, ttl);
Sleep(1000);
}
and it works on my computer. (Windows 10)
the result in my computer