0
votes

I have an application that uses sendto() with UDP to check resources on different ports. How can I get the ICMP port unreachable packet using recvfrom()?

My recvfrom() is like this:

SOCKADDR_STORAGE saFrom;
int nFromLen = sizeof( SOCKADDR_STORAGE );
nReceived = recvfrom ( Socket, Buffer, BufferSize, 0, ( struct sockaddr * ) &saFrom, (socklen_t *)&nFromLen );

When an ICMP port unreachable occurs, nReceived = -1, and WSAGetLastError() returns WSAECONNRESET(10054).

But since I'm checking on different ports, I'd like a way of determining which port triggered the ICMP port unreachable message. How can I determine that? (Maybe I can set some socket options?)

Edit: As per Len's suggestion(use ICMP only), I tried to create a socket by socket (AF_INET, SOCK_RAW, IPPROTO_ICMP), then call recvfrom() on it. recvfrom() returns 10022(WSAEINVAL) error because the socket is not bound. How should I fix that?

1

1 Answers

0
votes

You can't, see my blog posting on the subject here: http://www.lenholgate.com/blog/2007/12/bug-in-overlapped-udp-port-unreachable-errors.html

If you're on XP, then you can use SIO_UDP_CONNRESET with WSAIoctl to control if you get ERROR_PORT_UNREACHABLE reported rather than WSAECONNRESET but even with that set (or on an OS where this is the default) you still do not get the address of the remote port where the ICMP port unreachable happened.

I suggest you use one socket per port you're checking, that way you'll be able to determine where the error came from. Or use ICMP directly.