summaryrefslogtreecommitdiff
path: root/ext/socket
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-01-18 07:47:35 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-01-18 07:47:35 +0000
commitd620500dda16cfc3777894541a417d6153d5a1fb (patch)
tree74893e907fabc7298b5516a6321f4a321b22626e /ext/socket
parent55bf8fa11c3cc2833f6848ee8a5a4b56a51bc3d9 (diff)
* ext/socket/raddrinfo.c (addrinfo_ip_address): new method
AddrInfo#ip_address. (addrinfo_ip_port): new method AddrInfo#ip_port. (Init_addrinfo): define the methods above. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@21647 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/socket')
-rw-r--r--ext/socket/raddrinfo.c66
1 files changed, 66 insertions, 0 deletions
diff --git a/ext/socket/raddrinfo.c b/ext/socket/raddrinfo.c
index cca244af071..ee586fac314 100644
--- a/ext/socket/raddrinfo.c
+++ b/ext/socket/raddrinfo.c
@@ -1520,6 +1520,70 @@ addrinfo_ip_unpack(VALUE self)
return ret;
}
+/*
+ * call-seq:
+ * addrinfo.ip_address => string
+ *
+ * Returns the IP address as a string.
+ *
+ * AddrInfo.tcp("127.0.0.1", 80).ip_address #=> "127.0.0.1"
+ * AddrInfo.tcp("::1", 80).ip_address #=> "::1"
+ */
+static VALUE
+addrinfo_ip_address(VALUE self)
+{
+ rb_addrinfo_t *rai = get_addrinfo(self);
+ int family = ai_get_afamily(rai);
+ VALUE vflags;
+ VALUE ret;
+
+ if (!IS_IP_FAMILY(family))
+ rb_raise(rb_eSocket, "need IPv4 or IPv6 address");
+
+ vflags = INT2NUM(NI_NUMERICHOST|NI_NUMERICSERV);
+ ret = addrinfo_getnameinfo(1, &vflags, self);
+ return rb_ary_entry(ret, 0);
+}
+
+/*
+ * call-seq:
+ * addrinfo.ip_port => port
+ *
+ * Returns the port number as an integer.
+ *
+ * AddrInfo.tcp("127.0.0.1", 80).ip_port #=> 80
+ * AddrInfo.tcp("::1", 80).ip_port #=> 80
+ */
+static VALUE
+addrinfo_ip_port(VALUE self)
+{
+ rb_addrinfo_t *rai = get_addrinfo(self);
+ int family = ai_get_afamily(rai);
+ int port;
+
+ if (!IS_IP_FAMILY(family))
+ rb_raise(rb_eSocket, "need IPv4 or IPv6 address");
+
+ switch (family) {
+ case AF_INET:
+ if (rai->sockaddr_len != sizeof(struct sockaddr_in))
+ rb_raise(rb_eSocket, "unexpected sockaddr size for IPv4");
+ port = ntohs(((struct sockaddr_in *)&rai->addr)->sin_port);
+ break;
+
+ case AF_INET6:
+ if (rai->sockaddr_len != sizeof(struct sockaddr_in6))
+ rb_raise(rb_eSocket, "unexpected sockaddr size for IPv6");
+ port = ntohs(((struct sockaddr_in6 *)&rai->addr)->sin6_port);
+ break;
+
+ default:
+ rb_raise(rb_eSocket, "need IPv4 or IPv6 address");
+ }
+
+ return INT2NUM(port);
+}
+
#ifdef HAVE_SYS_UN_H
/*
* call-seq:
@@ -1768,6 +1832,8 @@ Init_addrinfo(void)
rb_define_method(rb_cAddrInfo, "ip?", addrinfo_ip_p, 0);
rb_define_method(rb_cAddrInfo, "ip_unpack", addrinfo_ip_unpack, 0);
+ 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?", addrinfo_ipv4_p, 0);
rb_define_method(rb_cAddrInfo, "ipv6?", addrinfo_ipv6_p, 0);
rb_define_method(rb_cAddrInfo, "unix?", addrinfo_unix_p, 0);