aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Ghigonis <laurent@p1sec.com>2013-06-28 01:31:13 +0200
committerLaurent Ghigonis <laurent@p1sec.com>2013-06-28 01:31:13 +0200
commitbf2dc85619aa8253659fe478f7511b9b519c3529 (patch)
tree86d537e4e275ef8f4990bcd4a3a5cf55f928b232
parentlibglouglou: traceroute: count hops (diff)
downloadglouglou-bf2dc85619aa8253659fe478f7511b9b519c3529.tar.xz
glouglou-bf2dc85619aa8253659fe478f7511b9b519c3529.zip
libglouglou: traceroute: improve hops counting
-rw-r--r--libglouglou/libggnet_traceroute.c66
-rw-r--r--libglouglou/libggnet_traceroute.h3
2 files changed, 38 insertions, 31 deletions
diff --git a/libglouglou/libggnet_traceroute.c b/libglouglou/libggnet_traceroute.c
index 352cb0b..c7b095b 100644
--- a/libglouglou/libggnet_traceroute.c
+++ b/libglouglou/libggnet_traceroute.c
@@ -83,8 +83,7 @@ static struct ggnet_traceroute_hop *
_hop_ip_id(struct ggnet_traceroute_req *, int);
static struct ggnet_traceroute_hop *
_hop_sport(struct ggnet_traceroute_req *, int);
-static struct ggnet_traceroute_hop *
- _hop_last(struct ggnet_traceroute_req *);
+static void _trace_done(struct ggnet_traceroute_req *);
static int pcap_dloff(pcap_t *); // XXX move to libggnet_utils ?
double timeval_diff(struct timeval *, struct timeval *);
@@ -259,10 +258,12 @@ ggnet_traceroute_report(struct ggnet_traceroute_req *req) {
#define left (sizeof(report) - (p - report))
p = report;
- if (req->hopcount != 0)
- p += (u_char)snprintf(p, left, "%d hops\n", req->hopcount);
+ if (req->target->ttl > 0)
+ p += (u_char)snprintf(p, left, "target:\t\tanswering\n");
else
- p += (u_char)snprintf(p, left, "target not answering\n");
+ p += (u_char)snprintf(p, left, "target:\t\tnot answering\n");
+ p += (u_char)snprintf(p, left, "hops total:\t%d\n", req->hopcount_total);
+ p += (u_char)snprintf(p, left, "hops answering:\t%d\n", req->hopcount_answering);
TAILQ_FOREACH(hop, &req->hops_list, entry) {
p += (u_char)snprintf(p, left, "%.2d: %s %s %.2f [XXX %p]\n", hop->ttl, addr_ntoa(&hop->ip), hop->answer, hop->delay, hop);
}
@@ -486,19 +487,13 @@ static void
_cb_trace_timeout(evutil_socket_t fd, short what, void *arg)
{
struct ggnet_traceroute_req *req;
- struct ggnet_traceroute_hop *last;
req = arg;
if (req->ggtr->verbose)
printf("XXX cbggnet_traceroute cb_trace_timeout (%s -> %s)\n",
addr_ntoa(&req->srcip), addr_ntoa(&req->target->ip));
- last = _hop_last(req);
- if (req->ggtr->verbose)
- printf("XXX last %p\n", last);
- if (last)
- req->target->ttl = last->ttl + 1;
- req->cb_done(req, req->data);
+ _trace_done(req);
}
static void
@@ -538,30 +533,41 @@ _hop_sport(struct ggnet_traceroute_req *req, int sport)
return NULL;
}
-/**
- * Returns the target hop, and clean the hops_list before calling user callback
- * Also sets the hopcount
+/** Called at the end of a traceroute
+ * - Clean the hops_list by removing last non-answering hops
+ * - Updates target ttl
+ * - Count answering and total hops
+ * - Calls user callback
*/
-static struct ggnet_traceroute_hop *
-_hop_last(struct ggnet_traceroute_req *req)
+static void
+_trace_done(struct ggnet_traceroute_req *req)
{
- struct ggnet_traceroute_hop *h, *ht;
- struct ggnet_traceroute_hop *last = NULL;
- int found = 0;
- int count = 0;
-
- TAILQ_FOREACH_SAFE(h, &req->hops_list, entry, ht) {
- count++;
- if (found)
+ struct ggnet_traceroute_hop *h, *ht, *hp;
+ int hopcount_total = 0;
+ int hopcount_answering = 0;
+
+ TAILQ_FOREACH_REVERSE_SAFE(h, &req->hops_list, tailhead, entry, ht) {
+ if (h->answer_count) {
+ if (addr_cmp(&h->ip, &req->target->ip) == 0) {
+ req->target->ttl = h->ttl + 1;
+ hp = TAILQ_PREV(h, tailhead, entry);
+ if (hp && (addr_cmp(&hp->ip, &req->target->ip) == 0)) {
+ TAILQ_REMOVE(&req->hops_list, h, entry);
+ continue;
+ }
+ }
+ hopcount_answering++;
+ }
+ if (hopcount_answering > 0)
+ hopcount_total++;
+ else {
TAILQ_REMOVE(&req->hops_list, h, entry);
- else if (addr_cmp(&h->ip, &req->target->ip) == 0) {
- last = h;
- found = 1;
- req->hopcount = count;
}
}
+ req->hopcount_total = hopcount_total;
+ req->hopcount_answering = hopcount_answering;
- return last;
+ req->cb_done(req, req->data);
}
static int
diff --git a/libglouglou/libggnet_traceroute.h b/libglouglou/libggnet_traceroute.h
index dbbb9ec..1d28299 100644
--- a/libglouglou/libggnet_traceroute.h
+++ b/libglouglou/libggnet_traceroute.h
@@ -55,7 +55,8 @@ struct ggnet_traceroute_req {
struct ggnet_traceroute_hop *target;
struct addr srcip;
struct ggnet_traceroute_req_params *params;
- int hopcount;
+ int hopcount_total;
+ int hopcount_answering;
TAILQ_HEAD(tailhead, ggnet_traceroute_hop) hops_list;
struct {
struct event *ev_recv;