X-Git-Url: http://git.archive.openwrt.org/?a=blobdiff_plain;f=util.c;h=4684b70a5501f8a4ce47875a2f9643429278c72d;hb=3558e5d49d8560fe7a09ef2034c10615b83974f9;hp=a4a117bc2ef4f49da0b0c90982330cd917654db5;hpb=788316ef66136e6a68d881e5b24ccf5a98fa4550;p=project%2Fmdnsd.git diff --git a/util.c b/util.c index a4a117b..4684b70 100644 --- a/util.c +++ b/util.c @@ -98,6 +98,28 @@ get_iface_ipv4(const char *ifname) return ret; } +int +get_iface_index(const char *ifname) +{ + struct ifreq ir; + int sock; + + sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock < 0) + return 0; + + memset(&ir, 0, sizeof(struct ifreq)); + + strncpy(ir.ifr_name, ifname, sizeof(ir.ifr_name)); + + if (ioctl(sock, SIOCGIFINDEX, &ir) < 0) + return 0; + + close(sock); + + return ir.ifr_ifindex; +} + char* get_hostname(void) { @@ -116,15 +138,19 @@ socket_setup(int fd, const char *ip) uint8_t ttl = 255; int yes = 1; int no = 0; - struct sockaddr_in sa; + struct sockaddr_in sa = { 0 }; + struct in_addr in; + + inet_aton(iface_ip, &in); sa.sin_family = AF_INET; sa.sin_port = htons(MCAST_PORT); inet_pton(AF_INET, MCAST_ADDR, &sa.sin_addr); memset(&mreq, 0, sizeof(mreq)); - mreq.imr_address.s_addr = htonl(INADDR_ANY); + mreq.imr_address.s_addr = in.s_addr; mreq.imr_multiaddr = sa.sin_addr; + mreq.imr_ifindex = iface_index; if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) < 0) fprintf(stderr, "ioctl failed: IP_MULTICAST_TTL\n"); @@ -132,6 +158,13 @@ socket_setup(int fd, const char *ip) if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) fprintf(stderr, "ioctl failed: SO_REUSEADDR\n"); + /* Some network drivers have issues with dropping membership of + * mcast groups when the iface is down, but don't allow rejoining + * when it comes back up. This is an ugly workaround + * -- this was copied from avahi -- + */ + setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)); + if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) { fprintf(stderr, "failed to join multicast group: %s\n", strerror(errno)); close(fd); @@ -152,7 +185,7 @@ socket_setup(int fd, const char *ip) } void* -memdup(void *d, int l) +memdup(const void *d, int l) { void *r = malloc(l); if (!r)