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

* ext/socket/option.c (rb_if_indextoname): new function to abstract

environments without if_indextoname.
  (inspect_ipv6_multicast_if): new function to inspect
  IPV6_MULTICAST_IF.
  Socket::Option.new(:INET6, :IPV6, :MULTICAST_IF,
  [2].pack("I!")).inspect is
  "#<Socket::Option: INET6 IPV6 MULTICAST_IF eth0>".


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@30378 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
akr 2010-12-26 00:25:14 +00:00
parent 5d47965174
commit 326ec51f4e
2 changed files with 55 additions and 16 deletions

View file

@ -1,3 +1,13 @@
Sun Dec 26 09:22:19 2010 Tanaka Akira <akr@fsij.org>
* ext/socket/option.c (rb_if_indextoname): new function to abstract
environments without if_indextoname.
(inspect_ipv6_multicast_if): new function to inspect
IPV6_MULTICAST_IF.
Socket::Option.new(:INET6, :IPV6, :MULTICAST_IF,
[2].pack("I!")).inspect is
"#<Socket::Option: INET6 IPV6 MULTICAST_IF eth0>".
Sun Dec 26 04:31:15 2010 Luis Lavena <luislavena@gmail.com> Sun Dec 26 04:31:15 2010 Luis Lavena <luislavena@gmail.com>
* ext/dl/win32/registry.rb: Corrected RegCreateKeyExA signature. * ext/dl/win32/registry.rb: Corrected RegCreateKeyExA signature.

View file

@ -324,7 +324,7 @@ inspect_errno(int level, int optname, VALUE data, VALUE ret)
} }
} }
#if defined(IPV6_MULTICAST_IF) || defined(IPV6_MULTICAST_LOOP) #if defined(IPV6_MULTICAST_LOOP)
static int static int
inspect_uint(int level, int optname, VALUE data, VALUE ret) inspect_uint(int level, int optname, VALUE data, VALUE ret)
{ {
@ -451,6 +451,21 @@ inet_ntop(int af, const void *addr, char *numaddr, size_t numaddr_len)
} }
#endif #endif
/* Although the buffer size needed depends on the prefixes, "%u" may generate "4294967295". */
static int
rb_if_indextoname(const char *succ_prefix, const char *fail_prefix, unsigned int ifindex, char *buf, size_t len)
{
#if defined(HAVE_IF_INDEXTONAME)
char ifbuf[IFNAMSIZ];
if (if_indextoname(ifindex, ifbuf) == NULL)
return snprintf(buf, len, "%s%u", fail_prefix, ifindex);
else
return snprintf(buf, len, "%s%s", succ_prefix, ifbuf);
#else
return snprintf(buf, len, "%s%u", fail_prefix, ifindex);
#endif
}
#if defined(IPPROTO_IP) && defined(HAVE_TYPE_STRUCT_IP_MREQ) /* 4.4BSD, GNU/Linux */ #if defined(IPPROTO_IP) && defined(HAVE_TYPE_STRUCT_IP_MREQ) /* 4.4BSD, GNU/Linux */
static int static int
inspect_ipv4_mreq(int level, int optname, VALUE data, VALUE ret) inspect_ipv4_mreq(int level, int optname, VALUE data, VALUE ret)
@ -475,13 +490,13 @@ inspect_ipv4_mreq(int level, int optname, VALUE data, VALUE ret)
} }
#endif #endif
#if defined(IPPROTO_IP) && defined(HAVE_TYPE_STRUCT_IP_MREQN) && defined(HAVE_IF_INDEXTONAME) /* GNU/Linux, FreeBSD 7 */ #if defined(IPPROTO_IP) && defined(HAVE_TYPE_STRUCT_IP_MREQN) /* GNU/Linux, FreeBSD 7 */
static int static int
inspect_ipv4_mreqn(int level, int optname, VALUE data, VALUE ret) inspect_ipv4_mreqn(int level, int optname, VALUE data, VALUE ret)
{ {
if (RSTRING_LEN(data) == sizeof(struct ip_mreqn)) { if (RSTRING_LEN(data) == sizeof(struct ip_mreqn)) {
struct ip_mreqn s; struct ip_mreqn s;
char addrbuf[INET_ADDRSTRLEN], ifbuf[IFNAMSIZ]; char addrbuf[INET_ADDRSTRLEN], ifbuf[32+IFNAMSIZ];
memcpy((char*)&s, RSTRING_PTR(data), sizeof(s)); memcpy((char*)&s, RSTRING_PTR(data), sizeof(s));
if (inet_ntop(AF_INET, &s.imr_multiaddr, addrbuf, (socklen_t)sizeof(addrbuf)) == NULL) if (inet_ntop(AF_INET, &s.imr_multiaddr, addrbuf, (socklen_t)sizeof(addrbuf)) == NULL)
rb_str_cat2(ret, " invalid-address"); rb_str_cat2(ret, " invalid-address");
@ -491,10 +506,8 @@ inspect_ipv4_mreqn(int level, int optname, VALUE data, VALUE ret)
rb_str_catf(ret, " invalid-address"); rb_str_catf(ret, " invalid-address");
else else
rb_str_catf(ret, " %s", addrbuf); rb_str_catf(ret, " %s", addrbuf);
if (if_indextoname(s.imr_ifindex, ifbuf) == NULL) rb_if_indextoname(" ", " ifindex:", s.imr_ifindex, ifbuf, sizeof(ifbuf));
rb_str_catf(ret, " ifindex:%d", s.imr_ifindex); rb_str_cat2(ret, ifbuf);
else
rb_str_catf(ret, " %s", ifbuf);
return 1; return 1;
} }
else { else {
@ -541,22 +554,38 @@ inspect_ipv4_multicast_if(int level, int optname, VALUE data, VALUE ret)
} }
#endif #endif
#if defined(IPPROTO_IPV6) && defined(HAVE_TYPE_STRUCT_IPV6_MREQ) && defined(HAVE_IF_INDEXTONAME) /* POSIX, RFC 3493 */ #if defined(IPV6_MULTICAST_IF) /* POSIX, RFC 3493 */
static int
inspect_ipv6_multicast_if(int level, int optname, VALUE data, VALUE ret)
{
if (RSTRING_LEN(data) == sizeof(int)) {
char ifbuf[32+IFNAMSIZ];
unsigned int ifindex;
memcpy((char*)&ifindex, RSTRING_PTR(data), sizeof(unsigned int));
rb_if_indextoname(" ", " ", ifindex, ifbuf, sizeof(ifbuf));
rb_str_cat2(ret, ifbuf);
return 1;
}
else {
return 0;
}
}
#endif
#if defined(IPPROTO_IPV6) && defined(HAVE_TYPE_STRUCT_IPV6_MREQ) /* POSIX, RFC 3493 */
static int static int
inspect_ipv6_mreq(int level, int optname, VALUE data, VALUE ret) inspect_ipv6_mreq(int level, int optname, VALUE data, VALUE ret)
{ {
if (RSTRING_LEN(data) == sizeof(struct ipv6_mreq)) { if (RSTRING_LEN(data) == sizeof(struct ipv6_mreq)) {
struct ipv6_mreq s; struct ipv6_mreq s;
char addrbuf[INET6_ADDRSTRLEN], ifbuf[IFNAMSIZ]; char addrbuf[INET6_ADDRSTRLEN], ifbuf[32+IFNAMSIZ];
memcpy((char*)&s, RSTRING_PTR(data), sizeof(s)); memcpy((char*)&s, RSTRING_PTR(data), sizeof(s));
if (inet_ntop(AF_INET6, &s.ipv6mr_multiaddr, addrbuf, (socklen_t)sizeof(addrbuf)) == NULL) if (inet_ntop(AF_INET6, &s.ipv6mr_multiaddr, addrbuf, (socklen_t)sizeof(addrbuf)) == NULL)
rb_str_cat2(ret, " invalid-address"); rb_str_cat2(ret, " invalid-address");
else else
rb_str_catf(ret, " %s", addrbuf); rb_str_catf(ret, " %s", addrbuf);
if (if_indextoname(s.ipv6mr_interface, ifbuf) == NULL) rb_if_indextoname(" ", " interface:", s.ipv6mr_interface, ifbuf, sizeof(ifbuf));
rb_str_catf(ret, " interface:%u", s.ipv6mr_interface); rb_str_cat2(ret, ifbuf);
else
rb_str_catf(ret, " %s", ifbuf);
return 1; return 1;
} }
else { else {
@ -779,15 +808,15 @@ sockopt_inspect(VALUE self)
case IPV6_MULTICAST_HOPS: inspected = inspect_int(level, optname, data, ret); break; case IPV6_MULTICAST_HOPS: inspected = inspect_int(level, optname, data, ret); break;
# endif # endif
# if defined(IPV6_MULTICAST_IF) /* POSIX */ # if defined(IPV6_MULTICAST_IF) /* POSIX */
case IPV6_MULTICAST_IF: inspected = inspect_uint(level, optname, data, ret); break; case IPV6_MULTICAST_IF: inspected = inspect_ipv6_multicast_if(level, optname, data, ret); break;
# endif # endif
# if defined(IPV6_MULTICAST_LOOP) /* POSIX */ # if defined(IPV6_MULTICAST_LOOP) /* POSIX */
case IPV6_MULTICAST_LOOP: inspected = inspect_uint(level, optname, data, ret); break; case IPV6_MULTICAST_LOOP: inspected = inspect_uint(level, optname, data, ret); break;
# endif # endif
# if defined(IPV6_JOIN_GROUP) && defined(HAVE_IF_INDEXTONAME) /* POSIX */ # if defined(IPV6_JOIN_GROUP) /* POSIX */
case IPV6_JOIN_GROUP: inspected = inspect_ipv6_mreq(level, optname, data, ret); break; case IPV6_JOIN_GROUP: inspected = inspect_ipv6_mreq(level, optname, data, ret); break;
# endif # endif
# if defined(IPV6_LEAVE_GROUP) && defined(HAVE_IF_INDEXTONAME) /* POSIX */ # if defined(IPV6_LEAVE_GROUP) /* POSIX */
case IPV6_LEAVE_GROUP: inspected = inspect_ipv6_mreq(level, optname, data, ret); break; case IPV6_LEAVE_GROUP: inspected = inspect_ipv6_mreq(level, optname, data, ret); break;
# endif # endif
# if defined(IPV6_UNICAST_HOPS) /* POSIX */ # if defined(IPV6_UNICAST_HOPS) /* POSIX */