diff options
author | itojun <> | 2000-01-26 06:51:26 +0000 |
---|---|---|
committer | itojun <> | 2000-01-26 06:51:26 +0000 |
commit | b2771c0992b93d3fc05508e5ff024fc970f22653 (patch) | |
tree | 740f2a86573e37e02c3807dcfa403a49402bf45d | |
parent | 6eb19fcc6e8f0878f8f20804e075b3c6d5b393ac (diff) | |
download | openbsd-b2771c0992b93d3fc05508e5ff024fc970f22653.tar.gz openbsd-b2771c0992b93d3fc05508e5ff024fc970f22653.tar.bz2 openbsd-b2771c0992b93d3fc05508e5ff024fc970f22653.zip |
fix RFC2553 conformance. AI_CANONNAME does not mean reverse query.
-rw-r--r-- | src/lib/libc/net/getaddrinfo.c | 136 |
1 files changed, 10 insertions, 126 deletions
diff --git a/src/lib/libc/net/getaddrinfo.c b/src/lib/libc/net/getaddrinfo.c index d06d4e96fb..47b298f9c5 100644 --- a/src/lib/libc/net/getaddrinfo.c +++ b/src/lib/libc/net/getaddrinfo.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: getaddrinfo.c,v 1.8 2000/01/18 10:20:00 itojun Exp $ */ | 1 | /* $OpenBSD: getaddrinfo.c,v 1.9 2000/01/26 06:51:26 itojun Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. | 4 | * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. |
@@ -156,8 +156,6 @@ static int explore_numeric __P((const struct addrinfo *, const char *, | |||
156 | const char *, struct addrinfo **)); | 156 | const char *, struct addrinfo **)); |
157 | static int explore_numeric_scope __P((const struct addrinfo *, const char *, | 157 | static int explore_numeric_scope __P((const struct addrinfo *, const char *, |
158 | const char *, struct addrinfo **)); | 158 | const char *, struct addrinfo **)); |
159 | static int get_name __P((const char *, const struct afd *, struct addrinfo **, | ||
160 | char *, const struct addrinfo *, const char *)); | ||
161 | static int get_canonname __P((const struct addrinfo *, | 159 | static int get_canonname __P((const struct addrinfo *, |
162 | struct addrinfo *, const char *)); | 160 | struct addrinfo *, const char *)); |
163 | static struct addrinfo *get_ai __P((const struct addrinfo *, | 161 | static struct addrinfo *get_ai __P((const struct addrinfo *, |
@@ -551,22 +549,15 @@ explore_fqdn(pai, hostname, servname, res) | |||
551 | if (af != pai->ai_family) | 549 | if (af != pai->ai_family) |
552 | continue; | 550 | continue; |
553 | 551 | ||
554 | if ((pai->ai_flags & AI_CANONNAME) == 0) { | 552 | GET_AI(cur->ai_next, afd, ap); |
555 | GET_AI(cur->ai_next, afd, ap); | 553 | GET_PORT(cur->ai_next, servname); |
556 | GET_PORT(cur->ai_next, servname); | 554 | if ((pai->ai_flags & AI_CANONNAME) != 0) { |
557 | } else { | ||
558 | /* | 555 | /* |
559 | * if AI_CANONNAME and if reverse lookup | 556 | * RFC2553 says that ai_canonname will be set only for |
560 | * fail, return ai anyway to pacify | 557 | * the first element. we do it for all the elements, |
561 | * calling application. | 558 | * just for convenience. |
562 | * | ||
563 | * XXX getaddrinfo() is a name->address | ||
564 | * translation function, and it looks | ||
565 | * strange that we do addr->name | ||
566 | * translation here. | ||
567 | */ | 559 | */ |
568 | get_name(ap, afd, &cur->ai_next, | 560 | GET_CANONNAME(cur->ai_next, hp->h_name); |
569 | ap, pai, servname); | ||
570 | } | 561 | } |
571 | 562 | ||
572 | while (cur && cur->ai_next) | 563 | while (cur && cur->ai_next) |
@@ -686,48 +677,10 @@ explore_numeric(pai, hostname, servname, res) | |||
686 | flags = pai->ai_flags; | 677 | flags = pai->ai_flags; |
687 | 678 | ||
688 | if (inet_pton(afd->a_af, hostname, pton) == 1) { | 679 | if (inet_pton(afd->a_af, hostname, pton) == 1) { |
689 | u_int32_t v4a; | ||
690 | #ifdef INET6 | ||
691 | u_char pfx; | ||
692 | #endif | ||
693 | |||
694 | switch (afd->a_af) { | ||
695 | case AF_INET: | ||
696 | v4a = (u_int32_t)ntohl(((struct in_addr *)pton)->s_addr); | ||
697 | if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a)) | ||
698 | flags &= ~AI_CANONNAME; | ||
699 | v4a >>= IN_CLASSA_NSHIFT; | ||
700 | if (v4a == 0 || v4a == IN_LOOPBACKNET) | ||
701 | flags &= ~AI_CANONNAME; | ||
702 | break; | ||
703 | #ifdef INET6 | ||
704 | case AF_INET6: | ||
705 | pfx = ((struct in6_addr *)pton)->s6_addr[0]; | ||
706 | if (pfx == 0 || pfx == 0xfe || pfx == 0xff) | ||
707 | flags &= ~AI_CANONNAME; | ||
708 | break; | ||
709 | #endif | ||
710 | } | ||
711 | |||
712 | if (pai->ai_family == afd->a_af || | 680 | if (pai->ai_family == afd->a_af || |
713 | pai->ai_family == PF_UNSPEC /*?*/) { | 681 | pai->ai_family == PF_UNSPEC /*?*/) { |
714 | if ((flags & AI_CANONNAME) == 0) { | 682 | GET_AI(cur->ai_next, afd, pton); |
715 | GET_AI(cur->ai_next, afd, pton); | 683 | GET_PORT(cur->ai_next, servname); |
716 | GET_PORT(cur->ai_next, servname); | ||
717 | } else { | ||
718 | /* | ||
719 | * if AI_CANONNAME and if reverse lookup | ||
720 | * fail, return ai anyway to pacify | ||
721 | * calling application. | ||
722 | * | ||
723 | * XXX getaddrinfo() is a name->address | ||
724 | * translation function, and it looks | ||
725 | * strange that we do addr->name | ||
726 | * translation here. | ||
727 | */ | ||
728 | get_name(pton, afd, &cur->ai_next, | ||
729 | pton, pai, servname); | ||
730 | } | ||
731 | while (cur && cur->ai_next) | 684 | while (cur && cur->ai_next) |
732 | cur = cur->ai_next; | 685 | cur = cur->ai_next; |
733 | } else | 686 | } else |
@@ -819,75 +772,6 @@ explore_numeric_scope(pai, hostname, servname, res) | |||
819 | } | 772 | } |
820 | 773 | ||
821 | static int | 774 | static int |
822 | get_name(addr, afd, res, numaddr, pai, servname) | ||
823 | const char *addr; | ||
824 | const struct afd *afd; | ||
825 | struct addrinfo **res; | ||
826 | char *numaddr; | ||
827 | const struct addrinfo *pai; | ||
828 | const char *servname; | ||
829 | { | ||
830 | struct hostent *hp = NULL; | ||
831 | struct addrinfo *cur = NULL; | ||
832 | int error = 0; | ||
833 | char *ap = NULL, *cn = NULL; | ||
834 | #ifdef USE_GETIPNODEBY | ||
835 | int h_error; | ||
836 | |||
837 | hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error); | ||
838 | #else | ||
839 | hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af); | ||
840 | #endif | ||
841 | if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) { | ||
842 | #ifdef USE_GETIPNODEBY | ||
843 | GET_AI(cur, afd, hp->h_addr_list[0]); | ||
844 | GET_PORT(cur, servname); | ||
845 | GET_CANONNAME(cur, hp->h_name); | ||
846 | #else | ||
847 | /* hp will be damaged if we use gethostbyaddr() */ | ||
848 | if ((ap = (char *)malloc(hp->h_length)) == NULL) { | ||
849 | error = EAI_MEMORY; | ||
850 | goto free; | ||
851 | } | ||
852 | memcpy(ap, hp->h_addr_list[0], hp->h_length); | ||
853 | if ((cn = strdup(hp->h_name)) == NULL) { | ||
854 | error = EAI_MEMORY; | ||
855 | goto free; | ||
856 | } | ||
857 | |||
858 | GET_AI(cur, afd, ap); | ||
859 | GET_PORT(cur, servname); | ||
860 | GET_CANONNAME(cur, cn); | ||
861 | free(ap); ap = NULL; | ||
862 | free(cn); cn = NULL; | ||
863 | #endif | ||
864 | } else { | ||
865 | GET_AI(cur, afd, numaddr); | ||
866 | GET_PORT(cur, servname); | ||
867 | } | ||
868 | |||
869 | #ifdef USE_GETIPNODEBY | ||
870 | if (hp) | ||
871 | freehostent(hp); | ||
872 | #endif | ||
873 | *res = cur; | ||
874 | return SUCCESS; | ||
875 | free: | ||
876 | if (cur) | ||
877 | freeaddrinfo(cur); | ||
878 | if (ap) | ||
879 | free(ap); | ||
880 | if (cn) | ||
881 | free(cn); | ||
882 | #ifdef USE_GETIPNODEBY | ||
883 | if (hp) | ||
884 | freehostent(hp); | ||
885 | #endif | ||
886 | *res = NULL; | ||
887 | return error; | ||
888 | } | ||
889 | |||
890 | static int | ||
891 | get_canonname(pai, ai, str) | 775 | get_canonname(pai, ai, str) |
892 | const struct addrinfo *pai; | 776 | const struct addrinfo *pai; |
893 | struct addrinfo *ai; | 777 | struct addrinfo *ai; |