1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* ext/socket/raddrinfo.c (addrinfo_ipv6_to_ipv4): new method.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@22042 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
akr 2009-02-04 15:10:03 +00:00
parent ac5b681334
commit 9dfc90dc70
2 changed files with 39 additions and 0 deletions

View file

@ -1,3 +1,7 @@
Thu Feb 5 00:09:39 2009 Tanaka Akira <akr@fsij.org>
* ext/socket/raddrinfo.c (addrinfo_ipv6_to_ipv4): new method.
Wed Feb 4 21:59:31 2009 Tanaka Akira <akr@fsij.org>
* transcode.c (make_econv_exception): show U+XXXX form for undefined

View file

@ -1832,6 +1832,39 @@ addrinfo_ipv6_mc_global_p(VALUE self)
return Qfalse;
}
/*
* Returns IPv4 address of IPv4 mapped/compatible IPv6 address.
* It returns nil if +self+ is not IPv4 mapped/compatible IPv6 address.
*
* AddrInfo.ip("::192.0.2.3").ipv6_to_ipv4 #=> #<AddrInfo: 192.0.2.3>
* AddrInfo.ip("::ffff:192.0.2.3").ipv6_to_ipv4 #=> #<AddrInfo: 192.0.2.3>
* AddrInfo.ip("::1").ipv6_to_ipv4 #=> nil
* AddrInfo.ip("192.0.2.3").ipv6_to_ipv4 #=> nil
* AddrInfo.unix("/tmp/sock").ipv6_to_ipv4 #=> nil
*/
static VALUE
addrinfo_ipv6_to_ipv4(VALUE self)
{
rb_addrinfo_t *rai = get_addrinfo(self);
struct in6_addr *addr;
int family = ai_get_afamily(rai);
if (family != AF_INET6) return Qnil;
addr = &((struct sockaddr_in6 *)&rai->addr)->sin6_addr;
if (IN6_IS_ADDR_V4MAPPED(addr) || IN6_IS_ADDR_V4COMPAT(addr)) {
struct sockaddr_in sin4;
MEMZERO(&sin4, struct sockaddr_in, 1);
sin4.sin_family = AF_INET;
SET_SIN_LEN(&sin4, sizeof(sin4));
memcpy(&sin4.sin_addr, (char*)addr + sizeof(*addr) - sizeof(sin4.sin_addr), sizeof(sin4.sin_addr));
return addrinfo_new((struct sockaddr *)&sin4, sizeof(sin4),
PF_INET, rai->socktype, rai->protocol,
rai->canonname, rai->inspectname);
}
else {
return Qnil;
}
}
#endif
#ifdef HAVE_SYS_UN_H
@ -2107,6 +2140,8 @@ Init_addrinfo(void)
rb_define_method(rb_cAddrInfo, "ipv6_mc_sitelocal?", addrinfo_ipv6_mc_sitelocal_p, 0);
rb_define_method(rb_cAddrInfo, "ipv6_mc_orglocal?", addrinfo_ipv6_mc_orglocal_p, 0);
rb_define_method(rb_cAddrInfo, "ipv6_mc_global?", addrinfo_ipv6_mc_global_p, 0);
rb_define_method(rb_cAddrInfo, "ipv6_to_ipv4", addrinfo_ipv6_to_ipv4, 0);
#endif
#ifdef HAVE_SYS_UN_H