46 rb_scan_args(argc, argv,
"21", &domain, &type, &protocol);
58 #if defined HAVE_SOCKETPAIR
72 pair_yield(
VALUE pair)
78 #if defined HAVE_SOCKETPAIR
108 rb_scan_args(argc, argv,
"21", &domain, &type, &protocol);
114 ret = socketpair(d, t, p, sp);
115 if (ret < 0 && (errno == EMFILE || errno == ENFILE)) {
117 ret = socketpair(d, t, p, sp);
134 #define rsock_sock_s_socketpair rb_f_notimplement
506 if (listen(fptr->
fd, backlog) < 0)
711 socklen_t
len = (socklen_t)
sizeof buf;
776 socklen_t
len = (socklen_t)
sizeof buf;
827 socklen_t
len = (socklen_t)
sizeof buf;
835 #ifdef HAVE_GETHOSTNAME
850 #ifndef HOST_NAME_MAX
851 # define HOST_NAME_MAX 1024
853 char buf[HOST_NAME_MAX+1];
856 if (gethostname(buf, (
int)
sizeof buf - 1) < 0)
859 buf[
sizeof buf - 1] =
'\0';
865 #include <sys/utsname.h>
877 #define sock_gethostname rb_f_notimplement
891 for (res = res0; res; res = res->
ai_next) {
909 switch (addr->sa_family) {
911 ptr = (
char*)&((
struct sockaddr_in*)addr)->sin_addr.s_addr;
912 len =
sizeof(((
struct sockaddr_in*)addr)->sin_addr.s_addr);
916 ptr = (
char*)&((
struct sockaddr_in6*)addr)->sin6_addr.s6_addr;
917 len =
sizeof(((
struct sockaddr_in6*)addr)->sin6_addr.s6_addr);
963 if (!
NIL_P(family)) {
973 #ifdef HAVE_HSTRERROR
984 if (h->h_aliases !=
NULL) {
985 for (pch = h->h_aliases; *pch; pch++) {
991 for (pch = h->h_addr_list; *pch; pch++) {
1020 const char *servicename, *protoname =
"tcp";
1027 sp = getservbyname(servicename, protoname);
1029 port = ntohs(sp->s_port);
1034 port =
STRTOUL(servicename, &end, 0);
1061 const char *protoname =
"tcp";
1065 if (portnum != (uint16_t)portnum) {
1066 const char *s = portnum > 0 ?
"big" :
"small";
1071 sp = getservbyport((
int)htons((uint16_t)portnum), protoname);
1114 VALUE host, port, family, socktype, protocol, flags, ret, revlookup;
1118 rb_scan_args(argc, argv,
"25", &host, &port, &family, &socktype, &protocol, &flags, &revlookup);
1123 if (!
NIL_P(socktype)) {
1126 if (!
NIL_P(protocol)) {
1129 if (!
NIL_P(flags)) {
1168 char hbuf[1024], pbuf[1024];
1173 struct sockaddr *sap;
1179 if (!
NIL_P(flags)) {
1192 sap = (
struct sockaddr*)&ss;
1216 #ifdef AI_NUMERICHOST
1231 hbuf[
sizeof(hbuf) - 1] =
'\0';
1245 pbuf[
sizeof(pbuf) - 1] =
'\0';
1252 if (error)
goto error_exit_addr;
1261 pbuf,
sizeof(pbuf), fl);
1262 if (error)
goto error_exit_name;
1265 char hbuf2[1024], pbuf2[1024];
1269 pbuf2,
sizeof(pbuf2), fl);
1270 if (error)
goto error_exit_name;
1271 if (strcmp(hbuf, hbuf2) != 0|| strcmp(pbuf, pbuf2) != 0) {
1332 struct sockaddr_in * sockaddr;
1337 (
char*)&((
struct sockaddr *)sockaddr)->sa_family +
1338 sizeof(((
struct sockaddr *)sockaddr)->sa_family) -
1341 if (((
struct sockaddr *)sockaddr)->sa_family != AF_INET
1343 && ((
struct sockaddr *)sockaddr)->sa_family != AF_INET6
1357 #ifdef HAVE_SYS_UN_H
1370 sock_s_pack_sockaddr_un(
VALUE self,
VALUE path)
1372 struct sockaddr_un sockaddr;
1376 MEMZERO(&sockaddr,
struct sockaddr_un, 1);
1377 sockaddr.sun_family = AF_UNIX;
1378 if (
sizeof(sockaddr.sun_path) < (
size_t)
RSTRING_LEN(path)) {
1380 (
size_t)
RSTRING_LEN(path),
sizeof(sockaddr.sun_path));
1383 addr =
rb_str_new((
char*)&sockaddr, rsock_unix_sockaddr_len(path));
1402 sock_s_unpack_sockaddr_un(
VALUE self,
VALUE addr)
1404 struct sockaddr_un * sockaddr;
1409 (
char*)&((
struct sockaddr *)sockaddr)->sa_family +
1410 sizeof(((
struct sockaddr *)sockaddr)->sa_family) -
1413 if (((
struct sockaddr *)sockaddr)->sa_family != AF_UNIX) {
1416 if (
sizeof(
struct sockaddr_un) < (
size_t)
RSTRING_LEN(addr)) {
1418 RSTRING_LEN(addr), (
int)
sizeof(
struct sockaddr_un));
1426 #if defined(HAVE_GETIFADDRS) || defined(SIOCGLIFCONF) || defined(SIOCGIFCONF) || defined(_WIN32)
1428 sockaddr_obj(
struct sockaddr *addr)
1431 #if defined(AF_INET6) && defined(__KAME__)
1432 struct sockaddr_in6 addr6;
1438 switch (addr->sa_family) {
1440 len = (socklen_t)
sizeof(
struct sockaddr_in);
1445 len = (socklen_t)
sizeof(
struct sockaddr_in6);
1450 memcpy(&addr6, addr, len);
1451 addr = (
struct sockaddr *)&addr6;
1452 if (IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr) &&
1453 addr6.sin6_scope_id == 0 &&
1454 (addr6.sin6_addr.s6_addr[2] || addr6.sin6_addr.s6_addr[3])) {
1455 addr6.sin6_scope_id = (addr6.sin6_addr.s6_addr[2] << 8) | addr6.sin6_addr.s6_addr[3];
1456 addr6.sin6_addr.s6_addr[2] = 0;
1457 addr6.sin6_addr.s6_addr[3] = 0;
1463 #ifdef HAVE_SYS_UN_H
1465 len = (socklen_t)
sizeof(
struct sockaddr_un);
1470 len = (socklen_t)
sizeof(
struct sockaddr_in);
1474 if (len < (socklen_t)
SA_LEN(addr))
1475 len = (socklen_t)
SA_LEN(addr);
1482 #if defined(HAVE_GETIFADDRS) || (defined(SIOCGLIFCONF) && defined(SIOCGLIFNUM) && !defined(__hpux)) || defined(SIOCGIFCONF) || defined(_WIN32)
1501 #if defined(HAVE_GETIFADDRS)
1502 struct ifaddrs *ifp =
NULL;
1507 ret = getifaddrs(&ifp);
1513 for (p = ifp;
p; p = p->ifa_next) {
1514 if (p->ifa_addr != NULL &&
IS_IP_FAMILY(p->ifa_addr->sa_family)) {
1522 #elif defined(SIOCGLIFCONF) && defined(SIOCGLIFNUM) && !defined(__hpux)
1529 char *reason =
NULL;
1536 fd = socket(AF_INET, SOCK_DGRAM, 0);
1540 memset(&ln, 0,
sizeof(ln));
1543 ret =
ioctl(fd, SIOCGLIFNUM, &ln);
1545 reason =
"SIOCGLIFNUM";
1549 memset(&lc, 0,
sizeof(lc));
1552 lc.lifc_len =
sizeof(
struct lifreq) * ln.lifn_count;
1553 lc.lifc_req =
xmalloc(lc.lifc_len);
1555 ret =
ioctl(fd, SIOCGLIFCONF, &lc);
1557 reason =
"SIOCGLIFCONF";
1562 for (i = 0; i < ln.lifn_count; i++) {
1563 struct lifreq *req = &lc.lifc_req[
i];
1565 if (req->lifr_addr.ss_family == AF_INET6 &&
1566 IN6_IS_ADDR_LINKLOCAL(&((
struct sockaddr_in6 *)(&req->lifr_addr))->sin6_addr) &&
1567 ((
struct sockaddr_in6 *)(&req->lifr_addr))->sin6_scope_id == 0) {
1569 memcpy(req2.lifr_name, req->lifr_name, LIFNAMSIZ);
1570 ret =
ioctl(fd, SIOCGLIFINDEX, &req2);
1572 reason =
"SIOCGLIFINDEX";
1575 ((
struct sockaddr_in6 *)(&req->lifr_addr))->sin6_scope_id = req2.lifr_index;
1577 rb_ary_push(list, sockaddr_obj((
struct sockaddr *)&req->lifr_addr));
1583 if (lc.lifc_buf != NULL)
1593 #elif defined(SIOCGIFCONF)
1596 #define EXTRA_SPACE (sizeof(struct ifconf) + sizeof(struct sockaddr_storage))
1597 char initbuf[4096+EXTRA_SPACE];
1598 char *buf = initbuf;
1603 const char *reason =
NULL;
1606 fd = socket(AF_INET, SOCK_DGRAM, 0);
1610 bufsize =
sizeof(initbuf);
1614 conf.ifc_len = bufsize;
1615 conf.ifc_req = (
struct ifreq *)buf;
1619 ret =
ioctl(fd, SIOCGIFCONF, &conf);
1621 reason =
"SIOCGIFCONF";
1627 if (bufsize - EXTRA_SPACE < conf.ifc_len) {
1628 if (bufsize < conf.ifc_len) {
1630 bufsize = conf.ifc_len + EXTRA_SPACE;
1633 bufsize = bufsize << 1;
1646 while ((
char*)req < (
char*)conf.ifc_req + conf.ifc_len) {
1647 struct sockaddr *addr = &req->ifr_addr;
1652 # ifndef _SIZEOF_ADDR_IFREQ
1653 # define _SIZEOF_ADDR_IFREQ(r) \
1654 (sizeof(struct ifreq) + \
1655 (sizeof(struct sockaddr) < (r).ifr_addr.sa_len ? \
1656 (r).ifr_addr.sa_len - sizeof(struct sockaddr) : \
1659 req = (
struct ifreq *)((
char*)req + _SIZEOF_ADDR_IFREQ(*req));
1661 req = (
struct ifreq *)((
char*)req +
sizeof(
struct ifreq));
1679 #elif defined(_WIN32)
1680 typedef struct ip_adapter_unicast_address_st {
1681 unsigned LONG_LONG dummy0;
1682 struct ip_adapter_unicast_address_st *
Next;
1684 struct sockaddr *lpSockaddr;
1685 int iSockaddrLength;
1693 } ip_adapter_unicast_address_t;
1694 typedef struct ip_adapter_anycast_address_st {
1695 unsigned LONG_LONG dummy0;
1696 struct ip_adapter_anycast_address_st *
Next;
1698 struct sockaddr *lpSockaddr;
1699 int iSockaddrLength;
1701 } ip_adapter_anycast_address_t;
1702 typedef struct ip_adapter_addresses_st {
1703 unsigned LONG_LONG dummy0;
1704 struct ip_adapter_addresses_st *
Next;
1706 ip_adapter_unicast_address_t *FirstUnicastAddress;
1707 ip_adapter_anycast_address_t *FirstAnycastAddress;
1722 } ip_adapter_addresses_t;
1723 typedef ULONG (WINAPI *GetAdaptersAddresses_t)(
ULONG,
ULONG, PVOID, ip_adapter_addresses_t *, PULONG);
1725 GetAdaptersAddresses_t pGetAdaptersAddresses;
1728 ip_adapter_addresses_t *adapters;
1731 h = LoadLibrary(
"iphlpapi.dll");
1734 pGetAdaptersAddresses = (GetAdaptersAddresses_t)GetProcAddress(h,
"GetAdaptersAddresses");
1735 if (!pGetAdaptersAddresses) {
1740 ret = pGetAdaptersAddresses(
AF_UNSPEC, 0, NULL, NULL, &len);
1741 if (ret != ERROR_SUCCESS && ret != ERROR_BUFFER_OVERFLOW) {
1746 adapters = (ip_adapter_addresses_t *)
ALLOCA_N(BYTE, len);
1747 ret = pGetAdaptersAddresses(
AF_UNSPEC, 0, NULL, adapters, &len);
1748 if (ret != ERROR_SUCCESS) {
1755 for (; adapters; adapters = adapters->Next) {
1756 ip_adapter_unicast_address_t *uni;
1757 ip_adapter_anycast_address_t *any;
1758 if (adapters->OperStatus != 1)
1760 for (uni = adapters->FirstUnicastAddress; uni; uni = uni->Next) {
1762 if (uni->Address.lpSockaddr->sa_family == AF_INET)
1766 rb_ary_push(list, sockaddr_obj(uni->Address.lpSockaddr));
1768 for (any = adapters->FirstAnycastAddress; any; any = any->Next) {
1770 if (any->Address.lpSockaddr->sa_family == AF_INET)
1774 rb_ary_push(list, sockaddr_obj(any->Address.lpSockaddr));
1783 #define socket_s_ip_address_list rb_f_notimplement
1924 #ifdef HAVE_SYS_UN_H