diff options
author | Laurent Ghigonis <laurent@p1sec.com> | 2013-07-09 11:45:00 +0200 |
---|---|---|
committer | Laurent Ghigonis <laurent@p1sec.com> | 2013-07-09 11:45:00 +0200 |
commit | 07306a2a00c908979fbb8cf3127278bae00803a4 (patch) | |
tree | 91c84a1d7f1402f1c2b7833a90b5ff1d245eae5b | |
parent | fix segfault because of bad libdnet intf_get_dst() usage (diff) | |
download | glouglou-07306a2a00c908979fbb8cf3127278bae00803a4.tar.xz glouglou-07306a2a00c908979fbb8cf3127278bae00803a4.zip |
WIP, improve traceroute
* del trace on timeout (still WIP)
* keep track of nodes traceroute usage
* fix IP address storage / transfer
* add some debug printf around
-rw-r--r-- | gg_map/gg_map.c | 91 | ||||
-rw-r--r-- | gg_sniff/pcap.c | 12 | ||||
-rw-r--r-- | libglouglou/libggnet.c | 28 | ||||
-rw-r--r-- | libglouglou/libggnet.h | 4 | ||||
-rw-r--r-- | libglouglou/libggnet_traceroute.c | 2 | ||||
-rw-r--r-- | libglouglou/libglouglou.c | 24 |
6 files changed, 108 insertions, 53 deletions
diff --git a/gg_map/gg_map.c b/gg_map/gg_map.c index 3fbc329..73a5068 100644 --- a/gg_map/gg_map.c +++ b/gg_map/gg_map.c @@ -57,7 +57,7 @@ _cb_ggnet_addgroup(struct ggnet *net, struct ggnet_nodegroup *group, { Egraph_Vertice *vgroup; - vgroup = egraph_group_add(_egraph, ip_to_str(group->addr.s_addr), group); + vgroup = egraph_group_add(_egraph, inet_ntoa(group->addr), group); ggnet_nodegroup_usrdata_set(group, vgroup); if (parent) egraph_group_vertice_attach(_egraph, vgroup, @@ -112,7 +112,8 @@ _node_to_vertice(struct ggnet_node *n) v = ggnet_node_usrdata_get(n); if (!v) { - v = egraph_vertice_add(_egraph, ip_to_str(n->addr.s_addr), n); + + v = egraph_vertice_add(_egraph, inet_ntoa(n->addr), n); ggnet_node_usrdata_set(n, v); group = ggnet_node_group_get(n); if (group) @@ -177,7 +178,7 @@ _conn_add(u_int id, u_int src, u_int dst, u_int proto, u_int8_t pktsize) e = egraph_edge_find(_egraph, va, vb); if (_loglevel >= 2) printf("_conn_add: a %d b %d e %p id %d\n", va->id, vb->id, e, id); - if (!e) { + if (!e && !egraph_edge_find(_egraph, va, vb)) { if (a->group && a->group->conn_count == 1) _node_detach_parentgroup(a); if (b->group && b->group->conn_count == 1) @@ -186,7 +187,33 @@ _conn_add(u_int id, u_int src, u_int dst, u_int proto, u_int8_t pktsize) if (_loglevel >= 2) printf("_conn_add: egraph edge added %p\n", e); } - ggnet_conn_usrdata_set(conn, e); + if (e) + ggnet_conn_usrdata_set(conn, e); +} + +static void +_del_trace(struct ggnet_node *a, struct ggnet_node *b) +{ + struct ggnet_node *n, *np; + Egraph_Vertice *va, *vb; + Egraph_Edge *e; + + n = b; + while ((np = n->path_parent)) { + if (np->used_traceroute > 0 && np->used_conn == 0) { + np->used_traceroute--; + if (np->used_traceroute == 0) { + va = ggnet_node_usrdata_get(np); + vb = ggnet_node_usrdata_get(n); + e = egraph_edge_find(_egraph, va, vb); + if (e) // XXX IN PROGRESS REMOVE but SEGV + egraph_edge_del(_egraph, e); + egraph_vertice_del(_egraph, va); + ggnet_node_usrdata_set(np, NULL); + } + } + n = np; + } } static void @@ -210,7 +237,12 @@ _conn_del(int id) { // a vertice without edge ... if (_loglevel >= 2) printf("_conn_del: edge del %p\n", e); // XXX - egraph_edge_del(_egraph, e); + if (b->path_parent) + _del_trace(a, b); + else { + egraph_edge_del(_egraph, e); + ggnet_conn_usrdata_set(conn, NULL); + } if (a->group && a->group->conn_count == 0) _node_attach_parentgroup(a); if (b->group && b->group->conn_count == 0) @@ -268,15 +300,18 @@ _node_link_next(struct ggnet_node *np, struct in_addr *ip) Egraph_Vertice *v; n = ggnet_node_find(_ggnet, ip); - if (!n) { - n = ggnet_node_add(_ggnet, ip, 0); - v = _node_to_vertice(n); - if (v) - egraph_vertice_type_set(_egraph, v, - "vertice_alt1"); - else - printf("gg_map: ERROR: could not create trace vertice !\n"); - } + if (np == n) + return n; + if (!n) + n = ggnet_node_add(_ggnet, ip, 1); + else if (n->used_traceroute > 0) + n->used_traceroute++; + v = _node_to_vertice(n); + if (v) + egraph_vertice_type_set(_egraph, v, + "vertice_alt1"); + else + printf("gg_map: ERROR: could not create trace vertice !\n"); ggnet_node_path_link(np, n); return n; } @@ -284,23 +319,37 @@ _node_link_next(struct ggnet_node *np, struct in_addr *ip) static void _conn_trace(u_int32_t addr, u_int32_t src, u_int8_t hopcount, struct gg_packet *pkt) { struct gg_packet_tracehop *h; - struct ggnet_node *n; + struct ggnet_node *a, *b, *n; + struct ggnet_conn *conn; struct in_addr ip; + Egraph_Edge *e; int i; + /* look for direct link between a and b */ ip.s_addr = src; - printf("XXX ==== SRC %x\n", src); - n = ggnet_node_find(_ggnet, &ip); - printf("XXX ==== SRC node %p\n", n); - if (!n) - return; + a = ggnet_node_find(_ggnet, &ip); + if (!a) return; + ip.s_addr = addr; + b = ggnet_node_find(_ggnet, &ip); + if (b) { + conn = ggnet_conn_find_by_node(_ggnet, a, b); + e = egraph_edge_find(_egraph, ggnet_node_usrdata_get(a), + ggnet_node_usrdata_get(b)); + if (e) { + printf("XXX remove direct edge !\n"); + /* remove direct link now that we have traceroute */ + egraph_edge_del(_egraph, e); + ggnet_conn_usrdata_set(conn, NULL); + } + } + /* build traceroute path between a and b */ + n = a; for (i=0; i<hopcount; i++) { h = &pkt->trace_hops[i]; ip.s_addr = h->addr; n = _node_link_next(n, &ip); } - ip.s_addr = addr; n = _node_link_next(n, &ip); } diff --git a/gg_sniff/pcap.c b/gg_sniff/pcap.c index 5a247d6..c80085d 100644 --- a/gg_sniff/pcap.c +++ b/gg_sniff/pcap.c @@ -144,7 +144,7 @@ ggsniff_pcap_init(struct event_base *ev_base, struct gg_client *ggcli, ggnet_set_dns(net, 1, ev_base, cb_nodename); // XXX IN PROGRESS traceroute, disabled for now, 20130705 // laurent - //ggnet_set_traceroute(net, 1, iface, ev_base, cb_nodetraceroute); + ggnet_set_traceroute(net, 1, iface, ev_base, cb_nodetraceroute); } _cap.ggcli = ggcli; @@ -327,7 +327,7 @@ cb_conntimer(int fd, short why, void *data) if (_cap.net->node_count > NODE_MAX_WITHOUT_TIMEOUT) { LIST_FOREACH_SAFE(n, &_cap.net->node_list, entry, ntmp) { - if (n->used == 0 && + if (n->used_conn == 0 && _cap.net->time > n->lastseen + NODE_TIMEOUT) ggnet_node_del(_cap.net, n); } @@ -372,6 +372,7 @@ cb_nodetraceroute(struct ggnet *net, struct ggnet_traceroute_req *req) pkt.trace_addr = req->target->ip.addr_ip; pkt.trace_src = req->srcip.addr_ip; printf("XXX oooooooooooooooooo %x\n", pkt.trace_addr); + printf("XXX oooooooooooooooooo %x\n", pkt.trace_src); pkt.trace_hopcount = req->hopcount_answering; i = 0; TAILQ_FOREACH(h, &req->hops_list, entry) { @@ -379,7 +380,7 @@ cb_nodetraceroute(struct ggnet *net, struct ggnet_traceroute_req *req) //pkt.trace_hops[i].addr = ip.s_addr; if (h->ip.addr_ip == 0) continue; - pkt.trace_hops[i].addr = ntohl(h->ip.addr_ip); + pkt.trace_hops[i].addr = h->ip.addr_ip; printf("XXX ------------------- %x\n", pkt.trace_hops[i].addr); pkt.trace_hops[i].delay = h->delay; pkt.trace_hops[i].loss = h->loss; @@ -443,8 +444,9 @@ ip_handle(struct ip *ip, const u_char *pend, u_int wirelen) } len -= ip_hlen; - src.s_addr = ntohl(ip->ip_src.s_addr); - dst.s_addr = ntohl(ip->ip_dst.s_addr); + memcpy(&src, &ip->ip_src, sizeof(struct in_addr)); + memcpy(&dst, &ip->ip_dst, sizeof(struct in_addr)); + printf("XXX %s (%d) -> %s (%d)\n", inet_ntoa(src), src.s_addr, inet_ntoa(dst), dst.s_addr); src_port = 0; dst_port = 0; proto = IPPROTO_IP; diff --git a/libglouglou/libggnet.c b/libglouglou/libggnet.c index 160ac8b..0666041 100644 --- a/libglouglou/libggnet.c +++ b/libglouglou/libggnet.c @@ -118,7 +118,7 @@ ggnet_free(struct ggnet *net) } struct ggnet_node * -ggnet_node_add(struct ggnet *net, struct in_addr *addr, int allow_grouping) +ggnet_node_add(struct ggnet *net, struct in_addr *addr, int traceroute_node) { struct ggnet_node *n; @@ -130,20 +130,22 @@ ggnet_node_add(struct ggnet *net, struct in_addr *addr, int allow_grouping) printf("could not allocate node\n"); exit(1); } + printf("XXX n=%p\n", n); n->net = net; n->addr.s_addr = addr->s_addr; n->lastseen = net->time; - //n->allow_grouping = allow_grouping; XXX IN PROGRESS why segfault ?? + n->used_traceroute = traceroute_node; // XXX IN PROGRESS why segfault ? LIST_INSERT_HEAD(&net->node_list, n, entry); net->node_count++; - if (net->use_grouping && allow_grouping) + if (net->use_grouping && !traceroute_node) 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 %x\n", ip.addr_ip); + printf("XXX calling trace on %x - %s - %x - %s\n", addr->s_addr, inet_ntoa(*addr), ip.addr_ip, addr_ntoa(&ip)); + printf("XXX n=%p\n", n); n->traceroute_req = ggnet_traceroute_trace_tcp(net->ggtraceroute, &ip, 80, _cb_traceroute_trace, NULL, n); } @@ -153,7 +155,7 @@ ggnet_node_add(struct ggnet *net, struct in_addr *addr, int allow_grouping) void ggnet_node_del(struct ggnet *net, struct ggnet_node *n) { - if (n->used) { + if (n->used_conn || n->used_traceroute) { printf("FATAL: ggnet_node_del: trying to remove a used node !\n"); exit(1); } @@ -246,14 +248,14 @@ ggnet_conn_add(struct ggnet *net, struct in_addr *src, int src_port, srcnode = ggnet_node_find(net, src); if (!srcnode) - srcnode = ggnet_node_add(net, src, 1); - srcnode->used++; + srcnode = ggnet_node_add(net, src, 0); + srcnode->used_conn++; if (srcnode->group) srcnode->group->conn_count++; dstnode = ggnet_node_find(net, dst); if (!dstnode) - dstnode = ggnet_node_add(net, dst, 1); - dstnode->used++; + dstnode = ggnet_node_add(net, dst, 0); + dstnode->used_conn++; if (dstnode->group) dstnode->group->conn_count++; @@ -323,10 +325,10 @@ ggnet_conn_del(struct ggnet *net, struct ggnet_conn *c) net->conn_freeids[net->conn_freeids_ptr] = c->id; } - c->src->used--; + c->src->used_conn--; if (c->src->group) c->src->group->conn_count--; - c->dst->used--; + c->dst->used_conn--; if (c->dst->group) c->dst->group->conn_count--; @@ -507,7 +509,7 @@ nodegroup_set(struct ggnet *net, struct ggnet_node *n) struct ggnet_nodegroup *group, *groot, *gclassb; u_int addr, addr2; - addr = n->addr.s_addr & 0xffff0000; + addr = n->addr.s_addr & 0x0000ffff; group = nodegroup_find(net, GROUP_ADDRESS, &addr); if (!group) { @@ -515,7 +517,7 @@ nodegroup_set(struct ggnet *net, struct ggnet_node *n) groot = nodegroup_find(net, GROUP_ADDRESS, &addr2); if (!groot) groot = nodegroup_add(net, GROUP_ADDRESS, &addr2, NULL); - addr2 = addr & 0xff000000; + addr2 = addr & 0x000000ff; gclassb = nodegroup_find(net, GROUP_ADDRESS, &addr2); if (!gclassb) gclassb = nodegroup_add(net, GROUP_ADDRESS, &addr2, groot); diff --git a/libglouglou/libggnet.h b/libglouglou/libggnet.h index 95d27d6..d855560 100644 --- a/libglouglou/libggnet.h +++ b/libglouglou/libggnet.h @@ -48,11 +48,11 @@ struct ggnet_node { LIST_ENTRY(ggnet_node) entry_path; struct ggnet *net; struct in_addr addr; + int used_conn; + int used_traceroute; LIST_HEAD(, ggnet_node) path_to; /* traceroute childs */ struct ggnet_node *path_parent; /* traceroute parent */ time_t lastseen; - int used; /* by ggnet_conn */ - int allow_grouping; struct ggnet_nodegroup *group; /* XXX for now only one group */ char fqdn[GGNET_DNSNAME_MAX]; struct ggnet_dns_req *dns_req; diff --git a/libglouglou/libggnet_traceroute.c b/libglouglou/libggnet_traceroute.c index 6003175..8934765 100644 --- a/libglouglou/libggnet_traceroute.c +++ b/libglouglou/libggnet_traceroute.c @@ -245,6 +245,8 @@ ggnet_traceroute_trace(struct ggnet_traceroute *ggtr, struct addr *ip, LIST_INSERT_HEAD(&ggtr->req_list, req, entry); ggtr->req_pending++; + + printf("XXX data=%p\n", data); return req; err: diff --git a/libglouglou/libglouglou.c b/libglouglou/libglouglou.c index d17137a..22efa8e 100644 --- a/libglouglou/libglouglou.c +++ b/libglouglou/libglouglou.c @@ -544,8 +544,8 @@ pkt_decode(char **buf, int *buf_len) switch(pkt->type) { case PACKET_NEWCONN: newpkt.newconn_id = ntohs(pkt->newconn_id); - newpkt.newconn_src = ntohl(pkt->newconn_src); - newpkt.newconn_dst = ntohl(pkt->newconn_dst); + newpkt.newconn_src = pkt->newconn_src; + newpkt.newconn_dst = pkt->newconn_dst; newpkt.newconn_proto = pkt->newconn_proto; newpkt.newconn_size = pkt->newconn_size; break; @@ -557,7 +557,7 @@ pkt_decode(char **buf, int *buf_len) newpkt.data_size = pkt->data_size; break; case PACKET_NAME: - newpkt.name_addr = ntohl(pkt->name_addr); + newpkt.name_addr = pkt->name_addr; newpkt.name_len = pkt->name_len; if (newpkt.name_len > GG_PKTARG_MAX) invalid("type name name_len"); @@ -568,8 +568,8 @@ pkt_decode(char **buf, int *buf_len) newpkt.name_len); break; case PACKET_TRACE: - newpkt.trace_addr = ntohl(pkt->trace_addr); - newpkt.trace_src = ntohl(pkt->trace_src); + newpkt.trace_addr = pkt->trace_addr; + newpkt.trace_src = pkt->trace_src; newpkt.trace_hopcount = pkt->trace_hopcount; if (newpkt.trace_hopcount > GG_PKTARG_MAX) invalid("type trace hopcount"); @@ -578,7 +578,7 @@ pkt_decode(char **buf, int *buf_len) 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].addr = 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; @@ -643,8 +643,8 @@ pkt_encode(struct gg_packet *pkt, struct gg_packet *newpkt) switch(pkt->type) { case PACKET_NEWCONN: newpkt->newconn_id = htons(pkt->newconn_id); - newpkt->newconn_src = htonl(pkt->newconn_src); - newpkt->newconn_dst = htonl(pkt->newconn_dst); + newpkt->newconn_src = pkt->newconn_src; + newpkt->newconn_dst = pkt->newconn_dst; newpkt->newconn_proto = pkt->newconn_proto; newpkt->newconn_size = pkt->newconn_size; break; @@ -658,7 +658,7 @@ pkt_encode(struct gg_packet *pkt, struct gg_packet *newpkt) case PACKET_NAME: if (pkt->name_len > GG_PKTARG_MAX) goto invalid; - newpkt->name_addr = htonl(pkt->name_addr); + newpkt->name_addr = pkt->name_addr; newpkt->name_len = pkt->name_len; strncpy((char *)newpkt->name_fqdn, (char *)pkt->name_fqdn, pkt->name_len); @@ -666,11 +666,11 @@ pkt_encode(struct gg_packet *pkt, struct gg_packet *newpkt) case PACKET_TRACE: if (pkt->trace_hopcount > GG_PKTARG_MAX) goto invalid; - newpkt->trace_addr = htonl(pkt->trace_addr); - newpkt->trace_src = htonl(pkt->trace_src); + newpkt->trace_addr = pkt->trace_addr; + newpkt->trace_src = pkt->trace_src; 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].addr = 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; |