#include #if !defined(__OpenBSD__) #define __USE_GNU #define _GNU_SOURCE #endif #include #include #include #include #include #include #include #include #include #include #include /* for get_iface() and droppriv() */ #include static void _cb_traceroute(struct addr *, struct ggnet_traceroute_req *, void *); struct event_base *_ev_base; struct ggnet_traceroute_req *_route = NULL; int _answer = 0; int main(int argc, char *argv[]) { struct ggnet_traceroute *ggtr; struct ggnet_traceroute_hop *hop; struct addr ip; struct timeval tv; if (argc < 2) { printf("usage: traceroute \n"); exit(1); } addr_aton(argv[1], &ip); bzero(&tv, sizeof(struct timeval)); tv.tv_sec = 10; _ev_base = event_base_new(); ggtr = ggnet_traceroute_new(_ev_base, get_iface(argv[1])); droppriv("nobody", 1, NULL); /* bad practise you should use dedicated user */ ggnet_traceroute_trace(ggtr, &ip, TRACEMODE_ICMP, _cb_traceroute, NULL); event_base_loopexit(_ev_base, &tv); event_base_dispatch(_ev_base); if (_answer) { printf("%s:\n", addr_ntoa(&ip)); TAILQ_FOREACH(hop, &_route->hops_list, entry) { printf("%s (%d)\n", addr_ntoa(&hop->ip), hop->delay); } } else { printf("no answer\n"); } return 0; } static void _cb_traceroute(struct addr *ip, struct ggnet_traceroute_req *route, void *data) { _route = route; _answer = 1; event_base_loopexit(_ev_base, NULL); }