aboutsummaryrefslogtreecommitdiffstats
path: root/libglouglou/libggnet.c
diff options
context:
space:
mode:
authorLaurent Ghigonis <laurent@p1sec.com>2012-12-13 15:43:29 +0100
committerLaurent Ghigonis <laurent@p1sec.com>2012-12-13 15:43:29 +0100
commit4dcf36c3ead23b05e61ad41203c4743d59ccf18a (patch)
treecd81d3b25d90d5f47dc249452e53be0edcd1faed /libglouglou/libggnet.c
parentmore DEBUG backtrace stuff (diff)
downloadglouglou-4dcf36c3ead23b05e61ad41203c4743d59ccf18a.tar.xz
glouglou-4dcf36c3ead23b05e61ad41203c4743d59ccf18a.zip
introducing node grouping, for now only on address
Diffstat (limited to 'libglouglou/libggnet.c')
-rw-r--r--libglouglou/libggnet.c125
1 files changed, 125 insertions, 0 deletions
diff --git a/libglouglou/libggnet.c b/libglouglou/libggnet.c
index 9c6314e..480eb22 100644
--- a/libglouglou/libggnet.c
+++ b/libglouglou/libggnet.c
@@ -4,6 +4,12 @@
#include "libglouglou.h"
#include "libggnet.h"
+static struct ggnet_nodegroup *nodegroup_add(struct ggnet *,
+ enum ggnet_grouptype, void *);
+static void nodegroup_del(struct ggnet *, struct ggnet_nodegroup *);
+static void nodegroup_set(struct ggnet *, struct ggnet_node *);
+static void nodegroup_unset(struct ggnet *, struct ggnet_node *);
+
struct ggnet *
ggnet_new(int manage_connid)
{
@@ -19,16 +25,34 @@ ggnet_new(int manage_connid)
return net;
}
+/**
+ * Sets grouping option
+ *
+ * Note: Must be set before any use of ggnet
+ */
+void
+ggnet_grouping_set(struct ggnet *net, int set,
+ void (*cb_addgroup)(struct ggnet *, struct ggnet_nodegroup *),
+ void (*cb_delgroup)(struct ggnet *, struct ggnet_nodegroup *))
+{
+ net->use_grouping = set;
+ net->cb_addgroup = cb_addgroup;
+ net->cb_delgroup = cb_delgroup;
+}
+
void
ggnet_free(struct ggnet *net)
{
struct ggnet_conn *c, *ctmp;
struct ggnet_node *n, *ntmp;
+ struct ggnet_nodegroup *g, *gtmp;
LIST_FOREACH_SAFE(c, &net->conn_list, entry, ctmp)
ggnet_conn_del(net, c);
LIST_FOREACH_SAFE(n, &net->node_list, entry, ntmp)
ggnet_node_del(net, n);
+ LIST_FOREACH_SAFE(g, &net->group_list, entry, gtmp)
+ nodegroup_del(net, g);
free(net);
}
@@ -45,6 +69,8 @@ ggnet_node_add(struct ggnet *net, struct in_addr *addr)
n->lastseen = net->time;
LIST_INSERT_HEAD(&net->node_list, n, entry);
net->node_count++;
+ if (net->use_grouping)
+ nodegroup_set(net, n);
return n;
}
@@ -56,6 +82,9 @@ ggnet_node_del(struct ggnet *net, struct ggnet_node *n)
gg_log_fatal("ggnet_node_del: trying to remove a used node !");
gg_log_debug("ggnet_node_del: ggnet_node_del");
+ if (net->use_grouping)
+ nodegroup_unset(net, n);
+
LIST_REMOVE(n, entry);
free(n);
net->node_count--;
@@ -99,6 +128,12 @@ ggnet_node_usrdata_set(struct ggnet_node *n, void *usrdata)
n->usrdata = usrdata;
}
+struct ggnet_nodegroup *
+ggnet_node_group_get(struct ggnet_node *n)
+{
+ return n->group;
+}
+
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,
@@ -168,6 +203,7 @@ ggnet_conn_del(struct ggnet *net, struct ggnet_conn *c)
{
gg_log_debug("ggnet_conn_del");
+ /* UNSUPPORTED
if (c->proto == IPPROTO_TCP) {
switch (c->state) {
case CONNSTATE_ESTABLISHED:
@@ -180,6 +216,7 @@ ggnet_conn_del(struct ggnet *net, struct ggnet_conn *c)
break;
}
}
+ */
if (net->manage_connid) {
if (net->conn_freeids_ptr == 0)
@@ -269,8 +306,96 @@ ggnet_conn_dst_get(struct ggnet_conn *c)
return c->dst;
}
+void *
+ggnet_nodegroup_usrdata_get(struct ggnet_nodegroup *g)
+{
+ return g->usrdata;
+}
+
+void
+ggnet_nodegroup_usrdata_set(struct ggnet_nodegroup *g, void *usrdata)
+{
+ g->usrdata = usrdata;
+}
+
void
ggnet_time_update(struct ggnet *net, time_t time)
{
net->time = time;
}
+
+static struct ggnet_nodegroup *
+nodegroup_add(struct ggnet *net, enum ggnet_grouptype type, void *param)
+{
+ struct ggnet_nodegroup *group;
+
+ group = xcalloc(1, sizeof(struct ggnet_nodegroup));
+ group->type = type;
+
+ switch (type) {
+ case GROUP_ADDRESS:
+ group->addr.s_addr = *(u_int *)param;
+ break;
+ case GROUP_WHOIS:
+ case GROUP_DNS:
+ case GROUP_ROUTE:
+ /* UNSUPPORTED */
+ free(group);
+ return NULL;
+ }
+
+ LIST_INSERT_HEAD(&net->group_list, group, entry);
+ net->cb_addgroup(net, group);
+
+ return group;
+}
+
+static void
+nodegroup_del(struct ggnet *net, struct ggnet_nodegroup *group)
+{
+ net->cb_delgroup(net, group);
+ LIST_REMOVE(group, entry);
+ free(group);
+}
+
+static void
+nodegroup_set(struct ggnet *net, struct ggnet_node *n)
+{
+ struct ggnet_nodegroup *group = NULL;
+ struct ggnet_nodegroup *g;
+ u_int addr;
+
+ addr = n->addr.s_addr & 0xffff0000;
+ LIST_FOREACH(g, &net->group_list, entry) {
+ switch (g->type) {
+ case GROUP_ADDRESS:
+ if (g->addr.s_addr == addr) {
+ group = g;
+ break;
+ }
+ case GROUP_WHOIS:
+ case GROUP_DNS:
+ case GROUP_ROUTE:
+ /* UNSUPPORTED */
+ break;
+ }
+ }
+ if (!group) {
+ group = nodegroup_add(net, GROUP_ADDRESS, &addr);
+ }
+
+ n->group = group;
+ group->node_count++;
+}
+
+static void
+nodegroup_unset(struct ggnet *net, struct ggnet_node *n)
+{
+ if (!n->group)
+ return;
+
+ n->group->node_count--;
+ if (n->group->node_count == 0)
+ nodegroup_del(net, n->group);
+}
+