aboutsummaryrefslogtreecommitdiffstats
path: root/ext
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-01-29 02:25:39 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-01-29 02:25:39 +0000
commit68db4a346417a4544399dbe1643a8e945c69755a (patch)
tree6f161bc05687e5e04a6ef5acb718c5e191e01b04 /ext
parentd899ed632189db0d07c7fa7729f2e3124900f84c (diff)
downloadruby-68db4a346417a4544399dbe1643a8e945c69755a.tar.gz
* ext/socket/spclet.c (socket_s_ip_address_list): support Windows XP
or later. (Win2k or earlier is still not supported) git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@21863 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext')
-rw-r--r--ext/socket/raddrinfo.c2
-rw-r--r--ext/socket/socket.c93
2 files changed, 93 insertions, 2 deletions
diff --git a/ext/socket/raddrinfo.c b/ext/socket/raddrinfo.c
index f5ea91af85..8966518dfd 100644
--- a/ext/socket/raddrinfo.c
+++ b/ext/socket/raddrinfo.c
@@ -914,7 +914,7 @@ inspect_sockaddr(VALUE addrinfo, VALUE ret)
break;
}
-#ifdef INET6
+#ifdef AF_INET6
case AF_INET6:
{
struct sockaddr_in6 *addr;
diff --git a/ext/socket/socket.c b/ext/socket/socket.c
index 20631e9da7..6ef0b3d4d8 100644
--- a/ext/socket/socket.c
+++ b/ext/socket/socket.c
@@ -1386,7 +1386,7 @@ sock_s_unpack_sockaddr_un(VALUE self, VALUE addr)
}
#endif
-#if defined(HAVE_GETIFADDRS) || defined(SIOCGLIFCONF) || defined(SIOCGIFCONF)
+#if defined(HAVE_GETIFADDRS) || defined(SIOCGLIFCONF) || defined(SIOCGIFCONF) || defined(_WIN32)
static VALUE
sockaddr_obj(struct sockaddr *addr)
{
@@ -1612,6 +1612,97 @@ socket_s_ip_address_list(VALUE self)
return list;
#undef EXTRA_SPACE
+#elif defined(_WIN32)
+ typedef struct ip_adapter_unicast_address_st {
+ unsigned LONG_LONG dummy0;
+ struct ip_adapter_unicast_address_st *Next;
+ struct {
+ struct sockaddr *lpSockaddr;
+ int iSockaddrLength;
+ } Address;
+ int dummy1;
+ int dummy2;
+ int dummy3;
+ long dummy4;
+ long dummy5;
+ long dummy6;
+ } ip_adapter_unicast_address_t;
+ typedef struct ip_adapter_anycast_address_st {
+ unsigned LONG_LONG dummy0;
+ struct ip_adapter_anycast_address_st *Next;
+ struct {
+ struct sockaddr *lpSockaddr;
+ int iSockaddrLength;
+ } Address;
+ } ip_adapter_anycast_address_t;
+ typedef struct ip_adapter_addresses_st {
+ unsigned LONG_LONG dummy0;
+ struct ip_adapter_addresses_st *Next;
+ void *dummy1;
+ ip_adapter_unicast_address_t *FirstUnicastAddress;
+ ip_adapter_anycast_address_t *FirstAnycastAddress;
+ void *dummy2;
+ void *dummy3;
+ void *dummy4;
+ void *dummy5;
+ void *dummy6;
+ BYTE dummy7[8];
+ DWORD dummy8;
+ DWORD dummy9;
+ DWORD dummy10;
+ DWORD IfType;
+ int dummy11;
+ DWORD dummy12;
+ DWORD dummy13[16];
+ void *dummy14;
+ } ip_adapter_addresses_t;
+ typedef ULONG (WINAPI *GetAdaptersAddresses_t)(ULONG, ULONG, PVOID, ip_adapter_addresses_t *, PULONG);
+ HMODULE h;
+ GetAdaptersAddresses_t pGetAdaptersAddresses;
+ ULONG len;
+ DWORD ret;
+ ip_adapter_addresses_t *adapters;
+ VALUE list;
+
+ h = LoadLibrary("iphlpapi.dll");
+ if (!h)
+ rb_notimplement();
+ pGetAdaptersAddresses = (GetAdaptersAddresses_t)GetProcAddress(h, "GetAdaptersAddresses");
+ if (!pGetAdaptersAddresses) {
+ CloseHandle(h);
+ rb_notimplement();
+ }
+
+ ret = pGetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, &len);
+ if (ret != ERROR_SUCCESS && ret != ERROR_BUFFER_OVERFLOW) {
+ errno = rb_w32_map_errno(ret);
+ CloseHandle(h);
+ rb_sys_fail("GetAdaptersAddresses");
+ }
+ adapters = (ip_adapter_addresses_t *)ALLOCA_N(BYTE, len);
+ ret = pGetAdaptersAddresses(AF_UNSPEC, 0, NULL, adapters, &len);
+ if (ret != ERROR_SUCCESS) {
+ errno = rb_w32_map_errno(ret);
+ CloseHandle(h);
+ rb_sys_fail("GetAdaptersAddresses");
+ }
+
+ list = rb_ary_new();
+ for (; adapters; adapters = adapters->Next) {
+ ip_adapter_unicast_address_t *uni;
+ ip_adapter_anycast_address_t *any;
+ for (uni = adapters->FirstUnicastAddress; uni; uni = uni->Next) {
+ if (IS_IP_FAMILY(uni->Address.lpSockaddr->sa_family))
+ rb_ary_push(list, sockaddr_obj(uni->Address.lpSockaddr));
+ }
+ for (any = adapters->FirstAnycastAddress; any; any = any->Next) {
+ if (IS_IP_FAMILY(any->Address.lpSockaddr->sa_family))
+ rb_ary_push(list, sockaddr_obj(any->Address.lpSockaddr));
+ }
+ }
+
+ CloseHandle(h);
+ return list;
#else
rb_notimplement();
#endif