aboutsummaryrefslogtreecommitdiffstats
path: root/libglouglou
diff options
context:
space:
mode:
authorLaurent Ghigonis <laurent@p1sec.com>2013-07-06 02:27:56 +0200
committerLaurent Ghigonis <laurent@p1sec.com>2013-07-06 02:27:56 +0200
commit2b575ec093dcd84d8d5c816fe41dd5b7363228e6 (patch)
tree7f32e89871b99edb4e6556007d9515353a266b06 /libglouglou
parentgg_map: printf use %p for pointers (diff)
downloadglouglou-2b575ec093dcd84d8d5c816fe41dd5b7363228e6.tar.xz
glouglou-2b575ec093dcd84d8d5c816fe41dd5b7363228e6.zip
WIP traceroute integration, disabled by default
gg_map is not graphing correctly the route for now
Diffstat (limited to 'libglouglou')
-rw-r--r--libglouglou/libggnet.c68
-rw-r--r--libglouglou/libggnet.h37
-rw-r--r--libglouglou/libggnet_dns.c5
-rw-r--r--libglouglou/libglouglou.c40
-rw-r--r--libglouglou/libglouglou.h16
5 files changed, 161 insertions, 5 deletions
diff --git a/libglouglou/libggnet.c b/libglouglou/libggnet.c
index 832de54..5f9810b 100644
--- a/libglouglou/libggnet.c
+++ b/libglouglou/libggnet.c
@@ -4,6 +4,7 @@
#include "libggnet.h"
#include "libggnet_dns.h"
+#include "libggnet_traceroute.h"
static struct ggnet_nodegroup *
nodegroup_add(struct ggnet *,
@@ -17,6 +18,7 @@ static struct ggnet_nodegroup *
static void nodegroup_set(struct ggnet *, struct ggnet_node *);
static void nodegroup_unset(struct ggnet *, struct ggnet_node *);
static void _cb_dns_reverse(struct in_addr *, char *, void *);
+static void _cb_traceroute_trace(struct ggnet_traceroute_req *req, void *data);
struct ggnet *
ggnet_new(int manage_connid)
@@ -53,12 +55,25 @@ ggnet_set_grouping(struct ggnet *net, int set,
}
void
+ggnet_setcb_traceroute(struct ggnet *net,
+ void (*cb_link)(struct ggnet *,
+ struct ggnet_node *, struct ggnet_node *),
+ void (*cb_unlink)(struct ggnet *,
+ struct ggnet_node *, struct ggnet_node *))
+{
+ net->cb_traceroute_link = cb_link;
+ net->cb_traceroute_unlink = cb_unlink;
+}
+
+void
ggnet_set_dns(struct ggnet *net, int set,
struct event_base *ev_base,
void (*cb_nodename)(struct ggnet *, struct ggnet_node *))
{
+ printf("XXX ggnet_set_dns %d\n", set);
net->use_dns = set;
if (set) {
+ printf("XXX calling ggnet_dns_new\n");
net->ggdns = ggnet_dns_new(ev_base);
net->cb_nodename = cb_nodename;
}
@@ -67,6 +82,20 @@ ggnet_set_dns(struct ggnet *net, int set,
}
void
+ggnet_set_traceroute(struct ggnet *net, int set, char *iface,
+ struct event_base *ev_base,
+ void (*cb_traceroute)(struct ggnet *, struct ggnet_traceroute_req *))
+{
+ net->use_traceroute = set;
+ if (set) {
+ net->ggtraceroute = ggnet_traceroute_new(ev_base, iface, net->debug);
+ net->cb_traceroute = cb_traceroute;
+ }
+ else if (net->use_traceroute)
+ ggnet_traceroute_free(net->ggtraceroute);
+}
+
+void
ggnet_debug_set(struct ggnet *net, int set)
{
net->debug = set;
@@ -110,6 +139,12 @@ ggnet_node_add(struct ggnet *net, struct in_addr *addr)
nodegroup_set(net, n);
if (net->use_dns)
n->dns_req = ggnet_dns_reverse(net->ggdns, &n->addr, _cb_dns_reverse, n);
+ if (net->use_traceroute) {
+ struct addr ip;
+ addr_aton(inet_ntoa(*addr), &ip);
+ printf("XXX calling trace on %s\n", inet_ntoa(*addr));
+ n->traceroute_req = ggnet_traceroute_trace_tcp(net->ggtraceroute, &ip, 80, _cb_traceroute_trace, NULL, n);
+ }
return n;
}
@@ -163,6 +198,26 @@ ggnet_node_group_get(struct ggnet_node *n)
return n->group;
}
+int
+ggnet_node_path_link(struct ggnet_node *a, struct ggnet_node *b)
+{
+ if (b->path_parent) {
+ if (b->path_parent == a)
+ return 0; /* already path connected */
+ /* remove old path link */
+ LIST_REMOVE(b, entry_path);
+ b->path_parent = NULL;
+ if (a->net->cb_traceroute_unlink)
+ a->net->cb_traceroute_unlink(a->net, a, b);
+ }
+ LIST_INSERT_HEAD(&a->path_to, b, entry_path);
+ b->path_parent = a;
+ if (a->net->cb_traceroute_link)
+ a->net->cb_traceroute_link(a->net, a, b);
+
+ return 1;
+}
+
struct ggnet_conn *
ggnet_conn_add(struct ggnet *net, struct in_addr *src, int src_port,
struct in_addr *dst, int dst_port, int proto, int size,
@@ -487,6 +542,7 @@ _cb_dns_reverse(struct in_addr *ip, char *name, void *data)
struct ggnet *net;
struct ggnet_node *n;
+ printf("XXX _cb_dns_reverse %s\n", name);
n = data;
net = n->net;
n->dns_req = NULL;
@@ -496,3 +552,15 @@ _cb_dns_reverse(struct in_addr *ip, char *name, void *data)
}
}
+static void
+_cb_traceroute_trace(struct ggnet_traceroute_req *req, void *data)
+{
+ struct ggnet *net;
+ struct ggnet_node *n;
+
+ printf("XXX _cb_traceroute_trace %p\n", req);
+ n = data;
+ net = n->net;
+ n->traceroute_req = NULL;
+ net->cb_traceroute(net, req);
+}
diff --git a/libglouglou/libggnet.h b/libglouglou/libggnet.h
index 794639b..fecf2bb 100644
--- a/libglouglou/libggnet.h
+++ b/libglouglou/libggnet.h
@@ -14,6 +14,8 @@
#include <bsd/sys/queue.h>
#endif
+#include "libggnet_traceroute.h"
+
#define GGNET_DNSNAME_MAX 60
#define GGNET_CONN_FREEIDS_COUNT 65536 /* 2^16 as freeids are u_int16_t */
@@ -43,13 +45,17 @@ struct ggnet_nodegroup {
struct ggnet_node {
LIST_ENTRY(ggnet_node) entry;
+ LIST_ENTRY(ggnet_node) entry_path;
struct ggnet *net;
struct in_addr addr;
+ LIST_HEAD(, ggnet_node) path_to; /* traceroute childs */
+ struct ggnet_node *path_parent; /* traceroute parent */
time_t lastseen;
- int used;
+ int used; /* by ggnet_conn */
+ struct ggnet_nodegroup *group; /* XXX for now only one group */
char fqdn[GGNET_DNSNAME_MAX];
- struct ggnet_nodegroup *group; /* XXX for now we support only one group */
struct ggnet_dns_req *dns_req;
+ struct ggnet_traceroute_req *traceroute_req;
void *usrdata;
};
@@ -82,7 +88,7 @@ struct ggnet {
int node_count;
u_int16_t conn_freeids[GGNET_CONN_FREEIDS_COUNT];
int conn_freeids_ptr;
- int manage_connid;
+ int manage_connid; /* XXX rename to active / passive */
time_t time;
int debug;
/* grouping */
@@ -93,6 +99,18 @@ struct ggnet {
int use_dns;
struct ggnet_dns *ggdns;
void (*cb_nodename)(struct ggnet *, struct ggnet_node *);
+ /* traceroute */
+ int use_traceroute;
+ struct ggnet_traceroute *ggtraceroute;
+ void (*cb_traceroute)(struct ggnet *, struct ggnet_traceroute_req *);
+ /* traceroute callbacks */
+ void (*cb_traceroute_link)(struct ggnet *,
+ struct ggnet_node *,
+ struct ggnet_node *);
+ void (*cb_traceroute_unlink)(struct ggnet *,
+ struct ggnet_node *,
+ struct ggnet_node *);
+
};
struct ggnet *ggnet_new(int);
@@ -102,10 +120,21 @@ void ggnet_set_grouping(struct ggnet *, int,
struct ggnet_nodegroup *),
void (*cb_delgroup)(struct ggnet *,
struct ggnet_nodegroup *));
+void ggnet_setcb_traceroute(struct ggnet *,
+ void (*cb_link)(struct ggnet *,
+ struct ggnet_node *,
+ struct ggnet_node *),
+ void (*cb_unlink)(struct ggnet *,
+ struct ggnet_node *,
+ struct ggnet_node *));
void ggnet_set_dns(struct ggnet *net, int set,
struct event_base *ev_base,
void (*cb_nodename)(struct ggnet *,
struct ggnet_node *));
+void ggnet_set_traceroute(struct ggnet *, int, char *,
+ struct event_base *,
+ void (*cb_traceroute)(struct ggnet *,
+ struct ggnet_traceroute_req *));
void ggnet_debug_set(struct ggnet *, int);
void ggnet_free(struct ggnet *);
struct ggnet_node *ggnet_node_add(struct ggnet *, struct in_addr *);
@@ -114,6 +143,8 @@ struct ggnet_node *ggnet_node_find(struct ggnet *, struct in_addr *);
void *ggnet_node_usrdata_get(struct ggnet_node *);
void ggnet_node_usrdata_set(struct ggnet_node *, void *);
struct ggnet_nodegroup *ggnet_node_group_get(struct ggnet_node *);
+int ggnet_node_path_link(struct ggnet_node *a,
+ struct ggnet_node *b);
struct ggnet_conn *ggnet_conn_add(struct ggnet *, struct in_addr *, int,
struct in_addr *, int, int, int, int);
void ggnet_conn_data(struct ggnet *, struct ggnet_conn *,
diff --git a/libglouglou/libggnet_dns.c b/libglouglou/libggnet_dns.c
index c6f8cce..66292b1 100644
--- a/libglouglou/libggnet_dns.c
+++ b/libglouglou/libggnet_dns.c
@@ -18,6 +18,8 @@ ggnet_dns_new(struct event_base *ev_base)
{
struct ggnet_dns *ggdns = NULL;
+ printf("XXX ggnet_dns_new\n");
+
ggdns = calloc(1, sizeof(struct ggnet_dns));
if (!ggdns) {
printf("could not allocate ggnet_dns\n");
@@ -53,6 +55,8 @@ ggnet_dns_reverse(struct ggnet_dns *ggdns,
struct evdns_request *ereq;
struct in_addr nip;
+ printf("XXX ggnet_dns_reverse %d\n", ip->s_addr);
+
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_flags = EVUTIL_AI_CANONNAME;
@@ -105,6 +109,7 @@ _cb_evdns_reverse(int result, char type, int count,
req = arg;
name = addresses;
+ printf("XXX _cb_evdns_reverse %p\n", name);
if (result != DNS_ERR_NONE || count == 0)
req->cb_usr(&req->ip, NULL, req->data);
else
diff --git a/libglouglou/libglouglou.c b/libglouglou/libglouglou.c
index f702d2a..9f41313 100644
--- a/libglouglou/libglouglou.c
+++ b/libglouglou/libglouglou.c
@@ -50,6 +50,8 @@ gg_packet_props_t gg_packet_props[] = {
{ (PACKET_HEADER_SIZE + sizeof((struct gg_packet *)0)->pdat.data) },
[PACKET_NAME] = \
{ ((PACKET_HEADER_SIZE + sizeof((struct gg_packet *)0)->pdat.name) - GG_PKTARG_MAX) },
+ [PACKET_TRACE] = \
+ { ((PACKET_HEADER_SIZE + sizeof((struct gg_packet *)0)->pdat.trace) - (sizeof(struct gg_packet_tracehop) * GG_PKTARG_MAX)) },
[PACKET_FORK] = \
{ (PACKET_HEADER_SIZE + sizeof((struct gg_packet *)0)->pdat.fork) },
[PACKET_EXEC] = \
@@ -514,8 +516,7 @@ pkt_decode(char **buf, int *buf_len)
{
static struct gg_packet newpkt;
struct gg_packet *pkt;
- int len;
- int packet_len;
+ int i, len, packet_len;
len = *buf_len;
@@ -566,6 +567,22 @@ pkt_decode(char **buf, int *buf_len)
strncpy((char *)newpkt.name_fqdn, (char *)pkt->name_fqdn,
newpkt.name_len);
break;
+ case PACKET_TRACE:
+ newpkt.trace_addr = ntohl(pkt->trace_addr);
+ newpkt.trace_hopcount = pkt->trace_hopcount;
+ if (newpkt.trace_hopcount > GG_PKTARG_MAX)
+ invalid("type trace hopcount");
+ packet_len = packet_len \
+ + newpkt.trace_hopcount * sizeof(struct gg_packet_tracehop);
+ if (len < packet_len)
+ goto incomplete;
+ for (i=0; i<newpkt.trace_hopcount; i++) {
+ newpkt.trace_hops[i].addr = ntohl(pkt->trace_hops[i].addr);
+ newpkt.trace_hops[i].delay = ntohs(pkt->trace_hops[i].delay);
+ newpkt.trace_hops[i].loss = pkt->trace_hops[i].loss;
+ newpkt.trace_hops[i].asn = pkt->trace_hops[i].asn;
+ }
+ break;
case PACKET_FORK:
newpkt.fork_pid = ntohl(pkt->fork_pid);
newpkt.fork_ppid = ntohl(pkt->fork_ppid);
@@ -615,6 +632,8 @@ invalid:
int
pkt_encode(struct gg_packet *pkt, struct gg_packet *newpkt)
{
+ int i;
+
if (pkt->type < PACKET_TYPE_MIN || pkt->type > PACKET_TYPE_MAX)
invalid("type");
@@ -643,6 +662,18 @@ pkt_encode(struct gg_packet *pkt, struct gg_packet *newpkt)
strncpy((char *)newpkt->name_fqdn, (char *)pkt->name_fqdn,
pkt->name_len);
break;
+ case PACKET_TRACE:
+ if (pkt->trace_hopcount > GG_PKTARG_MAX)
+ goto invalid;
+ newpkt->trace_addr = htonl(pkt->trace_addr);
+ newpkt->trace_hopcount = pkt->trace_hopcount;
+ for (i=0; i<newpkt->trace_hopcount; i++) {
+ newpkt->trace_hops[i].addr = htonl(pkt->trace_hops[i].addr);
+ newpkt->trace_hops[i].delay = htons(pkt->trace_hops[i].delay);
+ newpkt->trace_hops[i].loss = pkt->trace_hops[i].loss;
+ newpkt->trace_hops[i].asn = pkt->trace_hops[i].asn;
+ }
+ break;
case PACKET_FORK:
newpkt->fork_pid = htonl(pkt->fork_pid);
newpkt->fork_ppid = htonl(pkt->fork_ppid);
@@ -691,6 +722,11 @@ pkt_getsize(struct gg_packet *pkt)
goto invalid;
packet_len = packet_len + pkt->name_len;
break;
+ case PACKET_TRACE:
+ if (pkt->trace_hopcount > GG_PKTARG_MAX)
+ goto invalid;
+ packet_len = packet_len + pkt->trace_hopcount * sizeof(struct gg_packet_tracehop);
+ break;
case PACKET_EXEC:
if (pkt->exec_cmdlen > GG_PKTARG_MAX)
goto invalid;
diff --git a/libglouglou/libglouglou.h b/libglouglou/libglouglou.h
index fb755a7..ac57595 100644
--- a/libglouglou/libglouglou.h
+++ b/libglouglou/libglouglou.h
@@ -35,11 +35,19 @@ enum gg_packet_type { /* u_int8_t */
PACKET_DELCONN = 0x01,
PACKET_DATA = 0x02,
PACKET_NAME = 0x03,
+ PACKET_TRACE = 0x04,
PACKET_FORK = 0x10,
PACKET_EXEC = 0x11,
PACKET_EXIT = 0x12,
};
+struct __attribute__((packed)) gg_packet_tracehop {
+ u_int32_t addr;
+ u_int16_t delay;
+ u_int8_t loss;
+ u_int8_t asn;
+};
+
/* XXX is packed needed everywhere ? */
struct __attribute__((packed)) gg_packet {
u_int8_t ver;
@@ -64,6 +72,11 @@ struct __attribute__((packed)) gg_packet {
u_int8_t len;
u_char fqdn[GG_PKTARG_MAX];
} name;
+ struct __attribute__((packed)) trace {
+ u_int32_t addr;
+ u_int8_t hopcount;
+ struct gg_packet_tracehop hops[GG_PKTARG_MAX];
+ } trace;
struct __attribute__((packed)) fork {
u_int32_t pid;
u_int32_t ppid;
@@ -92,6 +105,9 @@ struct __attribute__((packed)) gg_packet {
#define name_addr pdat.name.addr
#define name_len pdat.name.len
#define name_fqdn pdat.name.fqdn
+#define trace_addr pdat.trace.addr
+#define trace_hopcount pdat.trace.hopcount
+#define trace_hops pdat.trace.hops
#define fork_pid pdat.fork.pid
#define fork_ppid pdat.fork.ppid
#define fork_cpid pdat.fork.cpid