net: NetworkMonitor: set scope_id on link-local IPv6 addresses

Change-Id: I20854d1e1eb7f823a1808cc98e7e5f79a0b78aca
Refs: #1428
diff --git a/src/net/detail/network-monitor-impl-osx.cpp b/src/net/detail/network-monitor-impl-osx.cpp
index ebf90b0..ddd4119 100644
--- a/src/net/detail/network-monitor-impl-osx.cpp
+++ b/src/net/detail/network-monitor-impl-osx.cpp
@@ -56,11 +56,11 @@
 #include "../../name.hpp"
 #include "../../util/logger.hpp"
 
-#include <ifaddrs.h>       // for getifaddrs()
-#include <arpa/inet.h>     // for inet_ntop()
-#include <netinet/in.h>    // for struct sockaddr_in{,6}
-#include <net/if_dl.h>     // for struct sockaddr_dl
-#include <net/if_types.h>  // for IFT_* constants
+#include <ifaddrs.h>      // for getifaddrs()
+#include <net/if.h>       // for if_nametoindex()
+#include <net/if_dl.h>    // for struct sockaddr_dl
+#include <net/if_types.h> // for IFT_* constants
+#include <netinet/in.h>   // for struct sockaddr_in{,6}
 
 #include <boost/asio/io_service.hpp>
 #include <boost/asio/ip/address.hpp>
@@ -357,7 +357,10 @@
         const sockaddr_in6* sin6 = reinterpret_cast<sockaddr_in6*>(ifa->ifa_addr);
         ip::address_v6::bytes_type bytes;
         std::copy_n(reinterpret_cast<const unsigned char*>(&sin6->sin6_addr), bytes.size(), bytes.begin());
-        ipAddr = ip::address_v6(bytes);
+        ip::address_v6 v6Addr(bytes);
+        if (v6Addr.is_link_local())
+          v6Addr.scope_id(if_nametoindex(netif.getName().data()));
+        ipAddr = v6Addr;
 
         const sockaddr_in6* sinMask = reinterpret_cast<sockaddr_in6*>(ifa->ifa_netmask);
         std::copy_n(reinterpret_cast<const unsigned char*>(&sinMask->sin6_addr), bytes.size(), bytes.begin());
diff --git a/src/net/detail/network-monitor-impl-rtnl.cpp b/src/net/detail/network-monitor-impl-rtnl.cpp
index dbc6815..02c84fb 100644
--- a/src/net/detail/network-monitor-impl-rtnl.cpp
+++ b/src/net/detail/network-monitor-impl-rtnl.cpp
@@ -420,7 +420,7 @@
   BOOST_ASSERT(interface != nullptr);
 
   namespace ip = boost::asio::ip;
-  ip::address ipAddr, broadcast;
+  ip::address ipAddr, broadcastAddr;
   uint32_t flags = ifa->ifa_flags; // will be overridden by IFA_FLAGS if the attribute is present
 
   const rtattr* rta = reinterpret_cast<const rtattr*>(IFA_RTA(ifa));
@@ -443,7 +443,10 @@
         if (ifa->ifa_family == AF_INET6 && attrLen == sizeof(ip::address_v6::bytes_type)) {
           ip::address_v6::bytes_type bytes;
           std::copy_n(attrData, bytes.size(), bytes.begin());
-          ipAddr = ip::address_v6(bytes);
+          ip::address_v6 v6Addr(bytes);
+          if (v6Addr.is_link_local())
+            v6Addr.scope_id(ifa->ifa_index);
+          ipAddr = v6Addr;
         }
         break;
 
@@ -451,7 +454,7 @@
         if (ifa->ifa_family == AF_INET && attrLen == sizeof(ip::address_v4::bytes_type)) {
           ip::address_v4::bytes_type bytes;
           std::copy_n(attrData, bytes.size(), bytes.begin());
-          broadcast = ip::address_v4(bytes);
+          broadcastAddr = ip::address_v4(bytes);
         }
         break;
 
@@ -466,13 +469,12 @@
     rta = RTA_NEXT(rta, rtaTotalLen);
   }
 
-  NetworkAddress address(
-    ifaFamilyToAddressFamily(ifa->ifa_family),
-    ipAddr,
-    broadcast,
-    ifa->ifa_prefixlen,
-    ifaScopeToAddressScope(ifa->ifa_scope),
-    flags);
+  NetworkAddress address(ifaFamilyToAddressFamily(ifa->ifa_family),
+                         ipAddr,
+                         broadcastAddr,
+                         ifa->ifa_prefixlen,
+                         ifaScopeToAddressScope(ifa->ifa_scope),
+                         flags);
   BOOST_ASSERT(address.getFamily() != AddressFamily::UNSPECIFIED);
 
   if (nlh->nlmsg_type == RTM_NEWADDR)