require 'mkmf' case RUBY_PLATFORM when /(ms|bcc)win32|mingw/ test_func = "WSACleanup" have_library("ws2_32", "WSACleanup") when /cygwin/ test_func = "socket" when /beos/ test_func = "socket" have_library("net", "socket") when /i386-os2_emx/ test_func = "socket" have_library("socket", "socket") else test_func = "socket" have_library("nsl", "t_open") have_library("socket", "socket") end unless $mswin or $bccwin or $mingw headers = %w end if /solaris/ =~ RUBY_PLATFORM and !try_compile("") # bug of gcc 3.0 on Solaris 8 ? headers << "sys/feature_tests.h" end if have_header("arpa/inet.h") headers << "arpa/inet.h" end ipv6 = false default_ipv6 = /cygwin/ !~ RUBY_PLATFORM if enable_config("ipv6", default_ipv6) if checking_for("ipv6") {try_link(< #include main() { socket(AF_INET6, SOCK_STREAM, 0); } EOF $defs << "-DENABLE_IPV6" << "-DINET6" ipv6 = true end end if ipv6 ipv6lib = nil class << (fmt = "unknown") def %(s) s || self end end idirs, ldirs = dir_config("inet6", %w[/usr/inet6 /usr/local/v6].find {|d| File.directory?(d)}) checking_for("ipv6 type", fmt) do if have_macro("IPV6_INRIA_VERSION", "netinet/in.h") "inria" elsif have_macro("__KAME__", "netinet/in.h") have_library(ipv6lib = "inet6") "kame" elsif have_macro("_TOSHIBA_INET6", "sys/param.h") have_library(ipv6lib = "inet6") and "toshiba" elsif have_macro("__V6D__", "sys/v6config.h") have_library(ipv6lib = "v6") and "v6d" elsif have_macro("_ZETA_MINAMI_INET6", "sys/param.h") have_library(ipv6lib = "inet6") and "zeta" elsif ipv6lib = with_config("ipv6-lib") warn < #ifndef EXIT_SUCCESS #define EXIT_SUCCESS 0 #endif #ifndef EXIT_FAILURE #define EXIT_FAILURE 1 #endif #ifndef AF_LOCAL #define AF_LOCAL AF_UNIX #endif main() { int passive, gaierr, inet4 = 0, inet6 = 0; struct addrinfo hints, *ai, *aitop; char straddr[INET6_ADDRSTRLEN], strport[16]; for (passive = 0; passive <= 1; passive++) { memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = passive ? AI_PASSIVE : 0; hints.ai_socktype = SOCK_STREAM; if ((gaierr = getaddrinfo(NULL, "54321", &hints, &aitop)) != 0) { (void)gai_strerror(gaierr); goto bad; } for (ai = aitop; ai; ai = ai->ai_next) { if (ai->ai_family == AF_LOCAL) continue; if (ai->ai_addr == NULL) goto bad; #if defined(_AIX) ai->ai_addr->sa_len = ai->ai_addrlen; ai->ai_addr->sa_family = ai->ai_family; #endif if (ai->ai_addrlen == 0 || getnameinfo(ai->ai_addr, ai->ai_addrlen, straddr, sizeof(straddr), strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) { goto bad; } if (strcmp(strport, "54321") != 0) { goto bad; } switch (ai->ai_family) { case AF_INET: if (passive) { if (strcmp(straddr, "0.0.0.0") != 0) { goto bad; } } else { if (strcmp(straddr, "127.0.0.1") != 0) { goto bad; } } inet4++; break; case AF_INET6: if (passive) { if (strcmp(straddr, "::") != 0) { goto bad; } } else { if (strcmp(straddr, "::1") != 0) { goto bad; } } inet6++; break; case AF_UNSPEC: goto bad; break; default: /* another family support? */ break; } } } if (!(inet4 == 0 || inet4 == 2)) goto bad; if (!(inet6 == 0 || inet6 == 2)) goto bad; if (aitop) freeaddrinfo(aitop); exit(EXIT_SUCCESS); bad: if (aitop) freeaddrinfo(aitop); exit(EXIT_FAILURE); } EOF end if ipv6 and not getaddr_info_ok abort <