From 2b575ec093dcd84d8d5c816fe41dd5b7363228e6 Mon Sep 17 00:00:00 2001 From: Laurent Ghigonis Date: Sat, 6 Jul 2013 02:27:56 +0200 Subject: WIP traceroute integration, disabled by default gg_map is not graphing correctly the route for now --- libglouglou/libggnet.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++ libglouglou/libggnet.h | 37 +++++++++++++++++++++++-- libglouglou/libggnet_dns.c | 5 ++++ libglouglou/libglouglou.c | 40 +++++++++++++++++++++++++-- libglouglou/libglouglou.h | 16 +++++++++++ 5 files changed, 161 insertions(+), 5 deletions(-) (limited to 'libglouglou') 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) @@ -52,13 +54,26 @@ ggnet_set_grouping(struct ggnet *net, int set, net->cb_delgroup = cb_delgroup; } +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; } @@ -66,6 +81,20 @@ ggnet_set_dns(struct ggnet *net, int set, ggnet_dns_free(net->ggdns); } +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) { @@ -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 #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; itrace_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; itrace_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 -- cgit v1.2.3-59-g8ed1b