aboutsummaryrefslogtreecommitdiffstats
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
parentmore DEBUG backtrace stuff (diff)
downloadglouglou-4dcf36c3ead23b05e61ad41203c4743d59ccf18a.tar.xz
glouglou-4dcf36c3ead23b05e61ad41203c4743d59ccf18a.zip
introducing node grouping, for now only on address
-rw-r--r--libglouglou/libggnet.c125
-rw-r--r--libglouglou/libggnet.h30
2 files changed, 155 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);
+}
+
diff --git a/libglouglou/libggnet.h b/libglouglou/libggnet.h
index a27e4e1..51d65d4 100644
--- a/libglouglou/libggnet.h
+++ b/libglouglou/libggnet.h
@@ -15,6 +15,24 @@
#define GGNET_MANAGE_CONNID_TRUE 1
#define GGNET_MANAGE_CONNID_FALSE 0
+#define GGNET_GROUPING_TRUE 1
+#define GGNET_GROUPING_FALSE 1
+
+enum ggnet_grouptype {
+ GROUP_ADDRESS,
+ GROUP_WHOIS,
+ GROUP_DNS,
+ GROUP_ROUTE
+};
+
+struct ggnet_nodegroup {
+ LIST_ENTRY(ggnet_nodegroup) entry;
+ enum ggnet_grouptype type;
+ struct in_addr addr;
+ char name[GGNET_DNSNAME_MAX];
+ int node_count;
+ void *usrdata;
+};
struct ggnet_node {
LIST_ENTRY(ggnet_node) entry;
@@ -25,6 +43,7 @@ struct ggnet_node {
#define GGNET_NODENAME_WAITING -1
#define GGNET_NODENAME_FAILED -2
char name[GGNET_DNSNAME_MAX];
+ struct ggnet_nodegroup *group; /* XXX for now we support only one group */
void *usrdata;
};
@@ -52,15 +71,22 @@ struct ggnet_conn {
struct ggnet {
LIST_HEAD(, ggnet_conn) conn_list;
LIST_HEAD(, ggnet_node) node_list;
+ LIST_HEAD(, ggnet_nodegroup) group_list;
int conn_count;
int node_count;
u_int16_t conn_freeids[GGNET_CONN_FREEIDS_COUNT];
int conn_freeids_ptr;
int manage_connid;
+ int use_grouping;
+ void (*cb_addgroup)(struct ggnet *, struct ggnet_nodegroup *);
+ void (*cb_delgroup)(struct ggnet *, struct ggnet_nodegroup *);
time_t time;
};
struct ggnet *ggnet_new(int);
+void ggnet_grouping_set(struct ggnet *, int,
+ void (*cb_addgroup)(struct ggnet *, struct ggnet_nodegroup *),
+ void (*cb_delgroup)(struct ggnet *, struct ggnet_nodegroup *));
void ggnet_free(struct ggnet *);
struct ggnet_node *ggnet_node_add(struct ggnet *, struct in_addr *);
void ggnet_node_del(struct ggnet *, struct ggnet_node *);
@@ -69,6 +95,7 @@ void ggnet_node_update_name(struct ggnet *, struct ggnet_node *,
char *, int);
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 *);
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 *,
@@ -83,6 +110,9 @@ void *ggnet_conn_usrdata_get(struct ggnet_conn *);
void ggnet_conn_usrdata_set(struct ggnet_conn *, void *);
void *ggnet_conn_src_get(struct ggnet_conn *);
void *ggnet_conn_dst_get(struct ggnet_conn *);
+void *ggnet_nodegroup_usrdata_get(struct ggnet_nodegroup *);
+void ggnet_nodegroup_usrdata_set(struct ggnet_nodegroup *,
+ void *);
void ggnet_time_update(struct ggnet *, time_t);
#endif /* _LIBGGNET_H_ */