]> git.meshlink.io Git - catta/commitdiff
* implement new source address check mechanisms
authorLennart Poettering <lennart@poettering.net>
Fri, 24 Jun 2005 19:02:51 +0000 (19:02 +0000)
committerLennart Poettering <lennart@poettering.net>
Fri, 24 Jun 2005 19:02:51 +0000 (19:02 +0000)
* introduce new types AvahiIfIndex and AvahiProtocol to abstract underlying OS structures a bit
* document string list, address and other stuff
* implement qclass = ANY queries
* don't make use of UTF8 collation as RFC mandates

git-svn-id: file:///home/lennart/svn/public/avahi/trunk@144 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe

18 files changed:
avahi-common/address.c
avahi-common/address.h
avahi-common/rr.c
avahi-common/rr.h
avahi-common/strlst.c
avahi-common/strlst.h
avahi-common/util.c
avahi-core/avahi-test.c
avahi-core/core.h
avahi-core/iface.c
avahi-core/iface.h
avahi-core/resolve-address.c
avahi-core/resolve-host-name.c
avahi-core/resolve-service.c
avahi-core/server.c
avahi-core/socket.c
avahi-core/socket.h
avahi-daemon/avahi.conf

index 3e6fc9754c438ea6a2f08c7b7136919ae430734a..b982a2cb7ca46f3b0257d6eb3ecc728c0456211b 100644 (file)
@@ -33,9 +33,9 @@
 guint avahi_address_get_size(const AvahiAddress *a) {
     g_assert(a);
 
-    if (a->family == AF_INET)
+    if (a->family == AVAHI_PROTO_INET)
         return 4;
-    else if (a->family == AF_INET6)
+    else if (a->family == AVAHI_PROTO_INET6)
         return 16;
 
     return 0;
@@ -111,18 +111,18 @@ gchar *avahi_reverse_lookup_name_ipv6_int(const AvahiIPv6Address *a) {
     return reverse_lookup_name_ipv6(a, "ip6.int");
 }
 
-AvahiAddress *avahi_address_parse(const char *s, guchar family, AvahiAddress *ret_addr) {
+AvahiAddress *avahi_address_parse(const gchar *s, AvahiProtocol family, AvahiAddress *ret_addr) {
     g_assert(ret_addr);
     g_assert(s);
 
-    if (family == AF_UNSPEC) {
+    if (family == AVAHI_PROTO_UNSPEC) {
         if (inet_pton(AF_INET, s, ret_addr->data.data) <= 0) {
             if (inet_pton(AF_INET6, s, ret_addr->data.data) <= 0)
                 return NULL;
             else
-                ret_addr->family = AF_INET6;
+                ret_addr->family = AVAHI_PROTO_INET6;
         } else
-            ret_addr->family = AF_INET;
+            ret_addr->family = AVAHI_PROTO_INET;
     } else {
         if (inet_pton(family, s, ret_addr->data.data) <= 0)
             return NULL;
@@ -168,7 +168,7 @@ gboolean avahi_address_is_ipv4_in_ipv6(const AvahiAddress *a) {
     
     g_assert(a);
 
-    if (a->family != AF_INET6)
+    if (a->family != AVAHI_PROTO_INET6)
         return FALSE;
 
     return memcmp(a->data.ipv6.address, ipv4_in_ipv6, sizeof(ipv4_in_ipv6)) == 0;
index 22cb74b8633ec5813be1e79d6e6f7e6c521fc82a..4b5fb27bd4b3c07f5ff43f3962a4bfe443882b87 100644 (file)
 #include <sys/socket.h>
 #include <glib.h>
 
+/** Protocol family specification, takes the values AVAHI_INET, AVAHI_INET6, AVAHI_UNSPEC */
+typedef guchar AvahiProtocol;
+
+/** Numeric network interface index. Takes OS dependent values and the special constant AVAHI_IF_UNSPEC  */
+typedef gint AvahiIfIndex;
+
+/** Values for AvahiProtocol */
+enum {
+    AVAHI_PROTO_INET = AF_INET,     /**< IPv4 */
+    AVAHI_PROTO_INET6 = AF_INET6,   /**< IPv6 */
+    AVAHI_PROTO_UNSPEC = AF_UNSPEC  /**< Unspecified/all protocol(s) */
+};
+
+/** Special values for AvahiIfIndex */
+enum {
+    AVAHI_IF_UNSPEC = -1 /**< Unspecifed/all interfaces */
+};
+
+/** An IPv4 address */
 typedef struct {
-    guint32 address;
+    guint32 address; /**< Address data in network byte order. */
 } AvahiIPv4Address;
 
+/** An IPv6 address */
 typedef struct {
-    guint8 address[16];
+    guint8 address[16]; /**< Address data */
 } AvahiIPv6Address;
 
+/** Protocol (address family) independant address structure */
 typedef struct {
-    guchar family;
+    AvahiProtocol family; /**< Address family */
 
     union {
-        AvahiIPv6Address ipv6;
-        AvahiIPv4Address ipv4;
-        guint8 data[1];
+        AvahiIPv6Address ipv6;  /** Address when IPv6 */
+        AvahiIPv4Address ipv4;  /** Address when IPv4 */
+        guint8 data[1];         /** Type independant data field */
     } data;
 } AvahiAddress;
 
+/** Return the address data size of the specified address. (4 for IPv4, 16 for IPv6) */
 guint avahi_address_get_size(const AvahiAddress *a);
+
+/** Compare two addresses. Returns 0 when equal, a negative value when a < b, a positive value when a > b. */
 gint avahi_address_cmp(const AvahiAddress *a, const AvahiAddress *b);
 
+/** Convert the specified address *a to a human readable character string */
 gchar *avahi_address_snprint(char *ret_s, guint length, const AvahiAddress *a);
 
-AvahiAddress *avahi_address_parse(const char *s, guchar family, AvahiAddress *ret_addr);
+/** Convert the specifeid human readable character string to an
+ * address structure. Set af to AVAHI_UNSPEC for automatic address
+ * family detection. */
+AvahiAddress *avahi_address_parse(const char *s, AvahiProtocol af, AvahiAddress *ret_addr);
 
+/** Make an address structture of a sockaddr structure */
 AvahiAddress *avahi_address_from_sockaddr(const struct sockaddr* sa, AvahiAddress *ret_addr);
+
+/** Return the port number of a sockaddr structure (either IPv4 or IPv6) */
 guint16 avahi_port_from_sockaddr(const struct sockaddr* sa);
 
+/** Generate the DNS reverse lookup name for an IPv4 address. g_free() the result! */
 gchar* avahi_reverse_lookup_name_ipv4(const AvahiIPv4Address *a);
+
+/** Generate the modern DNS reverse lookup name for an IPv6 address, ending in ipv6.arpa. g_free() the result! */
 gchar* avahi_reverse_lookup_name_ipv6_arpa(const AvahiIPv6Address *a);
+
+/** Generate the historic DNS reverse lookup name for an IPv6 address, ending in ipv6.int. g_free() the result! */
 gchar* avahi_reverse_lookup_name_ipv6_int(const AvahiIPv6Address *a);
 
+/** Check whether the specified IPv6 address is in fact an
+ * encapsulated IPv4 address */
 gboolean avahi_address_is_ipv4_in_ipv6(const AvahiAddress *a);
 
 #endif
index 7e974c4843f6052ca9f4821eb78f8238ceb07dee..13160fcbc2d8222fa0d3e5519c5b2df19fb12e08 100644 (file)
@@ -148,11 +148,15 @@ void avahi_record_unref(AvahiRecord *r) {
 const gchar *avahi_dns_class_to_string(guint16 class) {
     if (class & AVAHI_DNS_CACHE_FLUSH) 
         return "FLUSH";
-    
-    if (class == AVAHI_DNS_CLASS_IN)
-        return "IN";
 
-    return NULL;
+    switch (class) {
+        case AVAHI_DNS_CLASS_IN:
+            return "IN";
+        case AVAHI_DNS_CLASS_ANY:
+            return "ANY";
+        default:
+            return NULL;
+    }
 }
 
 const gchar *avahi_dns_type_to_string(guint16 type) {
@@ -266,16 +270,17 @@ gboolean avahi_key_pattern_match(const AvahiKey *pattern, const AvahiKey *k) {
     
     return avahi_domain_equal(pattern->name, k->name) &&
         (pattern->type == k->type || pattern->type == AVAHI_DNS_TYPE_ANY) &&
-        pattern->class == k->class;
+        (pattern->class == k->class || pattern->type == AVAHI_DNS_CLASS_ANY);
 }
 
 gboolean avahi_key_is_pattern(const AvahiKey *k) {
     g_assert(k);
 
-    return k->type == AVAHI_DNS_TYPE_ANY;
+    return
+        k->type == AVAHI_DNS_TYPE_ANY ||
+        k->class == AVAHI_DNS_CLASS_ANY;
 }
 
-
 guint avahi_key_hash(const AvahiKey *k) {
     g_assert(k);
 
@@ -313,8 +318,8 @@ static gboolean rdata_equal(const AvahiRecord *a, const AvahiRecord *b) {
 
         case AVAHI_DNS_TYPE_HINFO:
             return
-                !g_utf8_collate(a->data.hinfo.cpu, b->data.hinfo.cpu) &&
-                !g_utf8_collate(a->data.hinfo.os, b->data.hinfo.os);
+                !strcmp(a->data.hinfo.cpu, b->data.hinfo.cpu) &&
+                !strcmp(a->data.hinfo.os, b->data.hinfo.os);
 
         case AVAHI_DNS_TYPE_TXT:
             return avahi_string_list_equal(a->data.txt.string_list, b->data.txt.string_list);
index 404cc217730b704c94756a9cb6aa4d476c922ee8..da0b2859997e27ef2dd922e145492730c811dd85 100644 (file)
@@ -43,6 +43,7 @@ enum {
 
 enum {
     AVAHI_DNS_CLASS_IN = 0x01,
+    AVAHI_DNS_CLASS_ANY = 0xFF,
     AVAHI_DNS_CACHE_FLUSH = 0x8000,
     AVAHI_DNS_UNICAST_RESPONSE = 0x8000
 };
index 866618f3f1e36a2ec46c2104e1bd197b3f151532..0853414d9e1f591e21e3ce5b36a8f89fee43e03c 100644 (file)
@@ -176,7 +176,7 @@ guint avahi_string_list_serialize(AvahiStringList *l, gpointer data, guint size)
     return used;
 }
 
-gboolean avahi_string_list_equal(AvahiStringList *a, AvahiStringList *b) {
+gboolean avahi_string_list_equal(const AvahiStringList *a, const AvahiStringList *b) {
 
     for (;;) {
         if (!a && !b)
@@ -235,7 +235,7 @@ AvahiStringList *avahi_string_list_new_va(va_list va) {
     return avahi_string_list_add_many_va(NULL, va);
 }
 
-AvahiStringList *avahi_string_list_copy(AvahiStringList *l) {
+AvahiStringList *avahi_string_list_copy(const AvahiStringList *l) {
     AvahiStringList *r = NULL;
 
     for (; l; l = l->next)
index 80dfc2c891286e75654fd3e29763b45cf797787f..4fde8eb8b7e4ebaf0fcaf3250fc7a88495bc1646 100644 (file)
 
 #include <glib.h>
 
+/** Linked list of strings that can contain any number of binary
+ * characters, include NUL bytes. An empty list is created by
+ * assigning a NULL to a pointer to AvahiStringList. The string list
+ * is stored in reverse order, so that appending to the string list is
+ * effectively a prepending to the linked list.  This object is used
+ * primarily for storing DNS TXT record data. */
 typedef struct AvahiStringList {
-    struct AvahiStringList *next;
-    guint size;
-    guint8 text[1];
+    struct AvahiStringList *next; /**< Pointe to the next linked list element */
+    guint size;  /**< Size of text[] */
+    guint8 text[1]; /**< Character data */
 } AvahiStringList;
 
+/** Create a new string list by taking a variable list of NUL
+ * terminated strings. The strings are copied using g_strdup(). The
+ * argument list must be terminated by a NULL pointer. */
 AvahiStringList *avahi_string_list_new(const gchar *txt, ...);
+
+/** Same as avahi_string_list_new() but pass a va_list structure */
 AvahiStringList *avahi_string_list_new_va(va_list va);
 
+/** Free a string list */
 void avahi_string_list_free(AvahiStringList *l);
 
+/** Append a NUL terminated string to the specified string list. The
+ * passed string is copied using g_strdup(). Returns the new list
+ * start. */
 AvahiStringList *avahi_string_list_add(AvahiStringList *l, const gchar *text);
+
+/** Append am arbitrary length byte string to the list. Returns the
+ * new list start. */
 AvahiStringList *avahi_string_list_add_arbitrary(AvahiStringList *l, const guint8 *text, guint size);
+
+/** Same as avahi_string_list_add(), but takes a variable number of
+ * NUL terminated strings. The argument list must be terminated by a
+ * NULL pointer. Returns the new list start. */
 AvahiStringList *avahi_string_list_add_many(AvahiStringList *r, ...);
+
+/** Same as avahi_string_list_add_many(), but use a va_list
+ * structure. Returns the new list start. */
 AvahiStringList *avahi_string_list_add_many_va(AvahiStringList *r, va_list va);
 
+/** Convert the string list object to a single character string,
+ * seperated by spaces and enclosed in "". g_free() the result! This
+ * function doesn't work well with string that contain NUL bytes. */
 gchar* avahi_string_list_to_string(AvahiStringList *l);
 
+/** Serialize the string list object in a way that is compatible with
+ * the storing of DNS TXT records. Strings longer than 255 bytes are truncated. */
 guint avahi_string_list_serialize(AvahiStringList *l, gpointer data, guint size);
+
+/** Inverse of avahi_string_list_serialize() */
 AvahiStringList *avahi_string_list_parse(gconstpointer data, guint size);
 
-gboolean avahi_string_list_equal(AvahiStringList *a, AvahiStringList *b);
+/** Compare to string lists */
+gboolean avahi_string_list_equal(const AvahiStringList *a, const AvahiStringList *b);
 
-AvahiStringList *avahi_string_list_copy(AvahiStringList *l);
+/** Copy a string list */
+AvahiStringList *avahi_string_list_copy(const AvahiStringList *l);
 
 #endif
 
index a41475a3b7242d11ef9eb7fa67423fd01cad8bad..baf552796d9fcdd4bfdfe93877af1c8862fc9833 100644 (file)
@@ -79,25 +79,18 @@ static gchar *unescape_uneeded(const gchar *src, gchar *ret_dest, size_t size) {
 
 gchar *avahi_normalize_name(const gchar *s) {
     gchar tmp[256];
-    gchar *n, *t;
     guint l;
     g_assert(s);
 
     unescape_uneeded(s, tmp, sizeof(tmp));
 
-    n = g_utf8_normalize(tmp, -1, G_NORMALIZE_DEFAULT);
-
-    if ((l = strlen(n)) == 0) {
-        g_free(n);
+    if ((l = strlen(tmp)) == 0)
         return g_strdup(".");
-    }
 
-    if (n[l-1] == '.')
-        return n;
+    if (tmp[l-1] == '.')
+        return g_strdup(tmp);
 
-    t = g_strdup_printf("%s.", n);
-    g_free(n);
-    return t;
+    return g_strdup_printf("%s.", tmp);
 }
 
 gint avahi_timeval_compare(const GTimeVal *a, const GTimeVal *b) {
@@ -280,22 +273,6 @@ gchar *avahi_escape_label(const guint8* src, guint src_length, gchar **ret_name,
     return r;
 }
 
-static gint utf8_strcasecmp(const gchar *a, const gchar *b) {
-    gchar *ta, *tb;
-    gint r;
-    
-    g_assert(a);
-    g_assert(b);
-
-    ta = g_utf8_casefold(a, -1);
-    tb = g_utf8_casefold(b, -1);
-    r = g_utf8_collate(ta, tb);
-    g_free(ta);
-    g_free(tb);
-
-    return r;
-}
-
 gboolean avahi_domain_equal(const gchar *a, const gchar *b) {
     g_assert(a);
     g_assert(b);
@@ -314,7 +291,7 @@ gboolean avahi_domain_equal(const gchar *a, const gchar *b) {
         else if ((pa && !pb) || (!pa && pb))
             return FALSE;
 
-        if (utf8_strcasecmp(pa, pb))
+        if (g_ascii_strcasecmp(pa, pb))
             return FALSE;
     }
 
@@ -385,7 +362,7 @@ guint avahi_domain_hash(const gchar *s) {
     guint hash = 0;
     
     for (;;) {
-        gchar c[65], *n, *m;
+        gchar c[65], *m;
 
         if (!avahi_unescape_label(&s, c, sizeof(c)))
             return hash;
@@ -393,13 +370,9 @@ guint avahi_domain_hash(const gchar *s) {
         if (!c[0])
             continue;
         
-        n = g_utf8_normalize(c, -1, G_NORMALIZE_DEFAULT);
-        m = g_utf8_strdown(n, -1);
-
+        m = g_ascii_strdown(c, -1);
         hash += g_str_hash(m);
-
         g_free(m);
-        g_free(n);
     }
 }
 
index 908212cdb1dffbcd150b422e74d0e5c8f04396e1..9bd4e2ca923bbc61d56437e33b43f4757f804d6d 100644 (file)
@@ -52,7 +52,7 @@ static void record_browser_callback(AvahiRecordBrowser *r, gint interface, gucha
     g_assert(r);
     g_assert(record);
     g_assert(interface > 0);
-    g_assert(protocol != AF_UNSPEC);
+    g_assert(protocol != AVAHI_PROTO_UNSPEC);
 
     avahi_log_debug("SUBSCRIPTION: record [%s] on %i.%i is %s", t = avahi_record_to_string(record), interface, protocol,
               event == AVAHI_BROWSER_NEW ? "new" : "remove");
@@ -115,22 +115,22 @@ static void create_entries(gboolean new_name) {
         service_name = n;
     }
     
-    if (avahi_server_add_service(server, group, 0, AF_UNSPEC, "_http._tcp", service_name, NULL, NULL, 80, "foo", NULL) < 0) {
+    if (avahi_server_add_service(server, group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_http._tcp", service_name, NULL, NULL, 80, "foo", NULL) < 0) {
         avahi_log_error("Failed to add HTTP service");
         goto fail;
     }
 
-    if (avahi_server_add_service(server, group, 0, AF_UNSPEC, "_ftp._tcp", service_name, NULL, NULL, 21, "foo", NULL) < 0) {
+    if (avahi_server_add_service(server, group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_ftp._tcp", service_name, NULL, NULL, 21, "foo", NULL) < 0) {
         avahi_log_error("Failed to add FTP service");
         goto fail;
     }
 
-    if (avahi_server_add_service(server, group, 0, AF_UNSPEC, "_webdav._tcp", service_name, NULL, NULL, 80, "foo", NULL) < 0) {
+    if (avahi_server_add_service(server, group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_webdav._tcp", service_name, NULL, NULL, 80, "foo", NULL) < 0) {
         avahi_log_error("Failed to add WEBDAV service");
         goto fail;
     }
 
-    if (avahi_server_add_dns_server_address(server, group, 0, AF_UNSPEC, NULL, AVAHI_DNS_SERVER_RESOLVE, avahi_address_parse("192.168.50.1", AF_UNSPEC, &a), 53) < 0) {
+    if (avahi_server_add_dns_server_address(server, group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, NULL, AVAHI_DNS_SERVER_RESOLVE, avahi_address_parse("192.168.50.1", AVAHI_PROTO_UNSPEC, &a), 53) < 0) {
         avahi_log_error("Failed to add new DNS Server address");
         goto fail;
     }
@@ -218,22 +218,22 @@ int main(int argc, char *argv[]) {
     avahi_server_config_free(&config);
 
     k = avahi_key_new("_http._tcp.local", AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_PTR);
-    r = avahi_record_browser_new(server, -1, AF_UNSPEC, k, record_browser_callback, NULL);
+    r = avahi_record_browser_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, k, record_browser_callback, NULL);
     avahi_key_unref(k);
 
-    hnr = avahi_host_name_resolver_new(server, -1, AF_UNSPEC, "codes-CompUTER.local", AF_UNSPEC, hnr_callback, NULL);
+    hnr = avahi_host_name_resolver_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "codes-CompUTER.local", AVAHI_PROTO_UNSPEC, hnr_callback, NULL);
 
-    ar = avahi_address_resolver_new(server, -1, AF_UNSPEC, avahi_address_parse("192.168.50.15", AF_INET, &a), ar_callback, NULL);
+    ar = avahi_address_resolver_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, avahi_address_parse("192.168.50.15", AVAHI_PROTO_INET, &a), ar_callback, NULL);
 
-    db = avahi_domain_browser_new(server, -1, AF_UNSPEC, NULL, AVAHI_DOMAIN_BROWSER_BROWSE, db_callback, NULL);
+    db = avahi_domain_browser_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, NULL, AVAHI_DOMAIN_BROWSER_BROWSE, db_callback, NULL);
 
-    stb = avahi_service_type_browser_new(server, -1, AF_UNSPEC, NULL, stb_callback, NULL);
+    stb = avahi_service_type_browser_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, NULL, stb_callback, NULL);
 
-    sb = avahi_service_browser_new(server, -1, AF_UNSPEC, "_http._tcp", NULL, sb_callback, NULL);
+    sb = avahi_service_browser_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_http._tcp", NULL, sb_callback, NULL);
 
-    sr = avahi_service_resolver_new(server, -1, AF_UNSPEC, "Ecstasy HTTP", "_http._tcp", "local", AF_UNSPEC, sr_callback, NULL);
+    sr = avahi_service_resolver_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "Ecstasy HTTP", "_http._tcp", "local", AVAHI_PROTO_UNSPEC, sr_callback, NULL);
 
-    dsb = avahi_dns_server_browser_new(server, -1, AF_UNSPEC, "local", AVAHI_DNS_SERVER_RESOLVE, AF_UNSPEC, dsb_callback, NULL);
+    dsb = avahi_dns_server_browser_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "local", AVAHI_DNS_SERVER_RESOLVE, AVAHI_PROTO_UNSPEC, dsb_callback, NULL);
 
     loop = g_main_loop_new(NULL, FALSE);
     
index 74f5cf433433f329a26a6d72372d478f76f16a8b..e0b5b5c100d8d06c521738a87231864da407158e 100644 (file)
@@ -80,7 +80,7 @@ typedef struct AvahiServerConfig {
     gboolean publish_addresses;            /**< Register A, AAAA and PTR records for all local IP addresses */
     gboolean publish_workstation;          /**< Register a _workstation._tcp service */
     gboolean publish_domain;               /**< Announce the local domain for browsing */
-    gboolean check_response_ttl;           /**< If enabled the server ignores all incoming responses with IP TTL != 255 */
+    gboolean check_response_ttl;           /**< If enabled the server ignores all incoming responses with IP TTL != 255. Newer versions of the RFC do no longer contain this check, so it is disabled by default. */
     gboolean use_iff_running;        /**< Require IFF_RUNNING on local network interfaces. This is the official way to check for link beat. Unfortunately this doesn't work with all drivers. So bettere leave this off. */
     gboolean enable_reflector;             /**< Reflect incoming mDNS traffic to all local networks. This allows mDNS based network browsing beyond ethernet borders */
     gboolean reflect_ipv;                  /**< if enable_reflector is TRUE, enable/disable reflecting between IPv4 and IPv6 */
@@ -186,19 +186,20 @@ void avahi_entry_group_set_data(AvahiEntryGroup *g, gpointer userdata);
 /** Return the opaque user data pointer currently set for the entry group object */
 gpointer avahi_entry_group_get_data(AvahiEntryGroup *g);
 
+/** Add a new resource record to the server. Returns 0 on success, negative otherwise. */
 gint avahi_server_add(
-    AvahiServer *s,
-    AvahiEntryGroup *g,
-    gint interface,
-    guchar protocol,
-    AvahiEntryFlags flags,
-    AvahiRecord *r);
+    AvahiServer *s,           /**< The server object to add this record to */
+    AvahiEntryGroup *g,       /**< An entry group object if this new record shall be attached to one, or NULL. If you plan to remove the record sometime later you a required to pass an entry group object here. */
+    AvahiIfIndex interface,   /**< A numeric index of a network interface to attach this record to, or AVAHI_IF_UNSPEC to attach this record to all interfaces */
+    AvahiProtocol protocol,   /**< A protocol family to attach this record to. One of the AVAHI_PROTO_xxx constants. Use AVAHI_PROTO_UNSPEC to make this record available on all protocols (wich means on both IPv4 and IPv6). */
+    AvahiEntryFlags flags,    /**< Special flags for this record */
+    AvahiRecord *r            /**< The record to add. This function increases the reference counter of this object. */   );
 
 gint avahi_server_add_ptr(
     AvahiServer *s,
     AvahiEntryGroup *g,
-    gint interface,
-    guchar protocol,
+    AvahiIfIndex interface,
+    AvahiProtocol protocol,
     AvahiEntryFlags flags,
     const gchar *name,
     const gchar *dest);
@@ -206,8 +207,8 @@ gint avahi_server_add_ptr(
 gint avahi_server_add_address(
     AvahiServer *s,
     AvahiEntryGroup *g,
-    gint interface,
-    guchar protocol,
+    AvahiIfIndex interface,
+    AvahiProtocol protocol,
     AvahiEntryFlags flags,
     const gchar *name,
     AvahiAddress *a);
@@ -215,8 +216,8 @@ gint avahi_server_add_address(
 gint avahi_server_add_text(
     AvahiServer *s,
     AvahiEntryGroup *g,
-    gint interface,
-    guchar protocol,
+    AvahiIfIndex interface,
+    AvahiProtocol protocol,
     AvahiEntryFlags flags,
     const gchar *name,
     ... /* text records, terminated by NULL */);
@@ -224,8 +225,8 @@ gint avahi_server_add_text(
 gint avahi_server_add_text_va(
     AvahiServer *s,
     AvahiEntryGroup *g,
-    gint interface,
-    guchar protocol,
+    AvahiIfIndex interface,
+    AvahiProtocol protocol,
     AvahiEntryFlags flags,
     const gchar *name,
     va_list va);
@@ -233,8 +234,8 @@ gint avahi_server_add_text_va(
 gint avahi_server_add_text_strlst(
     AvahiServer *s,
     AvahiEntryGroup *g,
-    gint interface,
-    guchar protocol,
+    AvahiIfIndex interface,
+    AvahiProtocol protocol,
     AvahiEntryFlags flags,
     const gchar *name,
     AvahiStringList *strlst);
@@ -242,20 +243,20 @@ gint avahi_server_add_text_strlst(
 gint avahi_server_add_service(
     AvahiServer *s,
     AvahiEntryGroup *g,
-    gint interface,
-    guchar protocol,
+    AvahiIfIndex interface,
+    AvahiProtocol protocol,
     const gchar *type,
     const gchar *name,
     const gchar *domain,
     const gchar *host,
     guint16 port,
-    ...  /* text records, terminated by NULL */);
+    ...  /**< text records, terminated by NULL */);
 
 gint avahi_server_add_service_va(
     AvahiServer *s,
     AvahiEntryGroup *g,
-    gint interface,
-    guchar protocol,
+    AvahiIfIndex interface,
+    AvahiProtocol protocol,
     const gchar *type,
     const gchar *name,
     const gchar *domain,
@@ -266,8 +267,8 @@ gint avahi_server_add_service_va(
 gint avahi_server_add_service_strlst(
     AvahiServer *s,
     AvahiEntryGroup *g,
-    gint interface,
-    guchar protocol,
+    AvahiIfIndex interface,
+    AvahiProtocol protocol,
     const gchar *type,
     const gchar *name,
     const gchar *domain,
@@ -287,8 +288,8 @@ typedef enum {
 gint avahi_server_add_dns_server_address(
     AvahiServer *s,
     AvahiEntryGroup *g,
-    gint interface,
-    guchar protocol,
+    AvahiIfIndex interface,
+    AvahiProtocol protocol,
     const gchar *domain,
     AvahiDNSServerType type,
     const AvahiAddress *address,
@@ -300,8 +301,8 @@ resolvable via mDNS */
 gint avahi_server_add_dns_server_name(
     AvahiServer *s,
     AvahiEntryGroup *g,
-    gint interface,
-    guchar protocol,
+    AvahiIfIndex interface,
+    AvahiProtocol protocol,
     const gchar *domain,
     AvahiDNSServerType type,
     const gchar *name,
@@ -319,18 +320,18 @@ typedef enum {
 
 
 typedef struct AvahiRecordBrowser AvahiRecordBrowser;
-typedef void (*AvahiRecordBrowserCallback)(AvahiRecordBrowser *b, gint interface, guchar protocol, AvahiBrowserEvent event, AvahiRecord *record, gpointer userdata);
-AvahiRecordBrowser *avahi_record_browser_new(AvahiServer *server, gint interface, guchar protocol, AvahiKey *key, AvahiRecordBrowserCallback callback, gpointer userdata);
+typedef void (*AvahiRecordBrowserCallback)(AvahiRecordBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, AvahiRecord *record, gpointer userdata);
+AvahiRecordBrowser *avahi_record_browser_new(AvahiServer *server, AvahiIfIndex interface, AvahiProtocol protocol, AvahiKey *key, AvahiRecordBrowserCallback callback, gpointer userdata);
 void avahi_record_browser_free(AvahiRecordBrowser *b);
 
 typedef struct AvahiHostNameResolver AvahiHostNameResolver;
-typedef void (*AvahiHostNameResolverCallback)(AvahiHostNameResolver *r, gint interface, guchar protocol, AvahiResolverEvent event, const gchar *host_name, const AvahiAddress *a, gpointer userdata);
-AvahiHostNameResolver *avahi_host_name_resolver_new(AvahiServer *server, gint interface, guchar protocol, const gchar *host_name, guchar aprotocol, AvahiHostNameResolverCallback calback, gpointer userdata);
+typedef void (*AvahiHostNameResolverCallback)(AvahiHostNameResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const gchar *host_name, const AvahiAddress *a, gpointer userdata);
+AvahiHostNameResolver *avahi_host_name_resolver_new(AvahiServer *server, AvahiIfIndex interface, AvahiProtocol protocol, const gchar *host_name, AvahiProtocol aprotocol, AvahiHostNameResolverCallback calback, gpointer userdata);
 void avahi_host_name_resolver_free(AvahiHostNameResolver *r);
 
 typedef struct AvahiAddressResolver AvahiAddressResolver;
-typedef void (*AvahiAddressResolverCallback)(AvahiAddressResolver *r, gint interface, guchar protocol, AvahiResolverEvent event, const AvahiAddress *a, const gchar *host_name, gpointer userdata);
-AvahiAddressResolver *avahi_address_resolver_new(AvahiServer *server, gint interface, guchar protocol, const AvahiAddress *address, AvahiAddressResolverCallback calback, gpointer userdata);
+typedef void (*AvahiAddressResolverCallback)(AvahiAddressResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const AvahiAddress *a, const gchar *host_name, gpointer userdata);
+AvahiAddressResolver *avahi_address_resolver_new(AvahiServer *server, AvahiIfIndex interface, AvahiProtocol protocol, const AvahiAddress *address, AvahiAddressResolverCallback calback, gpointer userdata);
 void avahi_address_resolver_free(AvahiAddressResolver *r);
 
 /** The type of domain to browse for */
@@ -343,23 +344,23 @@ typedef enum {
 } AvahiDomainBrowserType;
 
 typedef struct AvahiDomainBrowser AvahiDomainBrowser;
-typedef void (*AvahiDomainBrowserCallback)(AvahiDomainBrowser *b, gint interface, guchar protocol, AvahiBrowserEvent event, const gchar *domain, gpointer userdata);
-AvahiDomainBrowser *avahi_domain_browser_new(AvahiServer *server, gint interface, guchar protocol, const gchar *domain, AvahiDomainBrowserType type, AvahiDomainBrowserCallback callback, gpointer userdata);
+typedef void (*AvahiDomainBrowserCallback)(AvahiDomainBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const gchar *domain, gpointer userdata);
+AvahiDomainBrowser *avahi_domain_browser_new(AvahiServer *server, AvahiIfIndex interface, AvahiProtocol protocol, const gchar *domain, AvahiDomainBrowserType type, AvahiDomainBrowserCallback callback, gpointer userdata);
 void avahi_domain_browser_free(AvahiDomainBrowser *b);
 
 typedef struct AvahiServiceTypeBrowser AvahiServiceTypeBrowser;
-typedef void (*AvahiServiceTypeBrowserCallback)(AvahiServiceTypeBrowser *b, gint interface, guchar protocol, AvahiBrowserEvent event, const gchar *type, const gchar *domain, gpointer userdata);
-AvahiServiceTypeBrowser *avahi_service_type_browser_new(AvahiServer *server, gint interface, guchar protocol, const gchar *domain, AvahiServiceTypeBrowserCallback callback, gpointer userdata);
+typedef void (*AvahiServiceTypeBrowserCallback)(AvahiServiceTypeBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const gchar *type, const gchar *domain, gpointer userdata);
+AvahiServiceTypeBrowser *avahi_service_type_browser_new(AvahiServer *server, AvahiIfIndex interface, AvahiProtocol protocol, const gchar *domain, AvahiServiceTypeBrowserCallback callback, gpointer userdata);
 void avahi_service_type_browser_free(AvahiServiceTypeBrowser *b);
 
 typedef struct AvahiServiceBrowser AvahiServiceBrowser;
-typedef void (*AvahiServiceBrowserCallback)(AvahiServiceBrowser *b, gint interface, guchar protocol, AvahiBrowserEvent event, const gchar *name, const gchar *type, const gchar *domain, gpointer userdata);
-AvahiServiceBrowser *avahi_service_browser_new(AvahiServer *server, gint interface, guchar protocol, const gchar *service_type, const gchar *domain, AvahiServiceBrowserCallback callback, gpointer userdata);
+typedef void (*AvahiServiceBrowserCallback)(AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const gchar *name, const gchar *type, const gchar *domain, gpointer userdata);
+AvahiServiceBrowser *avahi_service_browser_new(AvahiServer *server, AvahiIfIndex interface, AvahiProtocol protocol, const gchar *service_type, const gchar *domain, AvahiServiceBrowserCallback callback, gpointer userdata);
 void avahi_service_browser_free(AvahiServiceBrowser *b);
 
 typedef struct AvahiServiceResolver AvahiServiceResolver;
-typedef void (*AvahiServiceResolverCallback)(AvahiServiceResolver *r, gint interface, guchar protocol, AvahiResolverEvent event, const gchar *name, const gchar *type, const gchar *domain, const gchar *host_name, const AvahiAddress *a, guint16 port, AvahiStringList *txt, gpointer userdata);
-AvahiServiceResolver *avahi_service_resolver_new(AvahiServer *server, gint interface, guchar protocol, const gchar *name, const gchar *type, const gchar *domain, guchar aprotocol, AvahiServiceResolverCallback calback, gpointer userdata);
+typedef void (*AvahiServiceResolverCallback)(AvahiServiceResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const gchar *name, const gchar *type, const gchar *domain, const gchar *host_name, const AvahiAddress *a, guint16 port, AvahiStringList *txt, gpointer userdata);
+AvahiServiceResolver *avahi_service_resolver_new(AvahiServer *server, AvahiIfIndex interface, AvahiProtocol protocol, const gchar *name, const gchar *type, const gchar *domain, AvahiProtocol aprotocol, AvahiServiceResolverCallback calback, gpointer userdata);
 void avahi_service_resolver_free(AvahiServiceResolver *r);
 
 
@@ -367,8 +368,8 @@ void avahi_service_resolver_free(AvahiServiceResolver *r);
  * conventional unicast DNS servers which may be used to resolve
  * conventional domain names */
 typedef struct AvahiDNSServerBrowser AvahiDNSServerBrowser;
-typedef void (*AvahiDNSServerBrowserCallback)(AvahiDNSServerBrowser *b, gint interface, guchar protocol, AvahiBrowserEvent event, const gchar *host_name, const AvahiAddress *a, guint16 port, gpointer userdata);
-AvahiDNSServerBrowser *avahi_dns_server_browser_new(AvahiServer *server, gint interface, guchar protocol, const gchar *domain, AvahiDNSServerType type, guchar aprotocol, AvahiDNSServerBrowserCallback callback, gpointer userdata);
+typedef void (*AvahiDNSServerBrowserCallback)(AvahiDNSServerBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const gchar *host_name, const AvahiAddress *a, guint16 port, gpointer userdata);
+AvahiDNSServerBrowser *avahi_dns_server_browser_new(AvahiServer *server, AvahiIfIndex interface, AvahiProtocol protocol, const gchar *domain, AvahiDNSServerType type, AvahiProtocol aprotocol, AvahiDNSServerBrowserCallback callback, gpointer userdata);
 void avahi_dns_server_browser_free(AvahiDNSServerBrowser *b);
 
 #endif
index 60419dff61803dd90a2183c756541b5a4747068f..fb491c9b534568e648e6ef7caaa05da96be5b043 100644 (file)
@@ -102,7 +102,7 @@ static void update_hw_interface_rr(AvahiInterfaceMonitor *m, AvahiHwInterface *h
             g_free(t);
             
             hw->entry_group = avahi_entry_group_new(m->server, avahi_host_rr_entry_group_callback, NULL);
-            if (avahi_server_add_service(m->server, hw->entry_group, hw->index, AF_UNSPEC, "_workstation._tcp", name, NULL, NULL, 9, NULL) < 0) { 
+            if (avahi_server_add_service(m->server, hw->entry_group, hw->index, AVAHI_PROTO_UNSPEC, "_workstation._tcp", name, NULL, NULL, 9, NULL) < 0) { 
                 avahi_log_warn(__FILE__": avahi_server_add_service() failed.");
                 avahi_entry_group_free(hw->entry_group);
                 hw->entry_group = NULL;
@@ -210,12 +210,12 @@ static int netlink_list_items(AvahiNetlink *nl, guint16 type, guint *ret_seq) {
     return avahi_netlink_send(nl, n, ret_seq);
 }
 
-static void new_interface(AvahiInterfaceMonitor *m, AvahiHwInterface *hw, guchar protocol) {
+static void new_interface(AvahiInterfaceMonitor *m, AvahiHwInterface *hw, AvahiProtocol protocol) {
     AvahiInterface *i;
     
     g_assert(m);
     g_assert(hw);
-    g_assert(protocol != AF_UNSPEC);
+    g_assert(protocol != AVAHI_PROTO_UNSPEC);
 
     i = g_new(AvahiInterface, 1);
     i->monitor = m;
@@ -246,9 +246,9 @@ static void check_interface_relevant(AvahiInterfaceMonitor *m, AvahiInterface *i
     if (b && !i->announcing) {
         avahi_log_debug("New relevant interface %s.%i (#%i)", i->hardware->name, i->protocol, i->hardware->index);
 
-        if (i->protocol == AF_INET)
+        if (i->protocol == AVAHI_PROTO_INET)
             avahi_mdns_mcast_join_ipv4(i->hardware->index, m->server->fd_ipv4);
-        if (i->protocol == AF_INET6)
+        if (i->protocol == AVAHI_PROTO_INET6)
             avahi_mdns_mcast_join_ipv6(i->hardware->index, m->server->fd_ipv6);
 
         i->announcing = TRUE;
@@ -257,9 +257,9 @@ static void check_interface_relevant(AvahiInterfaceMonitor *m, AvahiInterface *i
     } else if (!b && i->announcing) {
         avahi_log_debug("Interface %s.%i no longer relevant", i->hardware->name, i->protocol);
 
-        if (i->protocol == AF_INET)
+        if (i->protocol == AVAHI_PROTO_INET)
             avahi_mdns_mcast_leave_ipv4(i->hardware->index, m->server->fd_ipv4);
-        if (i->protocol == AF_INET6)
+        if (i->protocol == AVAHI_PROTO_INET6)
             avahi_mdns_mcast_leave_ipv6(i->hardware->index, m->server->fd_ipv6);
 
         avahi_goodbye_interface(m->server, i, FALSE);
@@ -314,9 +314,9 @@ static void callback(AvahiNetlink *nl, struct nlmsghdr *n, gpointer userdata) {
             g_hash_table_insert(m->hash_table, &hw->index, hw);
 
             if (m->server->fd_ipv4 >= 0)
-                new_interface(m, hw, AF_INET);
+                new_interface(m, hw, AVAHI_PROTO_INET);
             if (m->server->fd_ipv6 >= 0)
-                new_interface(m, hw, AF_INET6);
+                new_interface(m, hw, AVAHI_PROTO_INET6);
         }
         
         hw->flags = ifinfomsg->ifi_flags;
@@ -377,7 +377,7 @@ static void callback(AvahiNetlink *nl, struct nlmsghdr *n, gpointer userdata) {
         AvahiAddress raddr;
         gboolean raddr_valid = FALSE;
 
-        if (ifaddrmsg->ifa_family != AF_INET && ifaddrmsg->ifa_family != AF_INET6)
+        if (ifaddrmsg->ifa_family != AVAHI_PROTO_INET && ifaddrmsg->ifa_family != AVAHI_PROTO_INET6)
             return;
 
         if (!(i = (AvahiInterface*) avahi_interface_monitor_get_interface(m, ifaddrmsg->ifa_index, ifaddrmsg->ifa_family)))
@@ -392,15 +392,15 @@ static void callback(AvahiNetlink *nl, struct nlmsghdr *n, gpointer userdata) {
 
             switch(a->rta_type) {
                 case IFA_ADDRESS:
-                    if ((raddr.family == AF_INET6 && RTA_PAYLOAD(a) != 16) ||
-                        (raddr.family == AF_INET && RTA_PAYLOAD(a) != 4))
+                    if ((raddr.family == AVAHI_PROTO_INET6 && RTA_PAYLOAD(a) != 16) ||
+                        (raddr.family == AVAHI_PROTO_INET && RTA_PAYLOAD(a) != 4))
                         return;
 
                     memcpy(raddr.data.data, RTA_DATA(a), RTA_PAYLOAD(a));
                     raddr_valid = TRUE;
 
                     break;
-                    
+
                 default:
                     ;
             }
@@ -426,6 +426,7 @@ static void callback(AvahiNetlink *nl, struct nlmsghdr *n, gpointer userdata) {
             
             addr->flags = ifaddrmsg->ifa_flags;
             addr->scope = ifaddrmsg->ifa_scope;
+            addr->prefix_len = ifaddrmsg->ifa_prefixlen;
 
             update_address_rr(m, addr, FALSE);
             check_interface_relevant(m, i);
@@ -516,13 +517,13 @@ void avahi_interface_monitor_free(AvahiInterfaceMonitor *m) {
 }
 
 
-AvahiInterface* avahi_interface_monitor_get_interface(AvahiInterfaceMonitor *m, gint index, guchar protocol) {
+AvahiInterface* avahi_interface_monitor_get_interface(AvahiInterfaceMonitor *m, AvahiIfIndex index, AvahiProtocol protocol) {
     AvahiHwInterface *hw;
     AvahiInterface *i;
     
     g_assert(m);
     g_assert(index > 0);
-    g_assert(protocol != AF_UNSPEC);
+    g_assert(protocol != AVAHI_PROTO_UNSPEC);
 
     if (!(hw = avahi_interface_monitor_get_hw_interface(m, index)))
         return NULL;
@@ -534,7 +535,7 @@ AvahiInterface* avahi_interface_monitor_get_interface(AvahiInterfaceMonitor *m,
     return NULL;
 }
 
-AvahiHwInterface* avahi_interface_monitor_get_hw_interface(AvahiInterfaceMonitor *m, gint index) {
+AvahiHwInterface* avahi_interface_monitor_get_hw_interface(AvahiInterfaceMonitor *m, AvahiIfIndex index) {
     g_assert(m);
     g_assert(index > 0);
 
@@ -557,9 +558,9 @@ void avahi_interface_send_packet_unicast(AvahiInterface *i, AvahiDnsPacket *p, c
 /*     else */
 /*         avahi_log_debug("multicast sending on '%s.%i'", i->hardware->name, i->protocol); */
     
-    if (i->protocol == AF_INET && i->monitor->server->fd_ipv4 >= 0)
+    if (i->protocol == AVAHI_PROTO_INET && i->monitor->server->fd_ipv4 >= 0)
         avahi_send_dns_packet_ipv4(i->monitor->server->fd_ipv4, i->hardware->index, p, a ? &a->data.ipv4 : NULL, port);
-    else if (i->protocol == AF_INET6 && i->monitor->server->fd_ipv6 >= 0)
+    else if (i->protocol == AVAHI_PROTO_INET6 && i->monitor->server->fd_ipv6 >= 0)
         avahi_send_dns_packet_ipv6(i->monitor->server->fd_ipv6, i->hardware->index, p, a ? &a->data.ipv6 : NULL, port);
 }
 
@@ -650,24 +651,24 @@ gboolean avahi_interface_address_relevant(AvahiInterfaceAddress *a) {
 }
 
 
-gboolean avahi_interface_match(AvahiInterface *i, gint index, guchar protocol) {
+gboolean avahi_interface_match(AvahiInterface *i, AvahiIfIndex index, AvahiProtocol protocol) {
     g_assert(i);
     
     if (index > 0 && index != i->hardware->index)
         return FALSE;
 
-    if (protocol != AF_UNSPEC && protocol != i->protocol)
+    if (protocol != AVAHI_PROTO_UNSPEC && protocol != i->protocol)
         return FALSE;
 
     return TRUE;
 }
 
-void avahi_interface_monitor_walk(AvahiInterfaceMonitor *m, gint interface, guchar protocol, AvahiInterfaceMonitorWalkCallback callback, gpointer userdata) {
+void avahi_interface_monitor_walk(AvahiInterfaceMonitor *m, AvahiIfIndex interface, AvahiProtocol protocol, AvahiInterfaceMonitorWalkCallback callback, gpointer userdata) {
     g_assert(m);
     g_assert(callback);
     
     if (interface > 0) {
-        if (protocol != AF_UNSPEC) {
+        if (protocol != AVAHI_PROTO_UNSPEC) {
             AvahiInterface *i;
             
             if ((i = avahi_interface_monitor_get_interface(m, interface, protocol)))
@@ -714,3 +715,51 @@ gboolean avahi_address_is_local(AvahiInterfaceMonitor *m, const AvahiAddress *a)
 
     return FALSE;
 }
+
+gboolean avahi_interface_address_on_link(AvahiInterface *i, const AvahiAddress *a) {
+    AvahiInterfaceAddress *ia;
+    
+    g_assert(i);
+    g_assert(a);
+
+    if (a->family != i->protocol)
+        return FALSE;
+
+    for (ia = i->addresses; ia; ia = ia->address_next) {
+
+        if (a->family == AVAHI_PROTO_INET) {
+            guint32 m;
+            
+            m = ~(((guint32) -1) >> ia->prefix_len);
+            
+            if ((g_ntohl(a->data.ipv4.address) & m) == (g_ntohl(ia->address.data.ipv4.address) & m))
+                return TRUE;
+        } else {
+            guint i;
+            guchar pl;
+            g_assert(a->family == AVAHI_PROTO_INET6);
+
+            pl = ia->prefix_len;
+            
+            for (i = 0; i < 16; i++) {
+                guint8 m;
+
+                if (pl == 0)
+                    return TRUE;
+                
+                if (pl >= 8) {
+                    m = 0xFF;
+                    pl -= 8;
+                } else {
+                    m = ~(0xFF >> pl);
+                    pl = 0;
+                }
+                
+                if ((a->data.ipv6.address[i] & m) != (ia->address.data.ipv6.address[i] & m))
+                    break;
+            }
+        }
+    }
+
+    return FALSE;
+}
index 1372e6fd137ffcf7d13e3b42bd217813325590ae..486207e0c4e275e1973b51fba118e21dce39d84a 100644 (file)
@@ -64,7 +64,7 @@ struct AvahiHwInterface {
     AvahiInterfaceMonitor *monitor;
 
     gchar *name;
-    gint index;
+    AvahiIfIndex index;
     guint flags;
     guint mtu;
 
@@ -82,7 +82,7 @@ struct AvahiInterface {
     AvahiInterfaceMonitor *monitor;
     
     AvahiHwInterface *hardware;
-    guchar protocol;
+    AvahiProtocol protocol;
     gboolean announcing;
 
     AvahiCache *cache;
@@ -100,6 +100,7 @@ struct AvahiInterfaceAddress {
     
     guchar flags;
     guchar scope;
+    guchar prefix_len;
     AvahiAddress address;
     
     AvahiEntryGroup *entry_group;
@@ -111,7 +112,7 @@ void avahi_interface_monitor_free(AvahiInterfaceMonitor *m);
 
 void avahi_interface_monitor_sync(AvahiInterfaceMonitor *m);
 
-AvahiInterface* avahi_interface_monitor_get_interface(AvahiInterfaceMonitor *m, gint index, guchar protocol);
+AvahiInterface* avahi_interface_monitor_get_interface(AvahiInterfaceMonitor *m, AvahiIfIndex index, AvahiProtocol protocol);
 AvahiHwInterface* avahi_interface_monitor_get_hw_interface(AvahiInterfaceMonitor *m, gint index);
 
 void avahi_interface_send_packet(AvahiInterface *i, AvahiDnsPacket *p);
@@ -126,14 +127,17 @@ void avahi_dump_caches(AvahiInterfaceMonitor *m, FILE *f);
 gboolean avahi_interface_relevant(AvahiInterface *i);
 gboolean avahi_interface_address_relevant(AvahiInterfaceAddress *a);
 
-gboolean avahi_interface_match(AvahiInterface *i, gint index, guchar protocol);
+gboolean avahi_interface_match(AvahiInterface *i, AvahiIfIndex index, AvahiProtocol protocol);
 
 typedef void (*AvahiInterfaceMonitorWalkCallback)(AvahiInterfaceMonitor *m, AvahiInterface *i, gpointer userdata);
     
-void avahi_interface_monitor_walk(AvahiInterfaceMonitor *m, gint index, guchar protocol, AvahiInterfaceMonitorWalkCallback callback, gpointer userdata);
+void avahi_interface_monitor_walk(AvahiInterfaceMonitor *m, AvahiIfIndex index, AvahiProtocol protocol, AvahiInterfaceMonitorWalkCallback callback, gpointer userdata);
 
 void avahi_update_host_rrs(AvahiInterfaceMonitor *m, gboolean remove);
 
 gboolean avahi_address_is_local(AvahiInterfaceMonitor *m, const AvahiAddress *a);
 
+gboolean avahi_interface_address_on_link(AvahiInterface *i, const AvahiAddress *a);
+
+
 #endif
index 07cbef4f403bd89dd536722ae3de2e09c87ac5eb..a4ed594deb57773eee7d6f16fa7d587537088340 100644 (file)
@@ -75,7 +75,7 @@ static void time_event_callback(AvahiTimeEvent *e, void *userdata) {
     g_assert(e);
     g_assert(r);
 
-    finish(r, -1, AF_UNSPEC, AVAHI_RESOLVER_TIMEOUT, NULL);
+    finish(r, -1, AVAHI_PROTO_UNSPEC, AVAHI_RESOLVER_TIMEOUT, NULL);
 }
 
 AvahiAddressResolver *avahi_address_resolver_new(AvahiServer *server, gint interface, guchar protocol, const AvahiAddress *address, AvahiAddressResolverCallback callback, gpointer userdata) {
@@ -88,7 +88,7 @@ AvahiAddressResolver *avahi_address_resolver_new(AvahiServer *server, gint inter
     g_assert(address);
     g_assert(callback);
 
-    g_assert(address->family == AF_INET || address->family == AF_INET6);
+    g_assert(address->family == AVAHI_PROTO_INET || address->family == AVAHI_PROTO_INET6);
 
     r = g_new(AvahiAddressResolver, 1);
     r->server = server;
@@ -101,7 +101,7 @@ AvahiAddressResolver *avahi_address_resolver_new(AvahiServer *server, gint inter
 
     AVAHI_LLIST_PREPEND(AvahiAddressResolver, resolver, server->address_resolvers, r);
     
-    if (address->family == AF_INET)
+    if (address->family == AVAHI_PROTO_INET)
         n = avahi_reverse_lookup_name_ipv4(&address->data.ipv4);
     else 
         n = avahi_reverse_lookup_name_ipv6_arpa(&address->data.ipv6);
index c10119a4fccfc6eea4da5c116914b3264bad94d0..fadfc85a8ba855e2c6523ae220e161ecd1008354 100644 (file)
@@ -64,12 +64,12 @@ static void finish(AvahiHostNameResolver *r, gint interface, guchar protocol, Av
     if (record) {
         switch (record->key->type) {
             case AVAHI_DNS_TYPE_A:
-                a.family = AF_INET;
+                a.family = AVAHI_PROTO_INET;
                 a.data.ipv4 = record->data.a.address;
                 break;
                 
             case AVAHI_DNS_TYPE_AAAA:
-                a.family = AF_INET6;
+                a.family = AVAHI_PROTO_INET6;
                 a.data.ipv6 = record->data.aaaa.address;
                 break;
                 
@@ -101,7 +101,7 @@ static void time_event_callback(AvahiTimeEvent *e, void *userdata) {
     g_assert(e);
     g_assert(r);
 
-    finish(r, -1, AF_UNSPEC, AVAHI_RESOLVER_TIMEOUT, NULL);
+    finish(r, -1, AVAHI_PROTO_UNSPEC, AVAHI_RESOLVER_TIMEOUT, NULL);
 }
 
 AvahiHostNameResolver *avahi_host_name_resolver_new(AvahiServer *server, gint interface, guchar protocol, const gchar *host_name, guchar aprotocol, AvahiHostNameResolverCallback callback, gpointer userdata) {
@@ -113,7 +113,7 @@ AvahiHostNameResolver *avahi_host_name_resolver_new(AvahiServer *server, gint in
     g_assert(host_name);
     g_assert(callback);
 
-    g_assert(aprotocol == AF_UNSPEC || aprotocol == AF_INET || aprotocol == AF_INET6);
+    g_assert(aprotocol == AVAHI_PROTO_UNSPEC || aprotocol == AVAHI_PROTO_INET || aprotocol == AVAHI_PROTO_INET6);
 
     r = g_new(AvahiHostNameResolver, 1);
     r->server = server;
@@ -128,13 +128,13 @@ AvahiHostNameResolver *avahi_host_name_resolver_new(AvahiServer *server, gint in
 
     AVAHI_LLIST_PREPEND(AvahiHostNameResolver, resolver, server->host_name_resolvers, r);
     
-    if (aprotocol == AF_INET || aprotocol == AF_UNSPEC) {
+    if (aprotocol == AVAHI_PROTO_INET || aprotocol == AVAHI_PROTO_UNSPEC) {
         k = avahi_key_new(host_name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_A);
         r->record_browser_a = avahi_record_browser_new(server, interface, protocol, k, record_browser_callback, r);
         avahi_key_unref(k);
     } 
 
-    if (aprotocol == AF_INET6 || aprotocol == AF_UNSPEC) {
+    if (aprotocol == AVAHI_PROTO_INET6 || aprotocol == AVAHI_PROTO_UNSPEC) {
         k = avahi_key_new(host_name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_AAAA);
         r->record_browser_aaaa = avahi_record_browser_new(server, interface, protocol, k, record_browser_callback, r);
         avahi_key_unref(k);
index deb4cdb53d33c2fca76dafffad75a88af79cb0c1..8fe9fd26a9d1838e203fdfe88453ab9435e4a00a 100644 (file)
@@ -94,12 +94,12 @@ static void finish(AvahiServiceResolver *r, AvahiResolverEvent event) {
         
         switch (r->address_record->key->type) {
             case AVAHI_DNS_TYPE_A:
-                a.family = AF_INET;
+                a.family = AVAHI_PROTO_INET;
                 a.data.ipv4 = r->address_record->data.a.address;
                 break;
                 
             case AVAHI_DNS_TYPE_AAAA:
-                a.family = AF_INET6;
+                a.family = AVAHI_PROTO_INET6;
                 a.data.ipv6 = r->address_record->data.aaaa.address;
                 break;
                 
@@ -134,13 +134,13 @@ static void record_browser_callback(AvahiRecordBrowser*rr, gint interface, gucha
     if (r->interface > 0 && interface != r->interface)
         return;
 
-    if (r->protocol != AF_UNSPEC && protocol != r->protocol)
+    if (r->protocol != AVAHI_PROTO_UNSPEC && protocol != r->protocol)
         return;
     
     if (r->interface <= 0)
         r->interface = interface;
 
-    if (r->protocol == AF_UNSPEC)
+    if (r->protocol == AVAHI_PROTO_UNSPEC)
         r->protocol = protocol;
     
     switch (record->key->type) {
@@ -150,13 +150,13 @@ static void record_browser_callback(AvahiRecordBrowser*rr, gint interface, gucha
 
                 g_assert(!r->record_browser_a && !r->record_browser_aaaa);
                 
-                if (r->address_protocol == AF_INET || r->address_protocol == AF_UNSPEC) {
+                if (r->address_protocol == AVAHI_PROTO_INET || r->address_protocol == AVAHI_PROTO_UNSPEC) {
                     AvahiKey *k = avahi_key_new(r->srv_record->data.srv.name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_A);
                     r->record_browser_a = avahi_record_browser_new(r->server, r->interface, r->protocol, k, record_browser_callback, r);
                     avahi_key_unref(k);
                 } 
                 
-                if (r->address_protocol == AF_INET6 || r->address_protocol == AF_UNSPEC) {
+                if (r->address_protocol == AVAHI_PROTO_INET6 || r->address_protocol == AVAHI_PROTO_UNSPEC) {
                     AvahiKey *k = avahi_key_new(r->srv_record->data.srv.name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_AAAA);
                     r->record_browser_aaaa = avahi_record_browser_new(r->server, r->interface, r->protocol, k, record_browser_callback, r);
                     avahi_key_unref(k);
@@ -204,7 +204,7 @@ AvahiServiceResolver *avahi_service_resolver_new(AvahiServer *server, gint inter
     g_assert(type);
     g_assert(callback);
 
-    g_assert(aprotocol == AF_UNSPEC || aprotocol == AF_INET || aprotocol == AF_INET6);
+    g_assert(aprotocol == AVAHI_PROTO_UNSPEC || aprotocol == AVAHI_PROTO_INET || aprotocol == AVAHI_PROTO_INET6);
 
     r = g_new(AvahiServiceResolver, 1);
     r->server = server;
index 0e92e2737c0e9c732aebdd854b7d035c9bdb963d..19badd12ae87ed6736000523d35008f2f864714d 100644 (file)
@@ -600,7 +600,7 @@ static void handle_query_packet(AvahiServer *s, AvahiDnsPacket *p, AvahiInterfac
             goto fail;
         }
 
-        if (record->key->type != AVAHI_DNS_TYPE_ANY) {
+        if (!avahi_key_is_pattern(record->key)) {
             reflect_probe(s, i, record);
             incoming_probe(s, record, i);
         }
@@ -638,7 +638,7 @@ static void handle_response_packet(AvahiServer *s, AvahiDnsPacket *p, AvahiInter
             break;
         }
 
-        if (record->key->type != AVAHI_DNS_TYPE_ANY) {
+        if (!avahi_key_is_pattern(record->key)) {
 
 /*             avahi_log_debug("Handling response: %s", txt = avahi_record_to_string(record)); */
 /*             g_free(txt); */
@@ -788,9 +788,9 @@ static void reflect_legacy_unicast_query_packet(AvahiServer *s, AvahiDnsPacket *
             j != i &&
             (s->config.reflect_ipv || j->protocol == i->protocol)) {
 
-            if (j->protocol == AF_INET && s->fd_legacy_unicast_ipv4 >= 0) {
+            if (j->protocol == AVAHI_PROTO_INET && s->fd_legacy_unicast_ipv4 >= 0) {
                 avahi_send_dns_packet_ipv4(s->fd_legacy_unicast_ipv4, j->hardware->index, p, NULL, 0);
-                } else if (j->protocol == AF_INET6 && s->fd_legacy_unicast_ipv6 >= 0)
+                } else if (j->protocol == AVAHI_PROTO_INET6 && s->fd_legacy_unicast_ipv6 >= 0)
                 avahi_send_dns_packet_ipv6(s->fd_legacy_unicast_ipv6, j->hardware->index, p, NULL, 0);
         }
 
@@ -835,7 +835,15 @@ static gboolean originates_from_local_legacy_unicast_socket(AvahiServer *s, cons
     return FALSE;
 }
 
-static void dispatch_packet(AvahiServer *s, AvahiDnsPacket *p, const struct sockaddr *sa, gint iface, gint ttl) {
+static gboolean is_mdns_mcast_address(const AvahiAddress *a) {
+    AvahiAddress b;
+    g_assert(a);
+
+    avahi_address_parse(a->family == AVAHI_PROTO_INET ? AVAHI_IPV4_MCAST_GROUP : AVAHI_IPV6_MCAST_GROUP, a->family, &b);
+    return avahi_address_cmp(a, &b) == 0;
+}
+
+static void dispatch_packet(AvahiServer *s, AvahiDnsPacket *p, const struct sockaddr *sa, AvahiAddress *dest, AvahiIfIndex iface, gint ttl) {
     AvahiInterface *i;
     AvahiAddress a;
     guint16 port;
@@ -843,6 +851,7 @@ static void dispatch_packet(AvahiServer *s, AvahiDnsPacket *p, const struct sock
     g_assert(s);
     g_assert(p);
     g_assert(sa);
+    g_assert(dest);
     g_assert(iface > 0);
 
     if (!(i = avahi_interface_monitor_get_interface(s->monitor, iface, sa->sa_family)) ||
@@ -896,18 +905,22 @@ static void dispatch_packet(AvahiServer *s, AvahiDnsPacket *p, const struct sock
         
 /*         avahi_log_debug("Handled query"); */
     } else {
-
         if (port != AVAHI_MDNS_PORT) {
             avahi_log_warn("Recieved repsonse with invalid source port %u on interface '%s.%i'", port, i->hardware->name, i->protocol);
             return;
         }
 
-        if (ttl != 255) {
+        if (ttl != 255 && s->config.check_response_ttl) {
             avahi_log_warn("Recieved response with invalid TTL %u on interface '%s.%i'.", ttl, i->hardware->name, i->protocol);
-            if (s->config.check_response_ttl)
-                return;
+            return;
         }
 
+        if (!is_mdns_mcast_address(dest) &&
+            !avahi_interface_address_on_link(i, &a)) {
+            avahi_log_warn("Recivied non-local response on interface '%s.%i'.", i->hardware->name, i->protocol);
+            return;
+        }
+        
         if (avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_QDCOUNT) != 0 ||
             avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_ANCOUNT) == 0 ||
             avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_NSCOUNT) != 0) {
@@ -920,7 +933,7 @@ static void dispatch_packet(AvahiServer *s, AvahiDnsPacket *p, const struct sock
     }
 }
 
-static void dispatch_legacy_unicast_packet(AvahiServer *s, AvahiDnsPacket *p, const struct sockaddr *sa, gint iface, gint ttl) {
+static void dispatch_legacy_unicast_packet(AvahiServer *s, AvahiDnsPacket *p, const struct sockaddr *sa, AvahiIfIndex iface, gint ttl) {
     AvahiInterface *i, *j;
     AvahiAddress a;
     guint16 port;
@@ -973,6 +986,7 @@ static void dispatch_legacy_unicast_packet(AvahiServer *s, AvahiDnsPacket *p, co
 static void work(AvahiServer *s) {
     struct sockaddr_in6 sa6;
     struct sockaddr_in sa;
+    AvahiAddress dest;
     AvahiDnsPacket *p;
     gint iface = 0;
     guint8 ttl;
@@ -980,28 +994,32 @@ static void work(AvahiServer *s) {
     g_assert(s);
 
     if (s->fd_ipv4 >= 0 && (s->pollfd_ipv4.revents & G_IO_IN)) {
-        if ((p = avahi_recv_dns_packet_ipv4(s->fd_ipv4, &sa, &iface, &ttl))) {
-            dispatch_packet(s, p, (struct sockaddr*) &sa, iface, ttl);
+        dest.family = AVAHI_PROTO_INET;
+        if ((p = avahi_recv_dns_packet_ipv4(s->fd_ipv4, &sa, &dest.data.ipv4, &iface, &ttl))) {
+            dispatch_packet(s, p, (struct sockaddr*) &sa, &dest, iface, ttl);
             avahi_dns_packet_free(p);
         }
     }
 
     if (s->fd_ipv6 >= 0 && (s->pollfd_ipv6.revents & G_IO_IN)) {
-        if ((p = avahi_recv_dns_packet_ipv6(s->fd_ipv6, &sa6, &iface, &ttl))) {
-            dispatch_packet(s, p, (struct sockaddr*) &sa6, iface, ttl);
+        dest.family = AVAHI_PROTO_INET6;
+        if ((p = avahi_recv_dns_packet_ipv6(s->fd_ipv6, &sa6, &dest.data.ipv6, &iface, &ttl))) {
+            dispatch_packet(s, p, (struct sockaddr*) &sa6, &dest, iface, ttl);
             avahi_dns_packet_free(p);
         }
     }
 
     if (s->fd_legacy_unicast_ipv4 >= 0 && (s->pollfd_legacy_unicast_ipv4.revents & G_IO_IN)) {
-        if ((p = avahi_recv_dns_packet_ipv4(s->fd_legacy_unicast_ipv4, &sa, &iface, &ttl))) {
+        dest.family = AVAHI_PROTO_INET;
+        if ((p = avahi_recv_dns_packet_ipv4(s->fd_legacy_unicast_ipv4, &sa, &dest.data.ipv4, &iface, &ttl))) {
             dispatch_legacy_unicast_packet(s, p, (struct sockaddr*) &sa, iface, ttl);
             avahi_dns_packet_free(p);
         }
     }
 
     if (s->fd_legacy_unicast_ipv6 >= 0 && (s->pollfd_legacy_unicast_ipv6.revents & G_IO_IN)) {
-        if ((p = avahi_recv_dns_packet_ipv6(s->fd_legacy_unicast_ipv6, &sa6, &iface, &ttl))) {
+        dest.family = AVAHI_PROTO_INET6;
+        if ((p = avahi_recv_dns_packet_ipv6(s->fd_legacy_unicast_ipv6, &sa6, &dest.data.ipv6, &iface, &ttl))) {
             dispatch_legacy_unicast_packet(s, p, (struct sockaddr*) &sa6, iface, ttl);
             avahi_dns_packet_free(p);
         }
@@ -1126,7 +1144,7 @@ static void register_hinfo(AvahiServer *s) {
     uname(&utsname);
     r->data.hinfo.cpu = g_strdup(g_strup(utsname.machine));
     r->data.hinfo.os = g_strdup(g_strup(utsname.sysname));
-    avahi_server_add(s, s->hinfo_entry_group, 0, AF_UNSPEC, AVAHI_ENTRY_UNIQUE, r);
+    avahi_server_add(s, s->hinfo_entry_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, AVAHI_ENTRY_UNIQUE, r);
     avahi_record_unref(r);
 
     avahi_entry_group_commit(s->hinfo_entry_group);
@@ -1137,11 +1155,11 @@ static void register_localhost(AvahiServer *s) {
     g_assert(s);
     
     /* Add localhost entries */
-    avahi_address_parse("127.0.0.1", AF_INET, &a);
-    avahi_server_add_address(s, NULL, 0, AF_UNSPEC, AVAHI_ENTRY_NOPROBE|AVAHI_ENTRY_NOANNOUNCE, "localhost", &a);
+    avahi_address_parse("127.0.0.1", AVAHI_PROTO_INET, &a);
+    avahi_server_add_address(s, NULL, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, AVAHI_ENTRY_NOPROBE|AVAHI_ENTRY_NOANNOUNCE, "localhost", &a);
 
-    avahi_address_parse("::1", AF_INET6, &a);
-    avahi_server_add_address(s, NULL, 0, AF_UNSPEC, AVAHI_ENTRY_NOPROBE|AVAHI_ENTRY_NOANNOUNCE, "ip6-localhost", &a);
+    avahi_address_parse("::1", AVAHI_PROTO_INET6, &a);
+    avahi_server_add_address(s, NULL, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, AVAHI_ENTRY_NOPROBE|AVAHI_ENTRY_NOANNOUNCE, "ip6-localhost", &a);
 }
 
 static void register_browse_domain(AvahiServer *s) {
@@ -1151,7 +1169,7 @@ static void register_browse_domain(AvahiServer *s) {
         return;
 
     s->browse_domain_entry_group = avahi_entry_group_new(s, NULL, NULL);
-    avahi_server_add_ptr(s, s->browse_domain_entry_group, 0, AF_UNSPEC, 0, "b._dns-sd._udp.local", s->domain_name);
+    avahi_server_add_ptr(s, s->browse_domain_entry_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, "b._dns-sd._udp.local", s->domain_name);
     avahi_entry_group_commit(s->browse_domain_entry_group);
 }
 
@@ -1429,8 +1447,8 @@ static gint check_record_conflict(AvahiServer *s, gint interface, guchar protoco
         if (interface <= 0 ||
             e->interface <= 0 ||
             e->interface == interface ||
-            protocol == AF_UNSPEC ||
-            e->protocol == AF_UNSPEC ||
+            protocol == AVAHI_PROTO_UNSPEC ||
+            e->protocol == AVAHI_PROTO_UNSPEC ||
             e->protocol == protocol)
 
             return -1;
@@ -1449,10 +1467,12 @@ gint avahi_server_add(
     AvahiRecord *r) {
     
     AvahiEntry *e, *t;
+    
     g_assert(s);
     g_assert(r);
 
-    g_assert(r->key->type != AVAHI_DNS_TYPE_ANY);
+    if (avahi_key_is_pattern(r->key))
+        return -1;
 
     if (check_record_conflict(s, interface, protocol, r, flags) < 0)
         return -1;
@@ -1559,7 +1579,7 @@ gint avahi_server_add_address(
 
     name = name ? (n = avahi_normalize_name(name)) : s->host_name_fqdn;
     
-    if (a->family == AF_INET) {
+    if (a->family == AVAHI_PROTO_INET) {
         gchar *reverse;
         AvahiRecord  *r;
 
@@ -1809,9 +1829,9 @@ gint avahi_server_add_dns_server_address(
     g_assert(s);
     g_assert(address);
     g_assert(type == AVAHI_DNS_SERVER_UPDATE || type == AVAHI_DNS_SERVER_RESOLVE);
-    g_assert(address->family == AF_INET || address->family == AF_INET6);
+    g_assert(address->family == AVAHI_PROTO_INET || address->family == AVAHI_PROTO_INET6);
 
-    if (address->family == AF_INET) {
+    if (address->family == AVAHI_PROTO_INET) {
         hexstring(n+2, sizeof(n)-2, &address->data, 4);
         r = avahi_record_new_full(n, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_A);
         r->data.a.address = address->data.ipv4;
@@ -2019,7 +2039,7 @@ AvahiServerConfig* avahi_server_config_init(AvahiServerConfig *c) {
     c->use_ipv4 = TRUE;
     c->host_name = NULL;
     c->domain_name = NULL;
-    c->check_response_ttl = TRUE;
+    c->check_response_ttl = FALSE;
     c->publish_hinfo = TRUE;
     c->publish_addresses = TRUE;
     c->publish_workstation = TRUE;
index b635dca467bab68d22548c0c47631195ab3ab6eb..1b1f2fdec454f4f9a4de025ddeff09159b48a02a 100644 (file)
@@ -48,7 +48,7 @@ static void mdns_mcast_group_ipv4(struct sockaddr_in *ret_sa) {
     
     ret_sa->sin_family = AF_INET;
     ret_sa->sin_port = htons(AVAHI_MDNS_PORT);
-    inet_pton(AF_INET, "224.0.0.251", &ret_sa->sin_addr);
+    inet_pton(AF_INET, AVAHI_IPV4_MCAST_GROUP, &ret_sa->sin_addr);
 }
 
 static void mdns_mcast_group_ipv6(struct sockaddr_in6 *ret_sa) {
@@ -59,7 +59,7 @@ static void mdns_mcast_group_ipv6(struct sockaddr_in6 *ret_sa) {
     
     ret_sa->sin6_family = AF_INET6;
     ret_sa->sin6_port = htons(AVAHI_MDNS_PORT);
-    inet_pton(AF_INET6, "ff02::fb", &ret_sa->sin6_addr);
+    inet_pton(AF_INET6, AVAHI_IPV6_MCAST_GROUP, &ret_sa->sin6_addr);
 }
 
 static void ipv4_address_to_sockaddr(struct sockaddr_in *ret_sa, const AvahiIPv4Address *a, guint16 port) {
@@ -399,7 +399,7 @@ gint avahi_send_dns_packet_ipv4(gint fd, gint interface, AvahiDnsPacket *p, cons
     msg.msg_controllen = sizeof(cmsg_data);
     msg.msg_flags = 0;
 
-    return sendmsg_loop(fd, &msg, MSG_DONTROUTE);
+    return sendmsg_loop(fd, &msg, 0 /*MSG_DONTROUTE*/);
 }
 
 gint avahi_send_dns_packet_ipv6(gint fd, gint interface, AvahiDnsPacket *p, const AvahiIPv6Address *a, guint16 port) {
@@ -441,10 +441,10 @@ gint avahi_send_dns_packet_ipv6(gint fd, gint interface, AvahiDnsPacket *p, cons
     msg.msg_controllen = sizeof(cmsg_data);
     msg.msg_flags = 0;
 
-    return sendmsg_loop(fd, &msg, MSG_DONTROUTE);
+    return sendmsg_loop(fd, &msg, 0 /*MSG_DONTROUTE*/);
 }
 
-AvahiDnsPacket* avahi_recv_dns_packet_ipv4(gint fd, struct sockaddr_in *ret_sa, gint *ret_iface, guint8* ret_ttl) {
+AvahiDnsPacket* avahi_recv_dns_packet_ipv4(gint fd, struct sockaddr_in *ret_sa, AvahiIPv4Address *ret_dest_address, gint *ret_iface, guint8* ret_ttl) {
     AvahiDnsPacket *p= NULL;
     struct msghdr msg;
     struct iovec io;
@@ -456,6 +456,7 @@ AvahiDnsPacket* avahi_recv_dns_packet_ipv4(gint fd, struct sockaddr_in *ret_sa,
 
     g_assert(fd >= 0);
     g_assert(ret_sa);
+    g_assert(ret_dest_address);
     g_assert(ret_iface);
     g_assert(ret_ttl);
 
@@ -487,8 +488,6 @@ AvahiDnsPacket* avahi_recv_dns_packet_ipv4(gint fd, struct sockaddr_in *ret_sa,
         /* Linux 2.4 behaves very strangely sometimes! */
 
         avahi_hexdump(AVAHI_DNS_PACKET_DATA(p), l); 
-        
-        
         goto fail;
     }
     
@@ -510,7 +509,9 @@ AvahiDnsPacket* avahi_recv_dns_packet_ipv4(gint fd, struct sockaddr_in *ret_sa,
                 *ret_ttl = (uint8_t) (*(int *) CMSG_DATA(cmsg));
                 found_ttl = TRUE;
             } else if (cmsg->cmsg_type == IP_PKTINFO) {
-                *ret_iface = (gint) ((struct in_pktinfo*) CMSG_DATA(cmsg))->ipi_ifindex;
+                struct in_pktinfo *i = (struct in_pktinfo*) CMSG_DATA(cmsg);
+                *ret_iface = (gint) i->ipi_ifindex;
+                ret_dest_address->address = i->ipi_addr.s_addr;
                 found_iface = TRUE;
             }
         }
@@ -530,7 +531,7 @@ fail:
     return NULL;
 }
 
-AvahiDnsPacket* avahi_recv_dns_packet_ipv6(gint fd, struct sockaddr_in6 *ret_sa, gint *ret_iface, guint8* ret_ttl) {
+AvahiDnsPacket* avahi_recv_dns_packet_ipv6(gint fd, struct sockaddr_in6 *ret_sa, AvahiIPv6Address *ret_dest_address, gint *ret_iface, guint8* ret_ttl) {
     AvahiDnsPacket *p = NULL;
     struct msghdr msg;
     struct iovec io;
@@ -543,6 +544,7 @@ AvahiDnsPacket* avahi_recv_dns_packet_ipv6(gint fd, struct sockaddr_in6 *ret_sa,
 
     g_assert(fd >= 0);
     g_assert(ret_sa);
+    g_assert(ret_dest_address);
     g_assert(ret_iface);
     g_assert(ret_ttl);
 
@@ -581,7 +583,9 @@ AvahiDnsPacket* avahi_recv_dns_packet_ipv6(gint fd, struct sockaddr_in6 *ret_sa,
         }
             
         if (cmsg->cmsg_level == SOL_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) {
-            *ret_iface = ((struct in6_pktinfo*) CMSG_DATA(cmsg))->ipi6_ifindex;
+            struct in6_pktinfo *i = (struct in6_pktinfo*) CMSG_DATA(cmsg);
+            *ret_iface = i->ipi6_ifindex;
+            memcpy(ret_dest_address->address, i->ipi6_addr.s6_addr, 16);
             found_iface = TRUE;
         }
     }
index 03eafb0911b85479d6989025e7c93b677868c20c..dc0bbdd9bd7ec4b46cb9183093cf1e8f6e1173f8 100644 (file)
@@ -27,6 +27,8 @@
 #include "dns.h"
 
 #define AVAHI_MDNS_PORT 5353
+#define AVAHI_IPV4_MCAST_GROUP "224.0.0.251"
+#define AVAHI_IPV6_MCAST_GROUP "ff02::fb"
 
 gint avahi_open_socket_ipv4(void);
 gint avahi_open_socket_ipv6(void);
@@ -37,8 +39,8 @@ gint avahi_open_legacy_unicast_socket_ipv6(void);
 gint avahi_send_dns_packet_ipv4(gint fd, gint iface, AvahiDnsPacket *p, const AvahiIPv4Address *a, guint16 port);
 gint avahi_send_dns_packet_ipv6(gint fd, gint iface, AvahiDnsPacket *p, const AvahiIPv6Address *a, guint16 port);
 
-AvahiDnsPacket *avahi_recv_dns_packet_ipv4(gint fd, struct sockaddr_in*ret_sa, gint *ret_iface, guint8 *ret_ttl);
-AvahiDnsPacket *avahi_recv_dns_packet_ipv6(gint fd, struct sockaddr_in6*ret_sa, gint *ret_iface, guint8 *ret_ttl);
+AvahiDnsPacket *avahi_recv_dns_packet_ipv4(gint fd, struct sockaddr_in*ret_sa, AvahiIPv4Address *ret_dest_address, gint *ret_iface, guint8 *ret_ttl);
+AvahiDnsPacket *avahi_recv_dns_packet_ipv6(gint fd, struct sockaddr_in6*ret_sa, AvahiIPv6Address *ret_dest_address, gint *ret_iface, guint8 *ret_ttl);
 
 int avahi_mdns_mcast_join_ipv4(int index, int fd);
 int avahi_mdns_mcast_join_ipv6(int index, int fd);
index 82f5326ad3c7afd9a26979ceb655ed9016e3b76b..fc47ecfacbe0115e22441244f98869061e08df13 100644 (file)
@@ -3,7 +3,7 @@
 #domain-name=local
 use-ipv4=yes
 use-ipv6=no
-check-response-ttl=yes
+check-response-ttl=no
 use-iff-running=yes
 enable-dbus=yes