From c77f4231ed850b90b9b6f337727e19b63418426f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 23 Dec 2004 17:16:28 +0000 Subject: [PATCH] * add support for both ipv4 AND ipv6 reverse lookups git-svn-id: file:///home/lennart/svn/public/avahi/trunk@4 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe --- address.c | 101 ++++++++++++++++++++++++++++++++---------------------- address.h | 8 +++-- flx.h | 5 ++- local.c | 65 +++++++++++++++++++++++------------ main.c | 14 +++++--- server.c | 43 ++++++++++++++++++++--- util.c | 2 +- util.h | 2 +- 8 files changed, 164 insertions(+), 76 deletions(-) diff --git a/address.c b/address.c index 633f40e..9099ad9 100644 --- a/address.c +++ b/address.c @@ -33,48 +33,67 @@ gchar *flx_address_snprint(char *s, guint length, const flxAddress *a) { 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; } diff --git a/address.h b/address.h index 28ccb4b..33dcc27 100644 --- a/address.h +++ b/address.h @@ -24,8 +24,12 @@ typedef struct { 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 diff --git a/flx.h b/flx.h index 8c46673..b7a5ae9 100644 --- a/flx.h +++ b/flx.h @@ -4,6 +4,8 @@ #include #include +#include "address.h" + struct _flxServer; typedef struct _flxServer flxServer; @@ -28,7 +30,8 @@ void flx_server_free(flxServer* s); 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); diff --git a/local.c b/local.c index 4a63274..7204ca8 100644 --- a/local.c +++ b/local.c @@ -13,8 +13,8 @@ #include "iface.h" typedef struct { - flxServer *server; flxAddress address; + flxServer *server; gint id; } addr_info; @@ -45,37 +45,44 @@ static guint addr_hash(gconstpointer v) { 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 */ @@ -86,9 +93,24 @@ static void addr_callback(flxInterfaceMonitor *m, flxInterfaceChange change, con 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) { @@ -116,6 +138,7 @@ flxLocalAddrSource *flx_local_addr_source_new(flxServer *s) { 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; @@ -129,7 +152,7 @@ flxLocalAddrSource *flx_local_addr_source_new(flxServer *s) { 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); diff --git a/main.c b/main.c index 9bba48c..da4b338 100644 --- a/main.c +++ b/main.c @@ -6,7 +6,7 @@ static GMainLoop *loop = NULL; -static gboolean timeout (gpointer data) { +static gboolean timeout(gpointer data) { g_main_loop_quit(loop); return FALSE; } @@ -14,14 +14,18 @@ static gboolean timeout (gpointer data) { 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); diff --git a/server.c b/server.c index 6ab1f1f..2fa1275 100644 --- a/server.c +++ b/server.c @@ -75,7 +75,7 @@ void flx_server_add_rr(flxServer *s, gint id, gint interface, const flxRecord *r 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); @@ -87,9 +87,8 @@ void flx_server_add(flxServer *s, gint id, const gchar *name, gint interface, gu 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) { @@ -203,7 +202,7 @@ void flx_server_dump(flxServer *s, FILE *f) { 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; @@ -230,3 +229,39 @@ void flx_server_dump(flxServer *s, FILE *f) { } } +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); +} diff --git a/util.c b/util.c index 7d3c3b6..334a799 100644 --- a/util.c +++ b/util.c @@ -9,7 +9,7 @@ gchar *flx_get_host_name(void) { 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); diff --git a/util.h b/util.h index a5d9feb..a9d12e0 100644 --- a/util.h +++ b/util.h @@ -3,7 +3,7 @@ #include -gchar *flx_normalize_name(gchar *s); +gchar *flx_normalize_name(const gchar *s); gchar *flx_get_host_name(void); #endif -- 2.39.5