I'm trying to catch all ICMP "destination unreachable - port unreachable" messages using RAW sockets in C++. And then process the underlying UDP protocol to find out for which port the destination was not reachable. So far I managed to receive the ICMP messages and filter them based on their type and code. However, I'm having hard time accessing the udp header. So far I tried these:
*(struct udphdr*)(icmp + sizeof(struct icmphdr) + sizeof(struct iphdr))
and
struct iphdr *ip = (struct iphdr*)ether_frame;
struct icmphdr *icmp = (struct icmphdr*)(ether_frame + ip->ihl*4);
struct iphdr *ip2 = (struct iphdr*)(icmp + sizeof(struct icmphdr))
struct udphdr *udphdr = (struct udphdr*)(ip2 + ip2->ihl*4)
But neither one worked. I'm sure it's just some simple pointers arithmetic mistake, but I cannot figure it out. So my questions are: How exactly are the protocols organized in ICMP response? How can I access the port number which was unreachable from a raw icmp response?
EDIT: The socket used for receiving was created using this->rcv_sd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP
and the response is received using recv(this->rcv_sd, ether_frame, IP_MAXPACKET, 0)
, where ether_frame
is a uint8_t
array of size IP_MAXPACKET
.