summaryrefslogtreecommitdiff
path: root/ext/socket/socket.c
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-05-06 11:51:07 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-05-06 11:51:07 +0000
commit9e08404b8a60487ab0d5ba9643a2e02f05d76310 (patch)
tree7761b53abddb3e611ed7804d4151221ece5fd2ed /ext/socket/socket.c
parent85bfd7308f11b581f10bb07f34a1bfb4ab64cdbb (diff)
* ext/socket/socket.c (socket_s_ip_address_list): Fill sin6_scope_id
if getifaddrs() returns an IPv6 link local address which sin6_scope_id is zero, such as on OpenIndiana SunOS 5.11. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40593 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/socket/socket.c')
-rw-r--r--ext/socket/socket.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/ext/socket/socket.c b/ext/socket/socket.c
index 3d59b6c..a0c9618 100644
--- a/ext/socket/socket.c
+++ b/ext/socket/socket.c
@@ -1658,6 +1658,26 @@ socket_s_ip_address_list(VALUE self)
for (p = ifp; p; p = p->ifa_next) {
if (p->ifa_addr != NULL && IS_IP_FAMILY(p->ifa_addr->sa_family)) {
struct sockaddr *addr = p->ifa_addr;
+#if defined(AF_INET6)
+ /*
+ * OpenIndiana SunOS 5.11 getifaddrs() returns IPv6 link local
+ * address with sin6_scope_id == 0.
+ * So fill it from the interface name (ifa_name).
+ */
+ struct sockaddr_in6 addr6;
+ if (addr->sa_family == AF_INET6) {
+ socklen_t len = (socklen_t)sizeof(struct sockaddr_in6);
+ memcpy(&addr6, addr, len);
+ addr = (struct sockaddr *)&addr6;
+ if (IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr) &&
+ addr6.sin6_scope_id == 0) {
+ unsigned int ifindex = if_nametoindex(p->ifa_name);
+ if (ifindex != 0) {
+ addr6.sin6_scope_id = ifindex;
+ }
+ }
+ }
+#endif
rb_ary_push(list, sockaddr_obj(addr, sockaddr_len(addr)));
}
}