ruby-changes:10384
From: akr <ko1@a...>
Date: Sun, 1 Feb 2009 21:29:05 +0900 (JST)
Subject: [ruby-changes:10384] Ruby:r21928 (trunk): * ext/socket/raddrinfo.c (addrinfo_ipv4_private_p): new method.
akr 2009-02-01 21:28:50 +0900 (Sun, 01 Feb 2009) New Revision: 21928 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=21928 Log: * ext/socket/raddrinfo.c (addrinfo_ipv4_private_p): new method. (addrinfo_ipv4_loopback_p): ditto. (addrinfo_ipv4_multicast_p): ditto. Modified files: trunk/ChangeLog trunk/ext/socket/raddrinfo.c trunk/test/socket/test_addrinfo.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 21927) +++ ChangeLog (revision 21928) @@ -1,3 +1,9 @@ +Sun Feb 1 21:27:55 2009 Tanaka Akira <akr@f...> + + * ext/socket/raddrinfo.c (addrinfo_ipv4_private_p): new method. + (addrinfo_ipv4_loopback_p): ditto. + (addrinfo_ipv4_multicast_p): ditto. + Sun Feb 1 16:10:06 2009 Nobuyoshi Nakada <nobu@r...> * lib/optparse.rb (Switch#summarize): strips an equal sign from Index: ext/socket/raddrinfo.c =================================================================== --- ext/socket/raddrinfo.c (revision 21927) +++ ext/socket/raddrinfo.c (revision 21928) @@ -1623,6 +1623,60 @@ return INT2NUM(port); } +static int +extract_in_addr(VALUE self, uint32_t *addrp) +{ + rb_addrinfo_t *rai = get_addrinfo(self); + int family = ai_get_afamily(rai); + if (family != AF_INET) return 0; + *addrp = ntohl(((struct sockaddr_in *)&rai->addr)->sin_addr.s_addr); + return 1; +} + +/* + * Returns true for IPv4 private address (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16). + * It returns false otherwise. + */ +static VALUE +addrinfo_ipv4_private_p(VALUE self) +{ + uint32_t a; + if (!extract_in_addr(self, &a)) return Qfalse; + if ((a & 0xff000000) == 0x0a000000 || /* 10.0.0.0/8 */ + (a & 0xfff00000) == 0xac100000 || /* 172.16.0.0/12 */ + (a & 0xffff0000) == 0xc0a80000) /* 192.168.0.0/16 */ + return Qtrue; + return Qfalse; +} + +/* + * Returns true for IPv4 loopback address (127.0.0.0/8). + * It returns false otherwise. + */ +static VALUE +addrinfo_ipv4_loopback_p(VALUE self) +{ + uint32_t a; + if (!extract_in_addr(self, &a)) return Qfalse; + if ((a & 0xff000000) == 0x7f000000) /* 127.0.0.0/8 */ + return Qtrue; + return Qfalse; +} + +/* + * Returns true for IPv4 multicast address (224.0.0.0/4). + * It returns false otherwise. + */ +static VALUE +addrinfo_ipv4_multicast_p(VALUE self) +{ + uint32_t a; + if (!extract_in_addr(self, &a)) return Qfalse; + if ((a & 0xf0000000) == 0xe0000000) /* 224.0.0.0/4 */ + return Qtrue; + return Qfalse; +} + #ifdef AF_INET6 static struct in6_addr * @@ -2036,6 +2090,10 @@ rb_define_method(rb_cAddrInfo, "ip_address", addrinfo_ip_address, 0); rb_define_method(rb_cAddrInfo, "ip_port", addrinfo_ip_port, 0); + rb_define_method(rb_cAddrInfo, "ipv4_private?", addrinfo_ipv4_private_p, 0); + rb_define_method(rb_cAddrInfo, "ipv4_loopback?", addrinfo_ipv4_loopback_p, 0); + rb_define_method(rb_cAddrInfo, "ipv4_multicast?", addrinfo_ipv4_multicast_p, 0); + #ifdef AF_INET6 rb_define_method(rb_cAddrInfo, "ipv6_unspecified?", addrinfo_ipv6_unspecified_p, 0); rb_define_method(rb_cAddrInfo, "ipv6_loopback?", addrinfo_ipv6_loopback_p, 0); Index: test/socket/test_addrinfo.rb =================================================================== --- test/socket/test_addrinfo.rb (revision 21927) +++ test/socket/test_addrinfo.rb (revision 21928) @@ -63,6 +63,25 @@ assert(!ipv4_ai.unix?) end + def test_ipv4_address_predicates + list = [ + [:ipv4_private?, "10.0.0.0", "10.255.255.255", + "172.16.0.0", "172.31.255.255", + "192.168.0.0", "192.168.255.255"], + [:ipv4_loopback?, "127.0.0.1", "127.0.0.0", "127.255.255.255"], + [:ipv4_multicast?, "224.0.0.0", "224.255.255.255"] + ] + list.each {|meth, *addrs| + addrs.each {|addr| + assert(AddrInfo.ip(addr).send(meth), "AddrInfo.ip(#{addr.inspect}).#{meth}") + list.each {|meth2,| + next if meth == meth2 + assert(!AddrInfo.ip(addr).send(meth2), "!AddrInfo.ip(#{addr.inspect}).#{meth2}") + } + } + } + end + def test_basicsocket_send s1 = Socket.new(:INET, :DGRAM, 0) s1.bind(Socket.sockaddr_in(0, "127.0.0.1")) @@ -326,7 +345,7 @@ assert_equal(ai1.canonname, ai2.canonname) end - def test_ipv6_predicates + def test_ipv6_address_predicates list = [ [:ipv6_unspecified?, "::"], [:ipv6_loopback?, "::1"], -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/