method
ip_address_list
v1_9_3_392 -
Show latest stable
-
0 notes -
Class: Socket
- 1_8_6_287
- 1_8_7_72
- 1_8_7_330
- 1_9_1_378
- 1_9_2_180 (0)
- 1_9_3_125 (0)
- 1_9_3_392 (0)
- 2_1_10 (0)
- 2_2_9 (0)
- 2_4_6 (0)
- 2_5_5 (0)
- 2_6_3 (0)
- What's this?
Related methods
- Class methods (29)
- accept_loop
- getaddrinfo
- gethostbyaddr
- gethostbyname
- gethostname
- getnameinfo
- getservbyname
- getservbyport
- ip_address_list
- new
- pack_sockaddr_in
- pack_sockaddr_un
- pair
- sockaddr_in
- sockaddr_un
- socketpair
- tcp
- tcp_server_loop
- tcp_server_sockets
- udp_server_loop
- udp_server_loop_on
- udp_server_recv
- udp_server_sockets
- unix
- unix_server_loop
- unix_server_socket
- unix_socket_abstract_name?
- unpack_sockaddr_in
- unpack_sockaddr_un
- Instance methods (13)
- accept
- __accept_nonblock (>= v2_4_6)
- accept_nonblock
- bind
- connect
- __connect_nonblock (>= v2_4_6)
- connect_nonblock
- ipv6only!
- listen
- recvfrom
- __recvfrom_nonblock (>= v2_4_6)
- recvfrom_nonblock
- sysaccept
= private
= protected
ip_address_list()
public
Returns local IP addresses as an array.
The array contains Addrinfo objects.
pp Socket.ip_address_list #=> [#<Addrinfo: 127.0.0.1>, #<Addrinfo: 192.168.0.128>, #<Addrinfo: ::1>, ...]
Show source
static VALUE socket_s_ip_address_list(VALUE self) { #if defined(HAVE_GETIFADDRS) struct ifaddrs *ifp = NULL; struct ifaddrs *p; int ret; VALUE list; ret = getifaddrs(&ifp); if (ret == -1) { rb_sys_fail("getifaddrs"); } list = rb_ary_new(); for (p = ifp; p; p = p->ifa_next) { if (p->ifa_addr != NULL && IS_IP_FAMILY(p->ifa_addr->sa_family)) { rb_ary_push(list, sockaddr_obj(p->ifa_addr)); } } freeifaddrs(ifp); return list; #elif defined(SIOCGLIFCONF) && defined(SIOCGLIFNUM) && !defined(__hpux) /* Solaris if_tcp(7P) */ /* HP-UX has SIOCGLIFCONF too. But it uses different struct */ int fd = -1; int ret; struct lifnum ln; struct lifconf lc; char *reason = NULL; int save_errno; int i; VALUE list = Qnil; lc.lifc_buf = NULL; fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd == -1) rb_sys_fail("socket"); memset(&ln, 0, sizeof(ln)); ln.lifn_family = AF_UNSPEC; ret = ioctl(fd, SIOCGLIFNUM, &ln); if (ret == -1) { reason = "SIOCGLIFNUM"; goto finish; } memset(&lc, 0, sizeof(lc)); lc.lifc_family = AF_UNSPEC; lc.lifc_flags = 0; lc.lifc_len = sizeof(struct lifreq) * ln.lifn_count; lc.lifc_req = xmalloc(lc.lifc_len); ret = ioctl(fd, SIOCGLIFCONF, &lc); if (ret == -1) { reason = "SIOCGLIFCONF"; goto finish; } list = rb_ary_new(); for (i = 0; i < ln.lifn_count; i++) { struct lifreq *req = &lc.lifc_req[i]; if (IS_IP_FAMILY(req->lifr_addr.ss_family)) { if (req->lifr_addr.ss_family == AF_INET6 && IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)(&req->lifr_addr))->sin6_addr) && ((struct sockaddr_in6 *)(&req->lifr_addr))->sin6_scope_id == 0) { struct lifreq req2; memcpy(req2.lifr_name, req->lifr_name, LIFNAMSIZ); ret = ioctl(fd, SIOCGLIFINDEX, &req2); if (ret == -1) { reason = "SIOCGLIFINDEX"; goto finish; } ((struct sockaddr_in6 *)(&req->lifr_addr))->sin6_scope_id = req2.lifr_index; } rb_ary_push(list, sockaddr_obj((struct sockaddr *)&req->lifr_addr)); } } finish: save_errno = errno; if (lc.lifc_buf != NULL) xfree(lc.lifc_req); if (fd != -1) close(fd); errno = save_errno; if (reason) rb_sys_fail(reason); return list; #elif defined(SIOCGIFCONF) int fd = -1; int ret; #define EXTRA_SPACE (sizeof(struct ifconf) + sizeof(struct sockaddr_storage)) char initbuf[4096+EXTRA_SPACE]; char *buf = initbuf; int bufsize; struct ifconf conf; struct ifreq *req; VALUE list = Qnil; const char *reason = NULL; int save_errno; fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd == -1) rb_sys_fail("socket"); bufsize = sizeof(initbuf); buf = initbuf; retry: conf.ifc_len = bufsize; conf.ifc_req = (struct ifreq *)buf; /* fprintf(stderr, "bufsize: %d\n", bufsize); */ ret = ioctl(fd, SIOCGIFCONF, &conf); if (ret == -1) { reason = "SIOCGIFCONF"; goto finish; } /* fprintf(stderr, "conf.ifc_len: %d\n", conf.ifc_len); */ if (bufsize - EXTRA_SPACE < conf.ifc_len) { if (bufsize < conf.ifc_len) { /* NetBSD returns required size for all interfaces. */ bufsize = conf.ifc_len + EXTRA_SPACE; } else { bufsize = bufsize << 1; } if (buf == initbuf) buf = NULL; buf = xrealloc(buf, bufsize); goto retry; } close(fd); fd = -1; list = rb_ary_new(); req = conf.ifc_req; while ((char*)req < (char*)conf.ifc_req + conf.ifc_len) { struct sockaddr *addr = &req->ifr_addr; if (IS_IP_FAMILY(addr->sa_family)) { rb_ary_push(list, sockaddr_obj(addr)); } #ifdef HAVE_SA_LEN # ifndef _SIZEOF_ADDR_IFREQ # define _SIZEOF_ADDR_IFREQ(r) \ (sizeof(struct ifreq) + \ (sizeof(struct sockaddr) < (r).ifr_addr.sa_len ? \ (r).ifr_addr.sa_len - sizeof(struct sockaddr) : \ 0)) # endif req = (struct ifreq *)((char*)req + _SIZEOF_ADDR_IFREQ(*req)); #else req = (struct ifreq *)((char*)req + sizeof(struct ifreq)); #endif } finish: save_errno = errno; if (buf != initbuf) xfree(buf); if (fd != -1) close(fd); errno = save_errno; if (reason) rb_sys_fail(reason); 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 OperStatus; 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) { FreeLibrary(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); FreeLibrary(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); FreeLibrary(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; if (adapters->OperStatus != 1) /* 1 means IfOperStatusUp */ continue; for (uni = adapters->FirstUnicastAddress; uni; uni = uni->Next) { #ifndef INET6 if (uni->Address.lpSockaddr->sa_family == AF_INET) #else if (IS_IP_FAMILY(uni->Address.lpSockaddr->sa_family)) #endif rb_ary_push(list, sockaddr_obj(uni->Address.lpSockaddr)); } for (any = adapters->FirstAnycastAddress; any; any = any->Next) { #ifndef INET6 if (any->Address.lpSockaddr->sa_family == AF_INET) #else if (IS_IP_FAMILY(any->Address.lpSockaddr->sa_family)) #endif rb_ary_push(list, sockaddr_obj(any->Address.lpSockaddr)); } } FreeLibrary(h); return list; #endif }