aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Ghigonis <laurent@p1sec.com>2013-07-09 11:45:00 +0200
committerLaurent Ghigonis <laurent@p1sec.com>2013-07-09 11:45:00 +0200
commit07306a2a00c908979fbb8cf3127278bae00803a4 (patch)
tree91c84a1d7f1402f1c2b7833a90b5ff1d245eae5b
parentfix segfault because of bad libdnet intf_get_dst() usage (diff)
downloadglouglou-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.c91
-rw-r--r--gg_sniff/pcap.c12
-rw-r--r--libglouglou/libggnet.c28
-rw-r--r--libglouglou/libggnet.h4
-rw-r--r--libglouglou/libggnet_traceroute.c2
-rw-r--r--libglouglou/libglouglou.c24
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;