aboutsummaryrefslogtreecommitdiffstats
path: root/libglouglou
diff options
context:
space:
mode:
authorLaurent Ghigonis <laurent@p1sec.com>2012-12-15 20:57:16 +0100
committerLaurent Ghigonis <laurent@p1sec.com>2012-12-15 20:57:16 +0100
commit285e1f2af92ae134ad2ce148ed9aa84c4342cb31 (patch)
tree8d45296fab74f9d1616127243e57e6cf714c7127 /libglouglou
parentchange default graph layout to EGRAPH_LAYOUT_KAMADAKAWAI (diff)
downloadglouglou-285e1f2af92ae134ad2ce148ed9aa84c4342cb31.tar.xz
glouglou-285e1f2af92ae134ad2ce148ed9aa84c4342cb31.zip
start coding on libggnet_traceroute in 'traceroute' branch.
TDD test in examples/traceroute.c
Diffstat (limited to 'libglouglou')
-rw-r--r--libglouglou/Makefile6
-rw-r--r--libglouglou/examples/traceroute.c60
-rw-r--r--libglouglou/libggnet_traceroute.c56
-rw-r--r--libglouglou/libggnet_traceroute.h39
4 files changed, 159 insertions, 2 deletions
diff --git a/libglouglou/Makefile b/libglouglou/Makefile
index 0343e6f..2065315 100644
--- a/libglouglou/Makefile
+++ b/libglouglou/Makefile
@@ -6,8 +6,10 @@ LIBDIR=$(PREFIX)/lib
LIBNAME=libglouglou
TARGET = ${LIBNAME}.so
-SOURCES = libglouglou.c sendbuf.c utils.c libggnet.c libggnet_dns.c
-HEADERS = libglouglou.h libggnet.h libggnet_dns.h
+SOURCES = libglouglou.c sendbuf.c utils.c \
+ libggnet.c libggnet_dns.c libggnet_traceroute.c
+HEADERS = libglouglou.h \
+ libggnet.h libggnet_dns.h libggnet_traceroute.h
OBJECTS = $(SOURCES:.c=.o)
all: $(TARGET)
diff --git a/libglouglou/examples/traceroute.c b/libglouglou/examples/traceroute.c
new file mode 100644
index 0000000..9d3e218
--- /dev/null
+++ b/libglouglou/examples/traceroute.c
@@ -0,0 +1,60 @@
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <libggnet_traceroute.h>
+
+static void _cb_traceroute(struct in_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 in_addr ip;
+ struct timeval tv;
+
+ if (argc < 2) {
+ printf("usage: traceroute <ip>\n");
+ exit(1);
+ }
+ inet_aton(argv[1], &ip);
+ ip.s_addr = ntohl(ip.s_addr);
+
+ bzero(&tv, sizeof(struct timeval));
+ tv.tv_sec = 5;
+
+ _ev_base = event_base_new();
+
+ ggtr = ggnet_traceroute_new(_ev_base);
+ ggnet_traceroute_reverse(ggtr, &ip, _cb_traceroute, NULL);
+
+ event_base_loopexit(_ev_base, &tv);
+ event_base_dispatch(_ev_base);
+
+ if (_answer) {
+ printf("%x:\n", ip.s_addr);
+ LIST_FOREACH(&_route->hops, h, entry) {
+ printf("%x (%d)\n", h->ip.s_addr, h->delay);
+ }
+ } else {
+ printf("no answer\n");
+ }
+ return 0;
+}
+
+static void
+_cb_traceroute(struct in_addr *ip,
+ struct ggnet_traceroute_req *route, void *data);
+{
+ _route = route;
+ _answer = 1;
+ event_base_loopexit(_ev_base, NULL);
+}
diff --git a/libglouglou/libggnet_traceroute.c b/libglouglou/libggnet_traceroute.c
new file mode 100644
index 0000000..3b8e6ed
--- /dev/null
+++ b/libglouglou/libggnet_traceroute.c
@@ -0,0 +1,56 @@
+/*
+ * Traceroute using libevent, libdnet and libpcap
+ *
+ * 2012 Laurent Ghigonis <laurent@p1sec.com>
+ *
+ * Inspired from jtrace (http://monkey.org/~jose/software/jtrace/)
+ * Copyright (c) 2003-2004 Jose Nazario <jose@monkey.org>
+ * All rights reserved.
+ */
+
+struct ggnet_traceroute *
+ggnet_traceroute_new(struct event_base *ev_base)
+{
+ struct ggnet_traceroute *ggtr;
+
+ ggtr = calloc(1, sizeof(struct ggnet_traceroute));
+ if (!ggtr) {
+ printf("could not allocate ggnet_traceroute\n");
+ exit(1);
+ }
+ ggtr->ev_base = ev_base;
+ return ggdns;
+}
+
+void
+ggnet_traceroute_free(struct ggnet_traceroute *ggtr)
+{
+ free(ggtr);
+}
+
+struct ggnet_traceroute_req *
+ggnet_traceroute_trace(struct ggnet_traceroute *ggtr,
+ struct in_iddr *ip,
+ void (*cb_usr)(struct in_addr *, struct ggnet_traceroute_req *, void *),
+ void *data)
+{
+ struct ggnet_traceroute_req *req;
+
+ req = calloc(1, sizeof(struct ggnet_traceroute_req));
+ if (!req) {
+ printf("could not allocate ggnet_traceroute_req\n");
+ exit(1);
+ }
+
+ LIST_INSERT_HEAD(&ggtr->req_list, req, entry);
+ return req;
+}
+
+void
+ggnet_traceroute_cancel(struct ggnet_traceroute *ggtr,
+ struct ggnet_traceroute_req *req)
+{
+ LIST_REMOVE(req, entry);
+ ggtr->req_pending--;
+ free(req);
+}
diff --git a/libglouglou/libggnet_traceroute.h b/libglouglou/libggnet_traceroute.h
new file mode 100644
index 0000000..24aea02
--- /dev/null
+++ b/libglouglou/libggnet_traceroute.h
@@ -0,0 +1,39 @@
+#include <event2/dns.h>
+#include <event2/util.h>
+#include <event2/event.h>
+
+#if defined(__OpenBSD__)
+#include <sys/queue.h>
+#else
+#include <bsd/sys/queue.h>
+#endif
+
+struct ggnet_traceroute_hop {
+ LIST_ENTRY(ggnet_traceroute_hop) entry;
+ struct in_addr ip;
+ int delay;
+ int loss;
+};
+
+struct ggnet_traceroute_req {
+ LIST_ENTRY(ggnet_traceroute_req) entry;
+ struct event *ev;
+ LIST_HEAD(, ggnet_traceroute_hop) hops;
+ void (*cb_usr)(struct in_addr *, char *, void *);
+ void *data;
+};
+
+struct ggnet_traceroute {
+ struct event_base *ev_base;
+ int req_pending;
+ LIST_HEAD(, ggnet_traceroute_req) req_list; /* XXX for now unused. remove ? */
+};
+
+struct ggnet_traceroute *ggnet_traceroute_new(struct event_base *);
+void ggnet_traceroute_free(struct ggnet_dns *);
+struct ggnet_traceroute_req *ggnet_traceroute_trace(struct ggnet_traceroute *ggtr,
+ struct in_iddr *ip,
+ void (*cb_usr)(struct in_addr *, struct ggnet_traceroute_req *, void *),
+ void *data)
+void ggnet_traceroute_cancel(struct ggnet_traceroute *,
+ struct ggnet_traceroute_req *);