Writing a basic traceroute script in C
-
28-10-2019 - |
Question
I have to write a trceroute script but I'm not sure if my attempts are correct.
Right now I'm doing it like that (please correct me if I'm doing wrong or clumsy):
- Got an struct for ip- and udpheader
- A checksum function
- Opening 2 sockets: One for sending UDP-packets in SOCK_RAW mode (to manipulate ttl) and one to receive ICMP-answers from the routers.
- Using sendto() to send UDP packet
- Having no clue how to receive and process an ICMP answer
Are there any more comfortable ways to change the TTL than using sock_raw where I have to define all header stuff by myself? What parameters should I use for socket() when opening ICMP sock? How to receive the ICMP answer?
Solution
What platform are you targeting? Here's a BSD flavor from OpenBSD source:
if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
err(5, "icmp socket");
if ((sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
err(5, "raw socket");
On Linux, I believe, you need to use IP_RECVERR
and recvmsg(2)
with the MSG_ERRQUEUE
, see ip(7)
.
OTHER TIPS
As far as setting the TTL is concerned, you can use setsockopt()
. Here's an extract from the iputils' source for ping
on Linux:
if (setsockopt(icmp_sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, 1) == -1) {
perror ("ping: can't set multicast time-to-live");
exit(2);
}
if (setsockopt(icmp_sock, IPPROTO_IP, IP_TTL, &ittl, sizeof(ittl)) == -1) {
perror ("ping: can't set unicast time-to-live");
exit(2);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow