[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]