Consistency in namespace-closing comments
[folly.git] / folly / IPAddressV6.cpp
index 71765e7646c25e99bbfeb3d3b8451d6c4011744e..e40a08e5d17e317f43fb6a6056569da41b1511a1 100644 (file)
 #include <ostream>
 #include <string>
 
-#include <net/if.h>
-
 #include <folly/Format.h>
 #include <folly/IPAddress.h>
 #include <folly/IPAddressV4.h>
 #include <folly/MacAddress.h>
 #include <folly/detail/IPAddressSource.h>
 
+#if !_WIN32
+#include <net/if.h>
+#else
+// Because of the massive pain that is libnl, this can't go into the socket
+// portability header as you can't include <linux/if.h> and <net/if.h> in
+// the same translation unit without getting errors -_-...
+#include <iphlpapi.h>
+#include <ntddndis.h>
+
+// Alias the max size of an interface name to what posix expects.
+#define IFNAMSIZ IF_NAMESIZE
+#endif
+
 using std::ostream;
 using std::string;
 
@@ -405,23 +416,33 @@ IPAddressV6 IPAddressV6::mask(size_t numBits) const {
 
 // public
 string IPAddressV6::str() const {
-  char buffer[INET6_ADDRSTRLEN] = {0};
-
-  if (inet_ntop(AF_INET6, toAddr().s6_addr, buffer, INET6_ADDRSTRLEN)) {
-    string ip(buffer);
-    char ifname[IFNAMSIZ] = {0};
-    if (if_indextoname(getScopeId(), ifname)) {
-      ip += "%";
-      ip += ifname;
-    }
-    return ip;
-  } else {
+  char buffer[INET6_ADDRSTRLEN + IFNAMSIZ + 1];
+
+  if (!inet_ntop(AF_INET6, toAddr().s6_addr, buffer, INET6_ADDRSTRLEN)) {
     throw IPAddressFormatException(to<std::string>(
         "Invalid address with hex ",
         "'",
         detail::Bytes::toHex(bytes(), 16),
-        "'"));
+        "'",
+        " with error ",
+        strerror(errno)));
   }
+
+  auto scopeId = getScopeId();
+  if (scopeId != 0) {
+    auto len = strlen(buffer);
+    buffer[len] = '%';
+
+    auto errsv = errno;
+    if (!if_indextoname(scopeId, buffer + len + 1)) {
+      // if we can't map the if because eg. it no longer exists,
+      // append the if index instead
+      snprintf(buffer + len + 1, IFNAMSIZ, "%u", scopeId);
+    }
+    errno = errsv;
+  }
+
+  return string(buffer);
 }
 
 // public
@@ -493,4 +514,4 @@ bool IPAddressV6::inBinarySubnet(const std::array<uint8_t, 2> addr,
   auto masked = mask(numBits);
   return (std::memcmp(addr.data(), masked.bytes(), 2) == 0);
 }
-} // folly
+} // namespace folly