diff options
author | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2009-02-24 13:02:59 +0000 |
---|---|---|
committer | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2009-02-24 13:02:59 +0000 |
commit | 0ae09794e5ec3682303abf38192dfc4c184dac07 (patch) | |
tree | 6e80a4a68563a9f418ce3ae191b360d0395d4cd4 /ext/socket/socket.c | |
parent | 7e20506eae51a76415e46132f769e6d1b799c415 (diff) |
* ext/socket/socket.c (sockaddr_obj): convert fe80:1::1 to fe80::1%1.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@22597 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/socket/socket.c')
-rw-r--r-- | ext/socket/socket.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/ext/socket/socket.c b/ext/socket/socket.c index 8c92301bd9..82b9750cd1 100644 --- a/ext/socket/socket.c +++ b/ext/socket/socket.c @@ -1407,6 +1407,9 @@ static VALUE sockaddr_obj(struct sockaddr *addr) { socklen_t len; +#if defined(AF_INET6) && defined(__KAME__) + struct sockaddr_in6 addr6; +#endif if (addr == NULL) return Qnil; @@ -1419,6 +1422,19 @@ sockaddr_obj(struct sockaddr *addr) #ifdef AF_INET6 case AF_INET6: len = sizeof(struct sockaddr_in6); +# ifdef __KAME__ + /* KAME uses the 2nd 16bit word of link local IPv6 address as interface index internally */ + /* convert fe80:1::1 to fe80::1%1 */ + memcpy(&addr6, addr, len); + addr = (struct sockaddr *)&addr6; + if (IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr) && + addr6.sin6_scope_id == 0 && + (addr6.sin6_addr.s6_addr[2] || addr6.sin6_addr.s6_addr[3])) { + addr6.sin6_scope_id = (addr6.sin6_addr.s6_addr[2] << 8) | addr6.sin6_addr.s6_addr[3]; + addr6.sin6_addr.s6_addr[2] = 0; + addr6.sin6_addr.s6_addr[3] = 0; + } +# endif break; #endif |