PUD: nwif: make setting ttl on tx socket work for IPv6
[olsrd.git] / lib / pud / src / networkInterfaces.c
index 6f16595..0fdbdce 100644 (file)
@@ -105,7 +105,7 @@ static int createRxSocket(TRxTxNetworkInterface * networkInterface,
        assert(networkInterface->ipAddress.in.sa_family == rxMcAddr->in.sa_family);
 
        memset(&address, 0, sizeof(address));
-       if (olsr_cnf->ip_version == AF_INET) {
+       if (networkInterface->ipAddress.in.sa_family == AF_INET) {
                assert(networkInterface->ipAddress.in4.sin_addr.s_addr != INADDR_ANY);
 
                ipFamilySetting = AF_INET;
@@ -190,7 +190,7 @@ static int createRxSocket(TRxTxNetworkInterface * networkInterface,
                struct ipv6_mreq mc6_settings;
                (void) memset(&mc6_settings, 0, sizeof(mc6_settings));
                mc6_settings.ipv6mr_multiaddr = rxMcAddr->in6.sin6_addr;
-               mc6_settings.ipv6mr_interface = 0;
+               mc6_settings.ipv6mr_interface = if_nametoindex((char *)networkInterface->name);
                errno = 0;
                if (setsockopt(rxSocket, ipProtoSetting, ipAddMembershipSetting,
                                &mc6_settings, sizeof(mc6_settings)) < 0) {
@@ -310,26 +310,28 @@ static int createTxSocket(TRxTxNetworkInterface * networkInterface) {
        int ipProtoSetting;
        int ipMcLoopSetting;
        int ipMcIfSetting;
+       int ipTtlSetting;
 
        union olsr_sockaddr address;
 
        int txSocket = -1;
 
        int mcLoopValue = 0;
-       unsigned char txTtl = getTxTtl();
+       int txTtl = getTxTtl();
 
        assert(networkInterface != NULL);
        assert(strncmp((char *) &networkInterface->name[0], "",
                                        sizeof(networkInterface->name)) != 0);
 
        memset(&address, 0, sizeof(address));
-       if (olsr_cnf->ip_version == AF_INET) {
+       if (networkInterface->ipAddress.in.sa_family == AF_INET) {
                assert(networkInterface->ipAddress.in4.sin_addr.s_addr != INADDR_ANY);
 
                ipFamilySetting = AF_INET;
                ipProtoSetting = IPPROTO_IP;
                ipMcLoopSetting = IP_MULTICAST_LOOP;
                ipMcIfSetting = IP_MULTICAST_IF;
+               ipTtlSetting = IP_MULTICAST_TTL;
 
                address.in4.sin_family = ipFamilySetting;
                address.in4.sin_addr = networkInterface->ipAddress.in4.sin_addr;
@@ -341,6 +343,7 @@ static int createTxSocket(TRxTxNetworkInterface * networkInterface) {
                ipProtoSetting = IPPROTO_IPV6;
                ipMcLoopSetting = IPV6_MULTICAST_LOOP;
                ipMcIfSetting = IPV6_MULTICAST_IF;
+               ipTtlSetting = IPV6_MULTICAST_HOPS;
 
                address.in6.sin6_family = ipFamilySetting;
                address.in6.sin6_addr = networkInterface->ipAddress.in6.sin6_addr;
@@ -377,7 +380,7 @@ static int createTxSocket(TRxTxNetworkInterface * networkInterface) {
 
        /* Set the TTL on the socket */
        errno = 0;
-       if (setsockopt(txSocket, ipProtoSetting, IP_MULTICAST_TTL, &txTtl,
+       if (setsockopt(txSocket, ipProtoSetting, ipTtlSetting, &txTtl,
                        sizeof(txTtl)) < 0) {
                pudError(true, "Could not set TTL on the transmit socket"
                        " for interface %s", networkInterface->name);
@@ -645,6 +648,7 @@ bool createNetworkInterfaces(socket_handler_func rxSocketHandlerFunction,
        struct ifaddrs *ifAddrs = NULL;
        struct ifaddrs *ifAddr = NULL;
        union olsr_sockaddr * rxMcAddr = getRxMcAddr();
+       union olsr_sockaddr * txMcAddr = getTxMcAddr();
 
        errno = 0;
        if (getifaddrs(&ifAddrs) != 0) {
@@ -655,48 +659,47 @@ bool createNetworkInterfaces(socket_handler_func rxSocketHandlerFunction,
        /* loop over all interfaces */
        for (ifAddr = ifAddrs; ifAddr != NULL; ifAddr = ifAddr->ifa_next) {
                union olsr_sockaddr * addr = (union olsr_sockaddr *)ifAddr->ifa_addr;
-               if (addr != NULL) {
-                       int addrFamily = addr->in.sa_family;
-                       if (addrFamily == olsr_cnf->ip_version) {
-                               char * ifName = ifAddr->ifa_name;
-
-                               /* determine whether the iterated interface is an OLSR
-                                * interface: returns NULL when the interface is not an
-                                * OLSR interface */
-                               struct interface *olsrIntf = if_ifwithname(ifName);
-                               bool isOlsrIf = (olsrIntf != NULL);
-
-                               /* determine whether the iterated interface is configured as a
-                                * non-OLSR interface in the plugin parameter list */
-                               bool isRxNonOlsrIf = isRxNonOlsrInterface(ifName);
-                               bool isTxNonOlsrIf = isTxNonOlsrInterface(ifName);
-                               bool isNonOlsrIf = isRxNonOlsrIf || isTxNonOlsrIf;
-
-                               if (!isOlsrIf && !isNonOlsrIf) {
-                                       /* Interface is not an OLSR interface AND interface is not
-                                        * configured as non-OLSR interface: skip */
-                                       continue;
-                               }
-
-                               if (isOlsrIf && !createOlsrInterface(olsrIntf)) {
-                                       /* creating an OLSR interface failed */
-                                       goto end;
-                               }
-
-                               if (!isNonOlsrIf) {
-                                       /* interface is not configured as non-OLSR interface: skip */
-                                       continue;
-                               }
-
-                               if (isRxNonOlsrIf && !createRxInterface(ifName, addr, rxSocketHandlerFunction, rxMcAddr)) {
-                                       /* creating a receive interface failed */
-                                       goto end;
-                               }
-
-                               if (isTxNonOlsrIf && !createTxInterface(ifName, addr)) {
-                                       /* creating a transmit interface failed */
-                                       goto end;
-                               }
+               if ((addr != NULL) && ((addr->in.sa_family == AF_INET) || (addr->in.sa_family == AF_INET6))) {
+                       char * ifName = ifAddr->ifa_name;
+
+                       struct interface * olsrIntf = ((addr->in.sa_family != olsr_cnf->ip_version) ?
+                                       NULL :
+                                       if_ifwithaddr((addr->in.sa_family == AF_INET) ?
+                                                       (union olsr_ip_addr *)&addr->in4.sin_addr :
+                                                       (union olsr_ip_addr *)&addr->in6.sin6_addr));
+                       bool isOlsrIf = (olsrIntf != NULL);
+
+                       /* determine whether the iterated interface is configured as a
+                        * non-OLSR interface in the plugin parameter list */
+                       bool isRxNonOlsrIf = isRxNonOlsrInterface(ifName) && (addr->in.sa_family == rxMcAddr->in.sa_family);
+                       bool isTxNonOlsrIf = isTxNonOlsrInterface(ifName) && (addr->in.sa_family == txMcAddr->in.sa_family);
+
+                       bool isNonOlsrIf = isRxNonOlsrIf || isTxNonOlsrIf;
+
+                       if (!isOlsrIf && !isNonOlsrIf) {
+                               /* Interface is not an OLSR interface AND interface is not
+                                * configured as non-OLSR interface: skip */
+                               continue;
+                       }
+
+                       if (isOlsrIf && !createOlsrInterface(olsrIntf)) {
+                               /* creating an OLSR interface failed */
+                               goto end;
+                       }
+
+                       if (!isNonOlsrIf) {
+                               /* interface is not configured as non-OLSR interface: skip */
+                               continue;
+                       }
+
+                       if (isRxNonOlsrIf && !createRxInterface(ifName, addr, rxSocketHandlerFunction, rxMcAddr)) {
+                               /* creating a receive interface failed */
+                               goto end;
+                       }
+
+                       if (isTxNonOlsrIf && !createTxInterface(ifName, addr)) {
+                               /* creating a transmit interface failed */
+                               goto end;
                        }
                }
        }