データ構造 | |
struct | sockinet |
struct | afd |
関数 | |
static int | get_name (const char *, struct afd *, struct addrinfo **, char *, struct addrinfo *, int) |
static int | get_addr (const char *, int, struct addrinfo **, struct addrinfo *, int) |
static int | str_isnumber (const char *) |
static int | get_ai (struct addrinfo **to_ai, struct addrinfo const *pai, struct afd *afd, const char *addr, short port) |
char * | gai_strerror (int ecode) |
void | freeaddrinfo (struct addrinfo *ai) |
static int | str_isnumber (char *p) const |
int | getaddrinfo (char *hostname, char *servname, const struct addrinfo *hints, struct addrinfo **res) const |
static int | get_name (char *addr, struct afd *afd, struct addrinfo **res, char *numaddr, struct addrinfo *pai, int port0) const |
static int | get_addr (char *hostname, int af, struct addrinfo **res, struct addrinfo *pai, int port0) const |
変数 | |
static int | translate = NO |
static struct in6_addr | faith_prefix = IN6ADDR_ANY_INIT |
static const char | in_addrany [] = { 0, 0, 0, 0 } |
static const char | in6_addrany [] |
static const char | in_loopback [] = { 127, 0, 0, 1 } |
static const char | in6_loopback [] |
static struct afd | afdl [] |
static char * | ai_errlist [] |
static int get_name | ( | const char * | , | |
struct afd * | , | |||
struct addrinfo ** | , | |||
char * | , | |||
struct addrinfo * | , | |||
int | ||||
) | [static] |
static int str_isnumber | ( | const char * | ) | [static] |
参照元 getaddrinfo().
static int get_ai | ( | struct addrinfo ** | to_ai, | |
struct addrinfo const * | pai, | |||
struct afd * | afd, | |||
const char * | addr, | |||
short | port | |||
) | [static] |
getaddrinfo.c の 149 行で定義されています。
参照元 get_addr()・get_name()・getaddrinfo().
00154 { 00155 char *p; 00156 if ((*to_ai = (struct addrinfo *)malloc(sizeof(struct addrinfo) + 00157 ((afd)->a_socklen))) 00158 == NULL) 00159 return 0; 00160 memcpy(*to_ai, pai, sizeof(struct addrinfo)); 00161 (*to_ai)->ai_addr = (struct sockaddr *)((*to_ai) + 1); 00162 memset((*to_ai)->ai_addr, 0, (afd)->a_socklen); 00163 (*to_ai)->ai_addrlen = (afd)->a_socklen; 00164 #ifdef HAVE_SOCKADDR_LEN 00165 (*to_ai)->ai_addr->sa_len = (afd)->a_socklen; 00166 #endif 00167 (*to_ai)->ai_addr->sa_family = (*to_ai)->ai_family = (afd)->a_af; 00168 ((struct sockinet *)(*to_ai)->ai_addr)->si_port = port; 00169 p = (char *)((*to_ai)->ai_addr); 00170 memcpy(p + (afd)->a_off, (addr), (afd)->a_addrlen); 00171 return 1; 00172 }
char* gai_strerror | ( | int | ecode | ) |
getaddrinfo.c の 177 行で定義されています。
参照元 check_name()・client_name()・lookup_name()・match_address()・open_socket_in()・open_socket_out()・try_bind_local().
00179 { 00180 if (ecode < 0 || ecode > EAI_MAX) 00181 ecode = EAI_MAX; 00182 return ai_errlist[ecode]; 00183 }
void freeaddrinfo | ( | struct addrinfo * | ai | ) |
getaddrinfo.c の 186 行で定義されています。
参照先 addrinfo::ai_next.
参照元 check_name()・client_name()・get_name()・match_address()・open_socket_in()・try_bind_local().
00188 { 00189 struct addrinfo *next; 00190 00191 do { 00192 next = ai->ai_next; 00193 if (ai->ai_canonname) 00194 free(ai->ai_canonname); 00195 /* no need to free(ai->ai_addr) */ 00196 free(ai); 00197 } while ((ai = next) != NULL); 00198 }
static int str_isnumber | ( | char * | p | ) | const [static] |
getaddrinfo.c の 201 行で定義されています。
00203 { 00204 char *q = (char *)p; 00205 while (*q) { 00206 if (! isdigit(*q)) 00207 return NO; 00208 q++; 00209 } 00210 return YES; 00211 }
int getaddrinfo | ( | char * | hostname, | |
char * | servname, | |||
const struct addrinfo * | hints, | |||
struct addrinfo ** | res | |||
) | const |
getaddrinfo.c の 214 行で定義されています。
参照先 afd::a_addrany・afd::a_af・afdl・addrinfo::ai_addr・addrinfo::ai_addrlen・addrinfo::ai_canonname・addrinfo::ai_family・addrinfo::ai_flags・addrinfo::ai_next・addrinfo::ai_protocol・addrinfo::ai_socktype・faith_prefix・get_ai()・inet_pton()・str_isnumber()・translate.
参照元 check_name()・client_name()・match_address()・open_socket_in()・open_socket_out()・try_bind_local().
00218 { 00219 struct addrinfo sentinel; 00220 struct addrinfo *top = NULL; 00221 struct addrinfo *cur; 00222 int i, error = 0; 00223 char pton[PTON_MAX]; 00224 struct addrinfo ai; 00225 struct addrinfo *pai; 00226 u_short port; 00227 00228 #ifdef FAITH 00229 static int firsttime = 1; 00230 00231 if (firsttime) { 00232 /* translator hack */ 00233 { 00234 char *q = getenv("GAI"); 00235 if (q && inet_pton(AF_INET6, q, &faith_prefix) == 1) 00236 translate = YES; 00237 } 00238 firsttime = 0; 00239 } 00240 #endif 00241 00242 /* initialize file static vars */ 00243 sentinel.ai_next = NULL; 00244 cur = &sentinel; 00245 pai = &ai; 00246 pai->ai_flags = 0; 00247 pai->ai_family = PF_UNSPEC; 00248 pai->ai_socktype = ANY; 00249 pai->ai_protocol = ANY; 00250 pai->ai_addrlen = 0; 00251 pai->ai_canonname = NULL; 00252 pai->ai_addr = NULL; 00253 pai->ai_next = NULL; 00254 port = ANY; 00255 00256 if (hostname == NULL && servname == NULL) 00257 return EAI_NONAME; 00258 if (hints) { 00259 /* error check for hints */ 00260 if (hints->ai_addrlen || hints->ai_canonname || 00261 hints->ai_addr || hints->ai_next) 00262 ERR(EAI_BADHINTS); /* xxx */ 00263 if (hints->ai_flags & ~AI_MASK) 00264 ERR(EAI_BADFLAGS); 00265 switch (hints->ai_family) { 00266 case PF_UNSPEC: 00267 case PF_INET: 00268 #ifdef INET6 00269 case PF_INET6: 00270 #endif 00271 break; 00272 default: 00273 ERR(EAI_FAMILY); 00274 } 00275 memcpy(pai, hints, sizeof(*pai)); 00276 switch (pai->ai_socktype) { 00277 case ANY: 00278 switch (pai->ai_protocol) { 00279 case ANY: 00280 break; 00281 case IPPROTO_UDP: 00282 pai->ai_socktype = SOCK_DGRAM; 00283 break; 00284 case IPPROTO_TCP: 00285 pai->ai_socktype = SOCK_STREAM; 00286 break; 00287 default: 00288 pai->ai_socktype = SOCK_RAW; 00289 break; 00290 } 00291 break; 00292 case SOCK_RAW: 00293 break; 00294 case SOCK_DGRAM: 00295 if (pai->ai_protocol != IPPROTO_UDP && 00296 pai->ai_protocol != ANY) 00297 ERR(EAI_BADHINTS); /*xxx*/ 00298 pai->ai_protocol = IPPROTO_UDP; 00299 break; 00300 case SOCK_STREAM: 00301 if (pai->ai_protocol != IPPROTO_TCP && 00302 pai->ai_protocol != ANY) 00303 ERR(EAI_BADHINTS); /*xxx*/ 00304 pai->ai_protocol = IPPROTO_TCP; 00305 break; 00306 default: 00307 ERR(EAI_SOCKTYPE); 00308 break; 00309 } 00310 } 00311 00312 /* 00313 * service port 00314 */ 00315 if (servname) { 00316 if (str_isnumber(servname)) { 00317 if (pai->ai_socktype == ANY) { 00318 /* caller accept *ANY* socktype */ 00319 pai->ai_socktype = SOCK_DGRAM; 00320 pai->ai_protocol = IPPROTO_UDP; 00321 } 00322 port = htons(atoi(servname)); 00323 } else { 00324 struct servent *sp; 00325 char *proto; 00326 00327 proto = NULL; 00328 switch (pai->ai_socktype) { 00329 case ANY: 00330 proto = NULL; 00331 break; 00332 case SOCK_DGRAM: 00333 proto = "udp"; 00334 break; 00335 case SOCK_STREAM: 00336 proto = "tcp"; 00337 break; 00338 default: 00339 fprintf(stderr, "panic!\n"); 00340 break; 00341 } 00342 if ((sp = getservbyname(servname, proto)) == NULL) 00343 ERR(EAI_SERVICE); 00344 port = sp->s_port; 00345 if (pai->ai_socktype == ANY) { 00346 if (strcmp(sp->s_proto, "udp") == 0) { 00347 pai->ai_socktype = SOCK_DGRAM; 00348 pai->ai_protocol = IPPROTO_UDP; 00349 } else if (strcmp(sp->s_proto, "tcp") == 0) { 00350 pai->ai_socktype = SOCK_STREAM; 00351 pai->ai_protocol = IPPROTO_TCP; 00352 } else 00353 ERR(EAI_PROTOCOL); /*xxx*/ 00354 } 00355 } 00356 } 00357 00358 /* 00359 * hostname == NULL. 00360 * passive socket -> anyaddr (0.0.0.0 or ::) 00361 * non-passive socket -> localhost (127.0.0.1 or ::1) 00362 */ 00363 if (hostname == NULL) { 00364 struct afd *afd; 00365 00366 for (afd = &afdl[0]; afd->a_af; afd++) { 00367 if (!(pai->ai_family == PF_UNSPEC 00368 || pai->ai_family == afd->a_af)) { 00369 continue; 00370 } 00371 00372 if (pai->ai_flags & AI_PASSIVE) { 00373 if (!get_ai(&cur->ai_next, pai, afd, afd->a_addrany, port)) 00374 goto free; 00375 /* xxx meaningless? 00376 * GET_CANONNAME(cur->ai_next, "anyaddr"); 00377 */ 00378 } else { 00379 if (!get_ai(&cur->ai_next, pai, afd, afd->a_loopback, 00380 port)) 00381 goto free; 00382 /* xxx meaningless? 00383 * GET_CANONNAME(cur->ai_next, "localhost"); 00384 */ 00385 } 00386 cur = cur->ai_next; 00387 } 00388 top = sentinel.ai_next; 00389 if (top) 00390 goto good; 00391 else 00392 ERR(EAI_FAMILY); 00393 } 00394 00395 /* hostname as numeric name */ 00396 for (i = 0; afdl[i].a_af; i++) { 00397 if (inet_pton(afdl[i].a_af, hostname, pton)) { 00398 u_long v4a; 00399 00400 switch (afdl[i].a_af) { 00401 case AF_INET: 00402 v4a = ((struct in_addr *)pton)->s_addr; 00403 if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a)) 00404 pai->ai_flags &= ~AI_CANONNAME; 00405 v4a >>= IN_CLASSA_NSHIFT; 00406 if (v4a == 0 || v4a == IN_LOOPBACKNET) 00407 pai->ai_flags &= ~AI_CANONNAME; 00408 break; 00409 #ifdef INET6 00410 case AF_INET6: 00411 { 00412 u_char pfx; 00413 pfx = ((struct in6_addr *)pton)->s6_addr[0]; 00414 if (pfx == 0 || pfx == 0xfe || pfx == 0xff) 00415 pai->ai_flags &= ~AI_CANONNAME; 00416 break; 00417 } 00418 #endif 00419 } 00420 00421 if (pai->ai_family == afdl[i].a_af || 00422 pai->ai_family == PF_UNSPEC) { 00423 if (! (pai->ai_flags & AI_CANONNAME)) { 00424 if (get_ai(&top, pai, &afdl[i], pton, port)) 00425 goto good; 00426 else 00427 goto free; 00428 } 00429 /* 00430 * if AI_CANONNAME and if reverse lookup 00431 * fail, return ai anyway to pacify 00432 * calling application. 00433 * 00434 * XXX getaddrinfo() is a name->address 00435 * translation function, and it looks strange 00436 * that we do addr->name translation here. 00437 */ 00438 get_name(pton, &afdl[i], &top, pton, pai, port); 00439 goto good; 00440 } else 00441 ERR(EAI_FAMILY); /*xxx*/ 00442 } 00443 } 00444 00445 if (pai->ai_flags & AI_NUMERICHOST) 00446 ERR(EAI_NONAME); 00447 00448 /* hostname as alphabetical name */ 00449 error = get_addr(hostname, pai->ai_family, &top, pai, port); 00450 if (error == 0) { 00451 if (top) { 00452 good: 00453 *res = top; 00454 return SUCCESS; 00455 } else 00456 error = EAI_FAIL; 00457 } 00458 free: 00459 if (top) 00460 freeaddrinfo(top); 00461 bad: 00462 *res = NULL; 00463 return error; 00464 }
static int get_name | ( | char * | addr, | |
struct afd * | afd, | |||
struct addrinfo ** | res, | |||
char * | numaddr, | |||
struct addrinfo * | pai, | |||
int | port0 | |||
) | const [static] |
getaddrinfo.c の 467 行で定義されています。
参照先 afd::a_addrlen・afd::a_af・freeaddrinfo()・freehostent()・get_ai().
00474 { 00475 u_short port = port0 & 0xffff; 00476 struct hostent *hp; 00477 struct addrinfo *cur; 00478 int error = 0; 00479 00480 #ifdef INET6 00481 { 00482 int h_error; 00483 hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error); 00484 } 00485 #else 00486 hp = gethostbyaddr(addr, afd->a_addrlen, AF_INET); 00487 #endif 00488 if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) { 00489 if (!get_ai(&cur, pai, afd, hp->h_addr_list[0], port)) 00490 goto free; 00491 GET_CANONNAME(cur, hp->h_name); 00492 } else { 00493 if (!get_ai(&cur, pai, afd, numaddr, port)) 00494 goto free; 00495 } 00496 00497 #ifdef INET6 00498 if (hp) 00499 freehostent(hp); 00500 #endif 00501 *res = cur; 00502 return SUCCESS; 00503 free: 00504 if (cur) 00505 freeaddrinfo(cur); 00506 #ifdef INET6 00507 if (hp) 00508 freehostent(hp); 00509 #endif 00510 /* bad: */ 00511 *res = NULL; 00512 return error; 00513 }
static int get_addr | ( | char * | hostname, | |
int | af, | |||
struct addrinfo ** | res, | |||
struct addrinfo * | pai, | |||
int | port0 | |||
) | const [static] |
getaddrinfo.c の 516 行で定義されています。
参照先 afd::a_af・afdl・addrinfo::ai_addr・addrinfo::ai_next・faith_prefix・get_ai()・translate.
00522 { 00523 u_short port = port0 & 0xffff; 00524 struct addrinfo sentinel; 00525 struct hostent *hp; 00526 struct addrinfo *top, *cur; 00527 struct afd *afd; 00528 int i, error = 0, h_error; 00529 char *ap; 00530 #ifndef INET6 00531 extern int h_errno; 00532 #endif 00533 00534 top = NULL; 00535 sentinel.ai_next = NULL; 00536 cur = &sentinel; 00537 #ifdef INET6 00538 if (af == AF_UNSPEC) { 00539 hp = getipnodebyname(hostname, AF_INET6, 00540 AI_ADDRCONFIG|AI_ALL|AI_V4MAPPED, &h_error); 00541 } else 00542 hp = getipnodebyname(hostname, af, AI_ADDRCONFIG, &h_error); 00543 #else 00544 hp = gethostbyname(hostname); 00545 h_error = h_errno; 00546 #endif 00547 if (hp == NULL) { 00548 switch (h_error) { 00549 case HOST_NOT_FOUND: 00550 case NO_DATA: 00551 error = EAI_NODATA; 00552 break; 00553 case TRY_AGAIN: 00554 error = EAI_AGAIN; 00555 break; 00556 case NO_RECOVERY: 00557 default: 00558 error = EAI_FAIL; 00559 break; 00560 } 00561 goto bad; 00562 } 00563 00564 if ((hp->h_name == NULL) || (hp->h_name[0] == 0) || 00565 (hp->h_addr_list[0] == NULL)) 00566 ERR(EAI_FAIL); 00567 00568 for (i = 0; (ap = hp->h_addr_list[i]) != NULL; i++) { 00569 switch (af) { 00570 #ifdef INET6 00571 case AF_INET6: 00572 afd = &afdl[N_INET6]; 00573 break; 00574 #endif 00575 #ifndef INET6 00576 default: /* AF_UNSPEC */ 00577 #endif 00578 case AF_INET: 00579 afd = &afdl[N_INET]; 00580 break; 00581 #ifdef INET6 00582 default: /* AF_UNSPEC */ 00583 if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) { 00584 ap += sizeof(struct in6_addr) - 00585 sizeof(struct in_addr); 00586 afd = &afdl[N_INET]; 00587 } else 00588 afd = &afdl[N_INET6]; 00589 break; 00590 #endif 00591 } 00592 #ifdef FAITH 00593 if (translate && afd->a_af == AF_INET) { 00594 struct in6_addr *in6; 00595 00596 if (!get_ai(&cur->ai_next, pai, &afdl[N_INET6], ap, port)) 00597 goto free; 00598 in6 = &((struct sockaddr_in6 *)cur->ai_next->ai_addr)->sin6_addr; 00599 memcpy(&in6->s6_addr32[0], &faith_prefix, 00600 sizeof(struct in6_addr) - sizeof(struct in_addr)); 00601 memcpy(&in6->s6_addr32[3], ap, sizeof(struct in_addr)); 00602 } else 00603 #endif /* FAITH */ 00604 if (!get_ai(&cur->ai_next, pai, afd, ap, port)) 00605 goto free; 00606 if (cur == &sentinel) { 00607 top = cur->ai_next; 00608 GET_CANONNAME(top, hp->h_name); 00609 } 00610 cur = cur->ai_next; 00611 } 00612 #ifdef INET6 00613 freehostent(hp); 00614 #endif 00615 *res = top; 00616 return SUCCESS; 00617 free: 00618 if (top) 00619 freeaddrinfo(top); 00620 #ifdef INET6 00621 if (hp) 00622 freehostent(hp); 00623 #endif 00624 bad: 00625 *res = NULL; 00626 return error; 00627 }
int translate = NO [static] |
struct in6_addr faith_prefix = IN6ADDR_ANY_INIT [static] |
const char in_addrany[] = { 0, 0, 0, 0 } [static] |
getaddrinfo.c の 66 行で定義されています。
const char in6_addrany[] [static] |
const char in_loopback[] = { 127, 0, 0, 1 } [static] |
getaddrinfo.c の 70 行で定義されています。
const char in6_loopback[] [static] |
char* ai_errlist[] [static] |
初期値:
{ "success.", "address family for hostname not supported.", "temporary failure in name resolution.", "invalid value for ai_flags.", "non-recoverable failure in name resolution.", "ai_family not supported.", "memory allocation failure.", "no address associated with hostname.", "hostname nor servname provided, or not known.", "servname not supported for ai_socktype.", "ai_socktype not supported.", "system error returned in errno.", "invalid value for hints.", "resolved protocol is unknown.", "unknown error.", }
getaddrinfo.c の 120 行で定義されています。