diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | ext/socket/socket.c | 15 |
2 files changed, 17 insertions, 3 deletions
@@ -1,3 +1,8 @@ +Mon Feb 8 21:03:53 2010 Tanaka Akira <akr@fsij.org> + + * ext/socket/socket.c (socket_s_ip_address_list): obtain the scope_id + of IPv6 link local address on OpenSolaris. + Mon Feb 8 16:27:57 2010 Nobuyoshi Nakada <nobu@ruby-lang.org> * dmyversion.c: empty load path in miniruby. diff --git a/ext/socket/socket.c b/ext/socket/socket.c index 16394820f4..ab7bd95094 100644 --- a/ext/socket/socket.c +++ b/ext/socket/socket.c @@ -1554,13 +1554,22 @@ socket_s_ip_address_list(VALUE self) goto finish; } - close(fd); - fd = -1; - list = rb_ary_new(); for (i = 0; i < ln.lifn_count; i++) { struct lifreq *req = &lc.lifc_req[i]; if (IS_IP_FAMILY(req->lifr_addr.ss_family)) { + if (req->lifr_addr.ss_family == AF_INET6 && + IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)(&req->lifr_addr))->sin6_addr) && + ((struct sockaddr_in6 *)(&req->lifr_addr))->sin6_scope_id == 0) { + struct lifreq req2; + memcpy(req2.lifr_name, req->lifr_name, LIFNAMSIZ); + ret = ioctl(fd, SIOCGLIFINDEX, &req2); + if (ret == -1) { + reason = "SIOCGLIFINDEX"; + goto finish; + } + ((struct sockaddr_in6 *)(&req->lifr_addr))->sin6_scope_id = req2.lifr_index; + } rb_ary_push(list, sockaddr_obj((struct sockaddr *)&req->lifr_addr)); } } |