41 #include "ruby/config.h"
43 #include RUBY_EXTCONF_H
45 #include <sys/types.h>
47 #include <sys/param.h>
48 #if defined(__BEOS__) && !defined(__HAIKU__) && !defined(BONE)
49 # include <net/socket.h>
51 # include <sys/socket.h>
53 #include <netinet/in.h>
54 #if defined(HAVE_ARPA_INET_H)
55 #include <arpa/inet.h>
57 #if defined(HAVE_ARPA_NAMESER_H)
58 #include <arpa/nameser.h>
61 #if defined(HAVE_RESOLV_H)
92 static int translate =
NO;
93 static struct in6_addr faith_prefix = IN6ADDR_ANY_INIT;
98 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
102 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
121 {PF_INET6,
sizeof(
struct in6_addr),
122 sizeof(struct sockaddr_in6),
123 offsetof(struct sockaddr_in6, sin6_addr),
124 in6_addrany, in6_loopback},
129 {
PF_INET,
sizeof(
struct in_addr),
130 sizeof(struct sockaddr_in),
131 offsetof(struct sockaddr_in, sin_addr),
132 in_addrany, in_loopback},
151 "address family for hostname not supported.",
152 "temporary failure in name resolution.",
153 "invalid value for ai_flags.",
154 "non-recoverable failure in name resolution.",
155 "ai_family not supported.",
156 "memory allocation failure.",
157 "no address associated with hostname.",
158 "hostname nor servname provided, or not known.",
159 "servname not supported for ai_socktype.",
160 "ai_socktype not supported.",
161 "system error returned in errno.",
162 "invalid value for hints.",
163 "resolved protocol is unknown.",
167 #define GET_CANONNAME(ai, str) \
168 if (pai->ai_flags & AI_CANONNAME) {\
169 if (((ai)->ai_canonname = (char *)malloc(strlen(str) + 1)) != NULL) {\
170 strcpy((ai)->ai_canonname, (str));\
177 #define GET_AI(ai, afd, addr, port) {\
179 if (((ai) = (struct addrinfo *)malloc(sizeof(struct addrinfo) +\
180 ((afd)->a_socklen)))\
185 memcpy((ai), pai, sizeof(struct addrinfo));\
186 (ai)->ai_addr = (struct sockaddr *)((ai) + 1);\
187 memset((ai)->ai_addr, 0, (afd)->a_socklen);\
188 SET_SA_LEN((ai)->ai_addr, (ai)->ai_addrlen = (afd)->a_socklen);\
189 (ai)->ai_addr->sa_family = (ai)->ai_family = (afd)->a_af;\
190 ((struct sockinet *)(ai)->ai_addr)->si_port = (port);\
191 p = (char *)((ai)->ai_addr);\
192 memcpy(p + (afd)->a_off, (addr), (afd)->a_addrlen);\
195 #define ERR(err) { error = (err); goto bad; }
197 #ifndef HAVE_GAI_STRERROR
198 #ifdef GAI_STRERROR_CONST
204 if (ecode < 0 || ecode >
EAI_MAX)
206 return (
char *)ai_errlist[ecode];
221 }
while ((ai = next) !=
NULL);
236 #ifndef HAVE_INET_PTON
243 #ifdef HAVE_INET_ATON
244 if (!inet_aton(hostname, &in))
250 if (sscanf(hostname,
"%d.%d.%d.%d%c", &d1, &d2, &d3, &d4, &ch) == 4 &&
251 0 <= d1 && d1 <= 255 && 0 <= d2 && d2 <= 255 &&
252 0 <= d3 && d3 <= 255 && 0 <= d4 && d4 <= 255) {
254 ((
long) d1 << 24) | ((
long) d2 << 16) |
255 ((
long) d3 << 8) | ((
long) d4 << 0));
261 memcpy(pton, &in,
sizeof(in));
279 static int firsttime = 1;
285 if (q &&
inet_pton(AF_INET6, q, &faith_prefix) == 1)
306 if (hostname ==
NULL && servname ==
NULL)
325 memcpy(pai, hints,
sizeof(*pai));
338 #if defined(SOCK_RAW)
344 #if defined(SOCK_RAW)
376 port = htons((
unsigned short)atoi(servname));
395 fprintf(stderr,
"panic!\n");
398 if ((sp = getservbyname((
char*)servname, proto)) ==
NULL)
402 if (strcmp(sp->s_proto,
"udp") == 0) {
405 }
else if (strcmp(sp->s_proto,
"tcp") == 0) {
418 if (hostname ==
NULL) {
422 for (afd = &
afdl[0]; afd->
a_af; afd++) {
432 s = socket(afd->
a_af, SOCK_DGRAM, 0);
435 #if defined(__BEOS__)
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)
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);
579 int i, error = 0, h_error;
587 hp = getipnodebyname(hostname, AF_INET6,
592 hp = gethostbyname((
char*)hostname);
612 if ((hp->h_name ==
NULL) || (hp->h_name[0] == 0) ||
613 (hp->h_addr_list[0] ==
NULL))
616 for (i = 0; (ap = hp->h_addr_list[
i]) !=
NULL; i++) {
620 afd = &
afdl[N_INET6];
631 if (IN6_IS_ADDR_V4MAPPED((
struct in6_addr *)ap)) {
632 ap +=
sizeof(
struct in6_addr) -
633 sizeof(struct in_addr);
636 afd = &
afdl[N_INET6];
641 if (translate && afd->
a_af == AF_INET) {
642 struct in6_addr *in6;
646 memcpy(&in6->s6_addr, &faith_prefix,
647 sizeof(
struct in6_addr) -
sizeof(
struct in_addr));
648 memcpy(&in6->s6_addr +
sizeof(
struct in_addr), ap,
649 sizeof(
struct in_addr));
653 if (cur == &sentinel) {
static const char *const ai_errlist[]
static const char in_addrany[]
static const struct afd afdl[]
#define GET_CANONNAME(ai, str)
static int get_addr(const char *hostname, int af, struct addrinfo **res, struct addrinfo *pai, int port0)
static int get_name(const char *addr, const struct afd *afd, struct addrinfo **res, char *numaddr, struct addrinfo *pai, int port0)
static const char in_loopback[]
#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)
static int inet_pton(int af, const char *hostname, void *pton)
static const char in6_loopback[]
static int get_name __P((const char *, const struct afd *, struct addrinfo **, char *, struct addrinfo *, int))
static int str_isnumber(const char *p)
static const char in6_addrany[]
#define IN_EXPERIMENTAL(i)
struct addrinfo * ai_next
struct sockaddr * ai_addr