Fix issues found by Coverity.
[oweals/tinc.git] / src / multicast_device.c
index 392fd3713e03fd33232404fe81e186ae43f60044..ad0185a3797f1000c4933102a83b958a497ce380 100644 (file)
@@ -1,7 +1,7 @@
 /*
     device.c -- multicast socket
     Copyright (C) 2002-2005 Ivo Timmermans,
-                  2002-2012 Guus Sliepen <guus@tinc-vpn.org>
+                  2002-2013 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -35,7 +35,7 @@ static uint64_t device_total_in = 0;
 static uint64_t device_total_out = 0;
 
 static struct addrinfo *ai = NULL;
-static mac_t ignore_src = {0};
+static mac_t ignore_src = {{0}};
 
 static bool setup_device(void) {
        char *host;
@@ -56,6 +56,7 @@ static bool setup_device(void) {
        space = strchr(host, ' ');
        if(!space) {
                logger(LOG_ERR, "Port number required for %s", device_info);
+               free(host);
                return false;
        }
 
@@ -75,6 +76,7 @@ static bool setup_device(void) {
        device_fd = socket(ai->ai_family, SOCK_DGRAM, IPPROTO_UDP);
        if(device_fd < 0) {
                logger(LOG_ERR, "Creating socket failed: %s", sockstrerror(sockerrno));
+               free(host);
                return false;
        }
 
@@ -88,46 +90,63 @@ static bool setup_device(void) {
        if(bind(device_fd, ai->ai_addr, ai->ai_addrlen)) {
                closesocket(device_fd);
                logger(LOG_ERR, "Can't bind to %s %s: %s", host, port, sockstrerror(sockerrno));
+               free(host);
                return false;
        }
 
        switch(ai->ai_family) {
+#ifdef IP_ADD_MEMBERSHIP
                case AF_INET: {
                        struct ip_mreq mreq;
                        struct sockaddr_in in;
                        memcpy(&in, ai->ai_addr, sizeof in);
                        mreq.imr_multiaddr.s_addr = in.sin_addr.s_addr;
                        mreq.imr_interface.s_addr = htonl(INADDR_ANY);
-                       if(setsockopt(device_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof mreq)) {
+                       if(setsockopt(device_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&mreq, sizeof mreq)) {
                                logger(LOG_ERR, "Cannot join multicast group %s %s: %s", host, port, sockstrerror(sockerrno));
                                closesocket(device_fd);
+                               free(host);
                                return false;
                        }
-                       setsockopt(device_fd, IPPROTO_IP, IP_MULTICAST_LOOP, &one, sizeof one);
-                       setsockopt(device_fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof ttl);
+#ifdef IP_MULTICAST_LOOP
+                       setsockopt(device_fd, IPPROTO_IP, IP_MULTICAST_LOOP, (const void *)&one, sizeof one);
+#endif
+#ifdef IP_MULTICAST_TTL
+                       setsockopt(device_fd, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&ttl, sizeof ttl);
+#endif
                } break;
+#endif
 
+#ifdef IPV6_JOIN_GROUP
                case AF_INET6: {
                        struct ipv6_mreq mreq;
                        struct sockaddr_in6 in6;
                        memcpy(&in6, ai->ai_addr, sizeof in6);
                        memcpy(&mreq.ipv6mr_multiaddr, &in6.sin6_addr, sizeof mreq.ipv6mr_multiaddr);
-                       mreq.ipv6mr_interface = 0;
-                       if(setsockopt(device_fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof mreq)) {
+                       mreq.ipv6mr_interface = in6.sin6_scope_id;
+                       if(setsockopt(device_fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, (void *)&mreq, sizeof mreq)) {
                                logger(LOG_ERR, "Cannot join multicast group %s %s: %s", host, port, sockstrerror(sockerrno));
                                closesocket(device_fd);
+                               free(host);
                                return false;
                        }
-                       setsockopt(device_fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &one, sizeof one);
-                       setsockopt(device_fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof ttl);
+#ifdef IPV6_MULTICAST_LOOP
+                       setsockopt(device_fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (const void *)&one, sizeof one);
+#endif
+#ifdef IPV6_MULTICAST_HOPS
+                       setsockopt(device_fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (void *)&ttl, sizeof ttl);
+#endif
                } break;
+#endif
        
                default:
                        logger(LOG_ERR, "Multicast for address family %hx unsupported", ai->ai_family);
                        closesocket(device_fd);
+                       free(host);
                        return false;
        }
 
+       free(host);
        logger(LOG_INFO, "%s is a %s", device, device_info);
 
        return true;
@@ -146,7 +165,7 @@ static void close_device(void) {
 static bool read_packet(vpn_packet_t *packet) {
        int lenin;
 
-       if((lenin = recv(device_fd, packet->data, MTU, 0)) <= 0) {
+       if((lenin = recv(device_fd, (void *)packet->data, MTU, 0)) <= 0) {
                logger(LOG_ERR, "Error while reading from %s %s: %s", device_info,
                           device, strerror(errno));
                return false;
@@ -172,7 +191,7 @@ static bool write_packet(vpn_packet_t *packet) {
        ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s",
                           packet->len, device_info);
 
-       if(sendto(device_fd, packet->data, packet->len, 0, ai->ai_addr, ai->ai_addrlen) < 0) {
+       if(sendto(device_fd, (void *)packet->data, packet->len, 0, ai->ai_addr, ai->ai_addrlen) < 0) {
                logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device,
                           strerror(errno));
                return false;