return (gchar*) inet_ntop(a->family, a->data, s, length);
}
-gchar* flx_reverse_lookup_name(const flxAddress *a) {
+gchar* flx_reverse_lookup_name_ipv4(const flxIPv4Address *a) {
+ guint32 n = ntohl(a->address);
g_assert(a);
- if (a->family == AF_INET) {
- guint32 n = ntohl(a->ipv4.address);
- return g_strdup_printf("%u.%u.%u.%u.in-addr.arpa", n & 0xFF, (n >> 8) & 0xFF, (n >> 16) & 0xFF, n >> 24);
- } else if (a->family == AF_INET6) {
-
- return g_strdup_printf("%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.int",
- a->ipv6.address[15] & 0xF,
- a->ipv6.address[15] >> 4,
- a->ipv6.address[14] & 0xF,
- a->ipv6.address[14] >> 4,
- a->ipv6.address[13] & 0xF,
- a->ipv6.address[13] >> 4,
- a->ipv6.address[12] & 0xF,
- a->ipv6.address[12] >> 4,
- a->ipv6.address[11] & 0xF,
- a->ipv6.address[11] >> 4,
- a->ipv6.address[10] & 0xF,
- a->ipv6.address[10] >> 4,
- a->ipv6.address[9] & 0xF,
- a->ipv6.address[9] >> 4,
- a->ipv6.address[8] & 0xF,
- a->ipv6.address[8] >> 4,
- a->ipv6.address[7] & 0xF,
- a->ipv6.address[7] >> 4,
- a->ipv6.address[6] & 0xF,
- a->ipv6.address[6] >> 4,
- a->ipv6.address[5] & 0xF,
- a->ipv6.address[5] >> 4,
- a->ipv6.address[4] & 0xF,
- a->ipv6.address[4] >> 4,
- a->ipv6.address[3] & 0xF,
- a->ipv6.address[3] >> 4,
- a->ipv6.address[2] & 0xF,
- a->ipv6.address[2] >> 4,
- a->ipv6.address[1] & 0xF,
- a->ipv6.address[1] >> 4,
- a->ipv6.address[0] & 0xF,
- a->ipv6.address[0] >> 4);
- }
+ return g_strdup_printf("%u.%u.%u.%u.in-addr.arpa", n & 0xFF, (n >> 8) & 0xFF, (n >> 16) & 0xFF, n >> 24);
+}
+
+static gchar *reverse_lookup_name_ipv6(const flxIPv6Address *a, const gchar *suffix) {
+
+ return g_strdup_printf("%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%s",
+ a->address[15] & 0xF,
+ a->address[15] >> 4,
+ a->address[14] & 0xF,
+ a->address[14] >> 4,
+ a->address[13] & 0xF,
+ a->address[13] >> 4,
+ a->address[12] & 0xF,
+ a->address[12] >> 4,
+ a->address[11] & 0xF,
+ a->address[11] >> 4,
+ a->address[10] & 0xF,
+ a->address[10] >> 4,
+ a->address[9] & 0xF,
+ a->address[9] >> 4,
+ a->address[8] & 0xF,
+ a->address[8] >> 4,
+ a->address[7] & 0xF,
+ a->address[7] >> 4,
+ a->address[6] & 0xF,
+ a->address[6] >> 4,
+ a->address[5] & 0xF,
+ a->address[5] >> 4,
+ a->address[4] & 0xF,
+ a->address[4] >> 4,
+ a->address[3] & 0xF,
+ a->address[3] >> 4,
+ a->address[2] & 0xF,
+ a->address[2] >> 4,
+ a->address[1] & 0xF,
+ a->address[1] >> 4,
+ a->address[0] & 0xF,
+ a->address[0] >> 4,
+ suffix);
+}
+
+gchar *flx_reverse_lookup_name_ipv6_arpa(const flxIPv6Address *a) {
+ return reverse_lookup_name_ipv6(a, "ip6.arpa");
+}
- return NULL;
+gchar *flx_reverse_lookup_name_ipv6_int(const flxIPv6Address *a) {
+ return reverse_lookup_name_ipv6(a, "ip6.int");
+}
+
+flxAddress *flx_address_parse(const char *s, int family, flxAddress *ret_addr) {
+ g_assert(ret_addr);
+ g_assert(s);
+
+ if (inet_pton(family, s, ret_addr->data) < 0)
+ return NULL;
+
+ ret_addr->family = family;
+
+ return ret_addr;
}
guint flx_address_get_size(const flxAddress *a);
gint flx_address_cmp(const flxAddress *a, const flxAddress *b);
-gchar *flx_address_snprint(char *s, guint length, const flxAddress *a);
+gchar *flx_address_snprint(char *ret_s, guint length, const flxAddress *a);
-gchar* flx_reverse_lookup_name(const flxAddress *a);
+flxAddress *flx_address_parse(const char *s, int family, flxAddress *ret_addr);
+
+gchar* flx_reverse_lookup_name_ipv4(const flxIPv4Address *a);
+gchar* flx_reverse_lookup_name_ipv6_arpa(const flxIPv6Address *a);
+gchar* flx_reverse_lookup_name_ipv6_int(const flxIPv6Address *a);
#endif
#include <stdio.h>
#include <glib.h>
+#include "address.h"
+
struct _flxServer;
typedef struct _flxServer flxServer;
gint flx_server_get_next_id(flxServer *s);
void flx_server_add_rr(flxServer *s, gint id, gint interface, const flxRecord *rr);
-void flx_server_add(flxServer *s, gint id, const gchar *name, gint interface, guint16 type, gconstpointer data, guint size);
+void flx_server_add(flxServer *s, gint id, gint interface, const gchar *name, guint16 type, gconstpointer data, guint size);
+void flx_server_add_address(flxServer *s, gint id, gint interface, const gchar *name, flxAddress *a);
void flx_server_remove(flxServer *s, gint id);
#include "iface.h"
typedef struct {
- flxServer *server;
flxAddress address;
+ flxServer *server;
gint id;
} addr_info;
return hash(a, sizeof(a->family) + flx_address_get_size(a));
}
+static void remove_addr(flxLocalAddrSource *l, const flxInterfaceAddress *a) {
+ g_assert(l);
+ g_assert(a);
+
+ g_hash_table_remove(l->hash_table, &a->address);
+}
+
static void add_addr(flxLocalAddrSource *l, const flxInterfaceAddress *a) {
addr_info *ai;
- gchar *r;
g_assert(l);
g_assert(a);
- if (!(a->interface->flags & IFF_UP) ||
- !(a->interface->flags & IFF_RUNNING) ||
- (a->interface->flags & IFF_LOOPBACK))
- return;
-
- if (a->scope != RT_SCOPE_UNIVERSE)
- return;
+ if (g_hash_table_lookup(l->hash_table, &a->address))
+ return; /* Entry already existant */
ai = g_new(addr_info, 1);
ai->server = l->server;
ai->address = a->address;
ai->id = flx_server_get_next_id(l->server);
- flx_server_add(l->server, ai->id, l->hostname,
- ai->address.family == AF_INET ? FLX_DNS_TYPE_A : FLX_DNS_TYPE_AAAA,
- ai->address.data, flx_address_get_size(&ai->address));
- r = flx_reverse_lookup_name(&ai->address);
- flx_server_add(l->server, ai->id, r,
- FLX_DNS_TYPE_PTR,
- l->hostname, strlen(l->hostname)+1);
- g_free(r);
+ flx_server_add_address(l->server, ai->id, a->interface->index, l->hostname, &ai->address);
g_hash_table_replace(l->hash_table, &ai->address, ai);
+}
+static void handle_addr(flxLocalAddrSource *l, const flxInterfaceAddress *a) {
+ g_assert(l);
+ g_assert(a);
+
+ if (!(a->interface->flags & IFF_UP) ||
+ !(a->interface->flags & IFF_RUNNING) ||
+ (a->interface->flags & IFF_LOOPBACK) ||
+ a->scope != RT_SCOPE_UNIVERSE)
+
+ remove_addr(l, a);
+ else
+ add_addr(l, a);
}
/* Called whenever a new address becomes available, is changed or removed on the local machine */
g_assert(l);
if (change == FLX_INTERFACE_REMOVE)
- g_hash_table_remove(l->hash_table, &a->address);
- else if (change == FLX_INTERFACE_NEW)
- add_addr(l, a);
+ remove_addr(l, a);
+ else
+ handle_addr(l, a);
+}
+
+/* Called whenever a new interface becomes available, is changed or removed on the local machine */
+static void interface_callback(flxInterfaceMonitor *m, flxInterfaceChange change, const flxInterface *i, gpointer userdata) {
+ flxLocalAddrSource *l = userdata;
+ g_assert(m);
+ g_assert(i);
+ g_assert(l);
+
+ if (change == FLX_INTERFACE_CHANGE) {
+ flxInterfaceAddress *a;
+
+ for (a = i->addresses; a; a = a->next)
+ handle_addr(l, a);
+ }
}
static void destroy(gpointer data) {
g_free(hn);
flx_interface_monitor_add_address_callback(s->monitor, addr_callback, l);
+ flx_interface_monitor_add_interface_callback(s->monitor, interface_callback, l);
for (i = flx_interface_monitor_get_first(s->monitor); i; i = i->next) {
flxInterfaceAddress *a;
uname(&utsname);
c = g_strdup_printf("%s%c%s%n", g_strup(utsname.machine), 0, g_strup(utsname.sysname), &length);
- flx_server_add(l->server, l->hinfo_id, l->hostname,
+ flx_server_add(l->server, l->hinfo_id, 0, l->hostname,
FLX_DNS_TYPE_HINFO,
c, length+1);
g_free(c);
static GMainLoop *loop = NULL;
-static gboolean timeout (gpointer data) {
+static gboolean timeout(gpointer data) {
g_main_loop_quit(loop);
return FALSE;
}
int main(int argc, char *argv[]) {
flxServer *flx;
flxLocalAddrSource *l;
- guint32 ip;
+ flxAddress a;
+ gchar *r;
flx = flx_server_new(NULL);
l = flx_local_addr_source_new(flx);
-
-/* ip = inet_addr("127.0.0.1"); */
-/* flx_server_add(flx, flx_server_get_next_id(flx), "foo.local", FLX_DNS_TYPE_A, &ip, sizeof(ip)); */
+
+ flx_address_parse("127.0.0.1", AF_INET, &a);
+ flx_server_add_address(flx, 0, 0, "localhost", &a);
+
+ flx_address_parse("::1", AF_INET6, &a);
+ flx_server_add_address(flx, 0, 0, "ip6-localhost", &a);
g_timeout_add(1000, timeout, NULL);
g_hash_table_replace(s->rrset_by_name, e->rr.name, e);
}
-void flx_server_add(flxServer *s, gint id, const gchar *name, gint interface, guint16 type, gconstpointer data, guint size) {
+void flx_server_add(flxServer *s, gint id, gint interface, const gchar *name, guint16 type, gconstpointer data, guint size) {
flxRecord rr;
g_assert(s);
g_assert(name);
rr.class = FLX_DNS_CLASS_IN;
rr.data = (gpointer) data;
rr.size = size;
- rr.interface = interface;
rr.ttl = FLX_DEFAULT_TTL;
- flx_server_add_rr(s, id, 0, &rr);
+ flx_server_add_rr(s, id, interface, &rr);
}
const flxRecord *flx_server_iterate(flxServer *s, gint id, void **state) {
for (e = s->entries; e; e = e->next) {
char t[256];
- fprintf(f, "%-40s %-8s %-8s ", e->rr.name, dns_class_to_string(e->rr.class), dns_type_to_string(e->rr.type));
+ fprintf(f, "%i: %-40s %-8s %-8s ", e->interface, e->rr.name, dns_class_to_string(e->rr.class), dns_type_to_string(e->rr.type));
t[0] = 0;
}
}
+void flx_server_add_address(flxServer *s, gint id, gint interface, const gchar *name, flxAddress *a) {
+ gchar *n;
+ g_assert(s);
+ g_assert(name);
+ g_assert(a);
+
+ n = flx_normalize_name(name);
+
+ if (a->family == AF_INET) {
+ gchar *r;
+
+ flx_server_add(s, id, interface, n, FLX_DNS_TYPE_A, &a->ipv4, sizeof(a->ipv4));
+
+ r = flx_reverse_lookup_name_ipv4(&a->ipv4);
+ g_assert(r);
+ flx_server_add(s, id, interface, r, FLX_DNS_TYPE_PTR, n, strlen(n)+1);
+ g_free(r);
+
+ } else {
+ gchar *r;
+
+ flx_server_add(s, id, interface, n, FLX_DNS_TYPE_AAAA, &a->ipv6, sizeof(a->ipv6));
+
+ r = flx_reverse_lookup_name_ipv6_arpa(&a->ipv6);
+ g_assert(r);
+ flx_server_add(s, id, interface, r, FLX_DNS_TYPE_PTR, n, strlen(n)+1);
+ g_free(r);
+
+ r = flx_reverse_lookup_name_ipv6_int(&a->ipv6);
+ g_assert(r);
+ flx_server_add(s, id, interface, r, FLX_DNS_TYPE_PTR, n, strlen(n)+1);
+ g_free(r);
+ }
+
+ g_free(n);
+}
return g_strndup(t, sizeof(t));
}
-gchar *flx_normalize_name(gchar *s) {
+gchar *flx_normalize_name(const gchar *s) {
size_t l;
g_assert(s);
#include <glib.h>
-gchar *flx_normalize_name(gchar *s);
+gchar *flx_normalize_name(const gchar *s);
gchar *flx_get_host_name(void);
#endif