]> git.meshlink.io Git - catta/commitdiff
* add support for both ipv4 AND ipv6 reverse lookups
authorLennart Poettering <lennart@poettering.net>
Thu, 23 Dec 2004 17:16:28 +0000 (17:16 +0000)
committerLennart Poettering <lennart@poettering.net>
Thu, 23 Dec 2004 17:16:28 +0000 (17:16 +0000)
git-svn-id: file:///home/lennart/svn/public/avahi/trunk@4 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe

address.c
address.h
flx.h
local.c
main.c
server.c
util.c
util.h

index 633f40e682e0324a5366d9cf4a3645894e7dac6b..9099ad9b00e8d36fd65f534031dfe7cdeffb9ad6 100644 (file)
--- 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;
 }
index 28ccb4bf7aca2551cf59ed097f2756d12d07fd5f..33dcc279826e3dfb4f92e3b609a8642279cd0d1c 100644 (file)
--- 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 8c46673e0d990c8338f36edafcd4e306f68ec1e7..b7a5ae9977b0bbfa9ea538aeaa66957ace61fe8a 100644 (file)
--- a/flx.h
+++ b/flx.h
@@ -4,6 +4,8 @@
 #include <stdio.h>
 #include <glib.h>
 
+#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 4a63274a8f6ab4953454eb0f2d968d36bcbd889d..7204ca809f6a1e7f69b3acf58b2d7de0b1aac980 100644 (file)
--- 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 9bba48cfbf5601b8d53d68cf57d794d0fd6f6b94..da4b338faa3edba752ff6630cd718c4010cca019 100644 (file)
--- 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);
     
index 6ab1f1fd329fda3fe384cd9bbd450b0a2829d8ca..2fa12757ade932adf4dc0ec0ae8124560c759ee7 100644 (file)
--- 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 7d3c3b6bf8ff579aa884ac81c3dcf0f69312851e..334a7990e4cbd1bc417f47fa7b9db5a5f4f808b6 100644 (file)
--- 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 a5d9feb791dc22ed7a9ee8ab741eb4db1891224b..a9d12e0b7a22f14adb0c8c5b86d019850ddfe543 100644 (file)
--- a/util.h
+++ b/util.h
@@ -3,7 +3,7 @@
 
 #include <glib.h>
 
-gchar *flx_normalize_name(gchar *s);
+gchar *flx_normalize_name(const gchar *s);
 gchar *flx_get_host_name(void);
 
 #endif