41 #include "ruby/config.h" 43 #include RUBY_EXTCONF_H 45 #include <sys/types.h> 47 #include <sys/param.h> 48 #include <sys/socket.h> 49 #include <netinet/in.h> 50 #if defined(HAVE_ARPA_INET_H) 51 #include <arpa/inet.h> 53 #if defined(HAVE_ARPA_NAMESER_H) 54 #include <arpa/nameser.h> 57 #if defined(HAVE_RESOLV_H) 65 #if defined(_MSC_VER) && _MSC_VER <= 1200 82 #ifndef HAVE_TYPE_SOCKLEN_T 95 static int translate =
NO;
96 static struct in6_addr faith_prefix = IN6ADDR_ANY_INIT;
99 static const char in_addrany[] = { 0, 0, 0, 0 };
100 static const char in6_addrany[] = {
101 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
103 static const char in_loopback[] = { 127, 0, 0, 1 };
104 static const char in6_loopback[] = {
105 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
114 static const struct afd {
119 const char *a_addrany;
120 const char *a_loopback;
124 {PF_INET6,
sizeof(
struct in6_addr),
125 sizeof(struct sockaddr_in6),
126 offsetof(struct sockaddr_in6, sin6_addr),
127 in6_addrany, in6_loopback},
132 {
PF_INET,
sizeof(
struct in_addr),
133 sizeof(struct sockaddr_in),
134 offsetof(struct sockaddr_in, sin_addr),
135 in_addrany, in_loopback},
136 {0, 0, 0, 0,
NULL, NULL},
145 static int get_name
__P((
const char *,
const struct afd *,
148 static int get_addr
__P((
const char *,
int,
struct addrinfo **,
150 static int str_isnumber
__P((
const char *));
152 static const char *
const ai_errlist[] = {
154 "address family for hostname not supported.",
155 "temporary failure in name resolution.",
156 "invalid value for ai_flags.",
157 "non-recoverable failure in name resolution.",
158 "ai_family not supported.",
159 "memory allocation failure.",
160 "no address associated with hostname.",
161 "hostname nor servname provided, or not known.",
162 "servname not supported for ai_socktype.",
163 "ai_socktype not supported.",
164 "system error returned in errno.",
165 "invalid value for hints.",
166 "resolved protocol is unknown.",
170 #define GET_CANONNAME(ai, str) \ 171 if (pai->ai_flags & AI_CANONNAME) {\ 172 if (((ai)->ai_canonname = (char *)malloc(strlen(str) + 1)) != NULL) {\ 173 strcpy((ai)->ai_canonname, (str));\ 180 #define GET_AI(ai, afd, addr, port) {\ 182 if (((ai) = (struct addrinfo *)malloc(sizeof(struct addrinfo) +\ 183 ((afd)->a_socklen)))\ 188 memcpy((ai), pai, sizeof(struct addrinfo));\ 189 (ai)->ai_addr = (struct sockaddr *)((ai) + 1);\ 190 (ai)->ai_family = (afd)->a_af;\ 191 (ai)->ai_addrlen = (afd)->a_socklen;\ 192 INIT_SOCKADDR((ai)->ai_addr, (afd)->a_af, (afd)->a_socklen);\ 193 ((struct sockinet *)(ai)->ai_addr)->si_port = (port);\ 194 p = (char *)((ai)->ai_addr);\ 195 memcpy(p + (afd)->a_off, (addr), (afd)->a_addrlen);\ 198 #define ERR(err) { error = (err); goto bad; } 200 #ifndef HAVE_GAI_STRERROR 201 #ifdef GAI_STRERROR_CONST 207 if (ecode < 0 || ecode >
EAI_MAX)
209 return (
char *)ai_errlist[ecode];
224 }
while ((ai = next) !=
NULL);
228 str_isnumber(
const char *p)
239 #ifndef HAVE_INET_PTON 242 inet_pton(
int af,
const char *hostname,
void *pton)
246 #ifdef HAVE_INET_ATON 247 if (!inet_aton(hostname, &in))
253 if (sscanf(hostname,
"%d.%d.%d.%d%c", &d1, &d2, &d3, &d4, &ch) == 4 &&
254 0 <= d1 && d1 <= 255 && 0 <= d2 && d2 <= 255 &&
255 0 <= d3 && d3 <= 255 && 0 <= d4 && d4 <= 255) {
257 ((
long) d1 << 24) | ((
long) d2 << 16) |
258 ((
long) d3 << 8) | ((
long) d4 << 0));
264 memcpy(pton, &in,
sizeof(in));
282 static int firsttime = 1;
288 if (q && inet_pton(AF_INET6, q, &faith_prefix) == 1)
309 if (hostname ==
NULL && servname ==
NULL)
328 memcpy(pai, hints,
sizeof(*pai));
341 #if defined(SOCK_RAW) 347 #if defined(SOCK_RAW) 373 if (str_isnumber(servname)) {
379 port = htons((
unsigned short)atoi(servname));
398 fprintf(stderr,
"panic!\n");
401 if ((sp = getservbyname((
char*)servname, proto)) ==
NULL)
405 if (strcmp(sp->s_proto,
"udp") == 0) {
408 }
else if (strcmp(sp->s_proto,
"tcp") == 0) {
421 if (hostname ==
NULL) {
422 const struct afd *afd;
425 for (afd = &afdl[0]; afd->a_af; afd++) {
435 s = socket(afd->a_af, SOCK_DGRAM, 0);
463 for (i = 0; afdl[i].a_af; i++) {
464 if (inet_pton(afdl[i].a_af, hostname, pton)) {
470 switch (afdl[i].a_af) {
472 v4a = ((
struct in_addr *)pton)->s_addr;
481 pfx = ((
struct in6_addr *)pton)->s6_addr[0];
482 if (pfx == 0 || pfx == 0xfe || pfx == 0xff)
491 GET_AI(top, &afdl[i], pton, port);
503 get_name(pton, &afdl[i], &top, pton, pai, port);
514 error = get_addr(hostname, pai->
ai_family, &top, pai, port);
532 get_name(
const char *addr,
const struct afd *afd,
struct addrinfo **res,
char *numaddr,
struct addrinfo *pai,
int port0)
543 hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error);
545 hp = gethostbyaddr((
char*)addr, afd->a_addrlen, AF_INET);
547 if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {
548 GET_AI(cur, afd, hp->h_addr_list[0], port);
551 GET_AI(cur, afd, numaddr, port);
572 get_addr(
const char *hostname,
int af,
struct addrinfo **res,
struct addrinfo *pai,
int port0)
578 const struct afd *afd;
579 int i, error = 0, h_error;
587 hp = getipnodebyname(hostname, AF_INET6,
593 hp = gethostbyname((
char*)hostname);
613 if ((hp->h_name ==
NULL) || (hp->h_name[0] == 0) ||
614 (hp->h_addr_list[0] ==
NULL))
617 for (i = 0; (ap = hp->h_addr_list[i]) !=
NULL; i++) {
621 afd = &afdl[N_INET6];
632 if (IN6_IS_ADDR_V4MAPPED((
struct in6_addr *)ap)) {
633 ap +=
sizeof(
struct in6_addr) -
634 sizeof(struct in_addr);
637 afd = &afdl[N_INET6];
642 if (translate && afd->a_af == AF_INET) {
643 struct in6_addr *in6;
647 memcpy(&in6->s6_addr, &faith_prefix,
648 sizeof(
struct in6_addr) -
sizeof(
struct in_addr));
649 memcpy(&in6->s6_addr +
sizeof(
struct in_addr), ap,
650 sizeof(
struct in_addr));
654 if (cur == &sentinel) {
size_t strlen(const char *)
#define GET_CANONNAME(ai, str)
if(len<=MAX_WORD_LENGTH &&len >=MIN_WORD_LENGTH)
#define GET_AI(ai, afd, addr, port)
int getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res)
char * gai_strerror(int ecode)
void freeaddrinfo(struct addrinfo *ai)
#define IN_EXPERIMENTAL(i)
struct addrinfo * ai_next
struct sockaddr * ai_addr