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;
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;
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;
#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
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) {
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);
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);
enum {
AVAHI_DNS_CLASS_IN = 0x01,
+ AVAHI_DNS_CLASS_ANY = 0xFF,
AVAHI_DNS_CACHE_FLUSH = 0x8000,
AVAHI_DNS_UNICAST_RESPONSE = 0x8000
};
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)
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)
#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
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) {
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);
else if ((pa && !pb) || (!pa && pb))
return FALSE;
- if (utf8_strcasecmp(pa, pb))
+ if (g_ascii_strcasecmp(pa, pb))
return FALSE;
}
guint hash = 0;
for (;;) {
- gchar c[65], *n, *m;
+ gchar c[65], *m;
if (!avahi_unescape_label(&s, c, sizeof(c)))
return hash;
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);
}
}
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");
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;
}
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);
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 */
/** 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);
gint avahi_server_add_address(
AvahiServer *s,
AvahiEntryGroup *g,
- gint interface,
- guchar protocol,
+ AvahiIfIndex interface,
+ AvahiProtocol protocol,
AvahiEntryFlags flags,
const gchar *name,
AvahiAddress *a);
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 */);
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);
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);
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,
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,
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,
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,
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 */
} 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);
* 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
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;
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;
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;
} 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);
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;
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)))
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:
;
}
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);
}
-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;
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);
/* 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);
}
}
-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)))
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;
+}
AvahiInterfaceMonitor *monitor;
gchar *name;
- gint index;
+ AvahiIfIndex index;
guint flags;
guint mtu;
AvahiInterfaceMonitor *monitor;
AvahiHwInterface *hardware;
- guchar protocol;
+ AvahiProtocol protocol;
gboolean announcing;
AvahiCache *cache;
guchar flags;
guchar scope;
+ guchar prefix_len;
AvahiAddress address;
AvahiEntryGroup *entry_group;
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);
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
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) {
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;
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);
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;
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) {
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;
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);
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;
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) {
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);
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;
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);
}
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); */
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);
}
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;
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)) ||
/* 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) {
}
}
-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;
static void work(AvahiServer *s) {
struct sockaddr_in6 sa6;
struct sockaddr_in sa;
+ AvahiAddress dest;
AvahiDnsPacket *p;
gint iface = 0;
guint8 ttl;
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);
}
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);
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) {
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);
}
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;
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;
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;
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;
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;
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) {
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) {
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) {
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;
g_assert(fd >= 0);
g_assert(ret_sa);
+ g_assert(ret_dest_address);
g_assert(ret_iface);
g_assert(ret_ttl);
/* Linux 2.4 behaves very strangely sometimes! */
avahi_hexdump(AVAHI_DNS_PACKET_DATA(p), l);
-
-
goto fail;
}
*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;
}
}
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;
g_assert(fd >= 0);
g_assert(ret_sa);
+ g_assert(ret_dest_address);
g_assert(ret_iface);
g_assert(ret_ttl);
}
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;
}
}
#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);
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);
#domain-name=local
use-ipv4=yes
use-ipv6=no
-check-response-ttl=yes
+check-response-ttl=no
use-iff-running=yes
enable-dbus=yes