Index: avahi-daemon/main.c =================================================================== --- avahi-daemon/main.c (revision 1781) +++ avahi-daemon/main.c (working copy) @@ -601,6 +601,14 @@ } } #endif + else if (strcasecmp(p->key, "bind-ipv4") == 0) { + if (inet_pton(AF_INET, p->value, &(c->server_config.bind_ipv4)) < 0) + avahi_log_error("Invalid address \"%s\" for key \"%s\" in group \"%s\"\n", p->value, p->key, g->name); + } + else if (strcasecmp(p->key, "bind-ipv6") == 0) { + if (inet_pton(AF_INET6, p->value, &(c->server_config.bind_ipv6)) < 0) + avahi_log_error("Invalid address \"%s\" for key \"%s\" in group \"%s\"\n", p->value, p->key, g->name); + } else { avahi_log_error("Invalid configuration key \"%s\" in group \"%s\"\n", p->key, g->name); goto finish; Index: avahi-core/wide-area.c =================================================================== --- avahi-core/wide-area.c (revision 1781) +++ avahi-core/wide-area.c (working copy) @@ -579,8 +579,8 @@ e->cleanup_dead = 0; /* Create sockets */ - e->fd_ipv4 = s->config.use_ipv4 ? avahi_open_unicast_socket_ipv4() : -1; - e->fd_ipv6 = s->config.use_ipv6 ? avahi_open_unicast_socket_ipv6() : -1; + e->fd_ipv4 = s->config.use_ipv4 ? avahi_open_unicast_socket_ipv4(&(s->config.bind_ipv4)) : -1; + e->fd_ipv6 = s->config.use_ipv6 ? avahi_open_unicast_socket_ipv6(&(s->config.bind_ipv6)) : -1; if (e->fd_ipv4 < 0 && e->fd_ipv6 < 0) { avahi_log_error(__FILE__": Failed to create wide area sockets: %s", strerror(errno)); Index: avahi-core/core.h =================================================================== --- avahi-core/core.h (revision 1781) +++ avahi-core/core.h (working copy) @@ -46,7 +46,9 @@ char *host_name; /**< Default host name. If left empty defaults to the result of gethostname(2) of the libc */ char *domain_name; /**< Default domain name. If left empty defaults to .local */ int use_ipv4; /**< Enable IPv4 support */ + AvahiIPv4Address bind_ipv4; /**< Bind to a specific IPv4 address */ int use_ipv6; /**< Enable IPv6 support */ + AvahiIPv6Address bind_ipv6; /**< Bind to a specific IPv6 address */ int publish_hinfo; /**< Register a HINFO record for the host containing the local OS and CPU type */ int publish_addresses; /**< Register A, AAAA and PTR records for all local IP addresses */ int publish_workstation; /**< Register a _workstation._tcp service */ Index: avahi-core/server.c =================================================================== --- avahi-core/server.c (revision 1781) +++ avahi-core/server.c (working copy) @@ -1314,8 +1314,8 @@ static int setup_sockets(AvahiServer *s) { assert(s); - s->fd_ipv4 = s->config.use_ipv4 ? avahi_open_socket_ipv4(s->config.disallow_other_stacks) : -1; - s->fd_ipv6 = s->config.use_ipv6 ? avahi_open_socket_ipv6(s->config.disallow_other_stacks) : -1; + s->fd_ipv4 = s->config.use_ipv4 ? avahi_open_socket_ipv4(&(s->config.bind_ipv4), s->config.disallow_other_stacks) : -1; + s->fd_ipv6 = s->config.use_ipv6 ? avahi_open_socket_ipv6(&(s->config.bind_ipv6), s->config.disallow_other_stacks) : -1; if (s->fd_ipv6 < 0 && s->fd_ipv4 < 0) return AVAHI_ERR_NO_NETWORK; @@ -1325,8 +1325,8 @@ else if (s->fd_ipv6 < 0 && s->config.use_ipv6) avahi_log_notice("Failed to create IPv6 socket, proceeding in IPv4 only mode"); - s->fd_legacy_unicast_ipv4 = s->fd_ipv4 >= 0 && s->config.enable_reflector ? avahi_open_unicast_socket_ipv4() : -1; - s->fd_legacy_unicast_ipv6 = s->fd_ipv6 >= 0 && s->config.enable_reflector ? avahi_open_unicast_socket_ipv6() : -1; + s->fd_legacy_unicast_ipv4 = s->fd_ipv4 >= 0 && s->config.enable_reflector ? avahi_open_unicast_socket_ipv4(&(s->config.bind_ipv4)) : -1; + s->fd_legacy_unicast_ipv6 = s->fd_ipv6 >= 0 && s->config.enable_reflector ? avahi_open_unicast_socket_ipv6(&(s->config.bind_ipv6)) : -1; s->watch_ipv4 = s->watch_ipv6 = @@ -1561,7 +1561,9 @@ memset(c, 0, sizeof(AvahiServerConfig)); c->use_ipv6 = 1; + inet_pton(AF_INET6, "::", &(c->bind_ipv6)); c->use_ipv4 = 1; + inet_pton(AF_INET, "0.0.0.0", &(c->bind_ipv4)); c->host_name = NULL; c->domain_name = NULL; c->check_response_ttl = 0; Index: avahi-core/socket.c =================================================================== --- avahi-core/socket.c (revision 1781) +++ avahi-core/socket.c (working copy) @@ -309,7 +309,7 @@ return 0; } -int avahi_open_socket_ipv4(int no_reuse) { +int avahi_open_socket_ipv4(AvahiIPv4Address *bind_ipv4, int no_reuse) { struct sockaddr_in local; int fd = -1, r, ittl; uint8_t ttl, cyes; @@ -338,8 +338,7 @@ } memset(&local, 0, sizeof(local)); - local.sin_family = AF_INET; - local.sin_port = htons(AVAHI_MDNS_PORT); + ipv4_address_to_sockaddr(&local, bind_ipv4, AVAHI_MDNS_PORT); if (no_reuse) r = bind(fd, (struct sockaddr*) &local, sizeof(local)); @@ -371,7 +370,7 @@ return -1; } -int avahi_open_socket_ipv6(int no_reuse) { +int avahi_open_socket_ipv6(AvahiIPv6Address *bind_ipv6, int no_reuse) { struct sockaddr_in6 sa, local; int fd = -1, yes, r; int ttl; @@ -408,8 +407,7 @@ } memset(&local, 0, sizeof(local)); - local.sin6_family = AF_INET6; - local.sin6_port = htons(AVAHI_MDNS_PORT); + ipv6_address_to_sockaddr(&local, bind_ipv6, AVAHI_MDNS_PORT); if (no_reuse) r = bind(fd, (struct sockaddr*) &local, sizeof(local)); @@ -893,7 +891,7 @@ return NULL; } -int avahi_open_unicast_socket_ipv4(void) { +int avahi_open_unicast_socket_ipv4(AvahiIPv4Address *bind_ipv4) { struct sockaddr_in local; int fd = -1; @@ -903,7 +901,7 @@ } memset(&local, 0, sizeof(local)); - local.sin_family = AF_INET; + ipv4_address_to_sockaddr(&local, bind_ipv4, 0); if (bind(fd, (struct sockaddr*) &local, sizeof(local)) < 0) { avahi_log_warn("bind() failed: %s", strerror(errno)); @@ -933,7 +931,7 @@ return -1; } -int avahi_open_unicast_socket_ipv6(void) { +int avahi_open_unicast_socket_ipv6(AvahiIPv6Address *bind_ipv6) { struct sockaddr_in6 local; int fd = -1, yes; @@ -949,7 +947,7 @@ } memset(&local, 0, sizeof(local)); - local.sin6_family = AF_INET6; + ipv6_address_to_sockaddr(&local, bind_ipv6, 0); if (bind(fd, (struct sockaddr*) &local, sizeof(local)) < 0) { avahi_log_warn("bind() failed: %s", strerror(errno)); Index: avahi-core/socket.h =================================================================== --- avahi-core/socket.h (revision 1781) +++ avahi-core/socket.h (working copy) @@ -31,11 +31,11 @@ #define AVAHI_IPV4_MCAST_GROUP "224.0.0.251" #define AVAHI_IPV6_MCAST_GROUP "ff02::fb" -int avahi_open_socket_ipv4(int no_reuse); -int avahi_open_socket_ipv6(int no_reuse); +int avahi_open_socket_ipv4(AvahiIPv4Address *bind_ipv4, int no_reuse); +int avahi_open_socket_ipv6(AvahiIPv6Address *bind_ipv6, int no_reuse); -int avahi_open_unicast_socket_ipv4(void); -int avahi_open_unicast_socket_ipv6(void); +int avahi_open_unicast_socket_ipv4(AvahiIPv4Address *bind_ipv4); +int avahi_open_unicast_socket_ipv6(AvahiIPv6Address *bind_ipv6); int avahi_send_dns_packet_ipv4(int fd, AvahiIfIndex iface, AvahiDnsPacket *p, const AvahiIPv4Address *src_address, const AvahiIPv4Address *dst_address, uint16_t dst_port); int avahi_send_dns_packet_ipv6(int fd, AvahiIfIndex iface, AvahiDnsPacket *p, const AvahiIPv6Address *src_address, const AvahiIPv6Address *dst_address, uint16_t dst_port);