]>
The Tcpdump Group git mirrors - tcpdump/blob - missing/getaddrinfo.c
2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the project nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * "#ifdef FAITH" part is local hack for supporting IPv4-v6 translator.
33 * Issues to be discussed:
34 * - Thread safe-ness must be checked.
35 * - Return values. There are nonstandard return values defined and used
36 * in the source code. This is because RFC2553 is silent about which error
37 * code must be returned for which situation.
38 * - PF_UNSPEC case would be handled in getipnodebyname() with the AI_ALL flag.
45 #include <sys/types.h>
46 #include <sys/param.h>
48 #include <sys/sysctl.h>
50 #include <sys/socket.h>
52 #include <netinet/in.h>
53 #include <arpa/inet.h>
54 #include <arpa/nameser.h>
64 #ifndef HAVE_PORTABLE_PROTOTYPE
65 #include "cdecl_ext.h"
69 #ifndef HAVE_U_INT32_T
74 #ifndef HAVE_SOCKADDR_STORAGE
75 #include "sockstorage.h"
82 #if defined(__KAME__) && defined(INET6)
92 static int translate
= NO
;
93 static struct in6_addr faith_prefix
= IN6ADDR_ANY_INIT
;
96 static const char in_addrany
[] = { 0, 0, 0, 0 };
97 static const char in6_addrany
[] = {
98 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
100 static const char in_loopback
[] = { 127, 0, 0, 1 };
101 static const char in6_loopback
[] = {
102 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
109 u_int32_t si_scope_id
;
112 static const struct afd
{
117 const char *a_addrany
;
118 const char *a_loopback
;
122 {PF_INET6
, sizeof(struct in6_addr
),
123 sizeof(struct sockaddr_in6
),
124 offsetof(struct sockaddr_in6
, sin6_addr
),
125 in6_addrany
, in6_loopback
, 1},
127 {PF_INET
, sizeof(struct in_addr
),
128 sizeof(struct sockaddr_in
),
129 offsetof(struct sockaddr_in
, sin_addr
),
130 in_addrany
, in_loopback
, 0},
131 {0, 0, 0, 0, NULL
, NULL
, 0},
138 const char *e_protostr
;
140 #define WILD_AF(ex) ((ex)->e_wild & 0x01)
141 #define WILD_SOCKTYPE(ex) ((ex)->e_wild & 0x02)
142 #define WILD_PROTOCOL(ex) ((ex)->e_wild & 0x04)
145 static const struct explore explore
[] = {
147 { PF_LOCAL
, 0, ANY
, ANY
, NULL
, 0x01 },
150 { PF_INET6
, SOCK_DGRAM
, IPPROTO_UDP
, "udp", 0x07 },
151 { PF_INET6
, SOCK_STREAM
, IPPROTO_TCP
, "tcp", 0x07 },
152 { PF_INET6
, SOCK_RAW
, ANY
, NULL
, 0x05 },
154 { PF_INET
, SOCK_DGRAM
, IPPROTO_UDP
, "udp", 0x07 },
155 { PF_INET
, SOCK_STREAM
, IPPROTO_TCP
, "tcp", 0x07 },
156 { PF_INET
, SOCK_RAW
, ANY
, NULL
, 0x05 },
157 { -1, 0, 0, NULL
, 0 },
167 static int str_isnumber
__P((const char *));
168 static int explore_fqdn
__P((const struct addrinfo
*, const char *,
169 const char *, struct addrinfo
**));
170 static int explore_null
__P((const struct addrinfo
*, const char *,
171 const char *, struct addrinfo
**));
172 static int explore_numeric
__P((const struct addrinfo
*, const char *,
173 const char *, struct addrinfo
**));
174 static int explore_numeric_scope
__P((const struct addrinfo
*, const char *,
175 const char *, struct addrinfo
**));
176 static int get_name
__P((const char *, const struct afd
*, struct addrinfo
**,
177 char *, const struct addrinfo
*, const char *));
178 static int get_canonname
__P((const struct addrinfo
*,
179 struct addrinfo
*, const char *));
180 static struct addrinfo
*get_ai
__P((const struct addrinfo
*,
181 const struct afd
*, const char *));
182 static int get_portmatch
__P((const struct addrinfo
*, const char *));
183 static int get_port
__P((struct addrinfo
*, const char *, int));
184 static const struct afd
*find_afd
__P((int));
186 static char *ai_errlist
[] = {
188 "Address family for hostname not supported", /* EAI_ADDRFAMILY */
189 "Temporary failure in name resolution", /* EAI_AGAIN */
190 "Invalid value for ai_flags", /* EAI_BADFLAGS */
191 "Non-recoverable failure in name resolution", /* EAI_FAIL */
192 "ai_family not supported", /* EAI_FAMILY */
193 "Memory allocation failure", /* EAI_MEMORY */
194 "No address associated with hostname", /* EAI_NODATA */
195 "hostname nor servname provided, or not known", /* EAI_NONAME */
196 "servname not supported for ai_socktype", /* EAI_SERVICE */
197 "ai_socktype not supported", /* EAI_SOCKTYPE */
198 "System error returned in errno", /* EAI_SYSTEM */
199 "Invalid value for hints", /* EAI_BADHINTS */
200 "Resolved protocol is unknown", /* EAI_PROTOCOL */
201 "Unknown error", /* EAI_MAX */
204 /* XXX macros that make external reference is BAD. */
206 #define GET_AI(ai, afd, addr) \
208 /* external reference: pai, error, and label free */ \
209 (ai) = get_ai(pai, (afd), (addr)); \
210 if ((ai) == NULL) { \
211 error = EAI_MEMORY; \
216 #define GET_PORT(ai, serv) \
218 /* external reference: error and label free */ \
219 error = get_port((ai), (serv), 0); \
224 #define GET_CANONNAME(ai, str) \
226 /* external reference: pai, error and label free */ \
227 error = get_canonname(pai, (ai), (str)); \
234 /* external reference: error, and label bad */ \
239 #define MATCH_FAMILY(x, y, w) \
240 ((x) == (y) || ((w) && ((x) == PF_UNSPEC || (y) == PF_UNSPEC)))
241 #define MATCH(x, y, w) \
242 ((x) == (y) || ((w) && ((x) == ANY || (y) == ANY)))
248 if (ecode
< 0 || ecode
> EAI_MAX
)
250 return ai_errlist
[ecode
];
257 struct addrinfo
*next
;
261 if (ai
->ai_canonname
)
262 free(ai
->ai_canonname
);
263 /* no need to free(ai->ai_addr) */
265 } while ((ai
= next
) != NULL
);
282 getaddrinfo(hostname
, servname
, hints
, res
)
283 const char *hostname
, *servname
;
284 const struct addrinfo
*hints
;
285 struct addrinfo
**res
;
287 struct addrinfo sentinel
;
288 struct addrinfo
*cur
;
292 struct addrinfo
*pai
;
293 const struct afd
*afd
;
294 const struct explore
*ex
;
297 static int firsttime
= 1;
300 /* translator hack */
301 char *q
= getenv("GAI");
302 if (q
&& inet_pton(AF_INET6
, q
, &faith_prefix
) == 1)
308 sentinel
.ai_next
= NULL
;
312 pai
->ai_family
= PF_UNSPEC
;
313 pai
->ai_socktype
= ANY
;
314 pai
->ai_protocol
= ANY
;
316 pai
->ai_canonname
= NULL
;
320 if (hostname
== NULL
&& servname
== NULL
)
323 /* error check for hints */
324 if (hints
->ai_addrlen
|| hints
->ai_canonname
||
325 hints
->ai_addr
|| hints
->ai_next
)
326 ERR(EAI_BADHINTS
); /* xxx */
327 if (hints
->ai_flags
& ~AI_MASK
)
329 switch (hints
->ai_family
) {
339 memcpy(pai
, hints
, sizeof(*pai
));
342 * if both socktype/protocol are specified, check if they
343 * are meaningful combination.
345 if (pai
->ai_socktype
!= ANY
&& pai
->ai_protocol
!= ANY
) {
346 for (ex
= explore
; ex
->e_af
>= 0; ex
++) {
347 if (pai
->ai_family
!= ex
->e_af
)
349 if (ex
->e_socktype
== ANY
)
351 if (ex
->e_protocol
== ANY
)
353 if (pai
->ai_socktype
== ex
->e_socktype
354 && pai
->ai_protocol
!= ex
->e_protocol
) {
362 * check for special cases. (1) numeric servname is disallowed if
363 * socktype/protocol are left unspecified. (2) servname is disallowed
364 * for raw and other inet{,6} sockets.
366 if (MATCH_FAMILY(pai
->ai_family
, PF_INET
, 1)
367 || MATCH_FAMILY(pai
->ai_family
, PF_INET6
, 1)) {
370 if (pai
->ai_family
== PF_UNSPEC
)
371 pai
->ai_family
= PF_INET6
;
372 error
= get_portmatch(pai
, servname
);
381 /* NULL hostname, or numeric hostname */
382 for (ex
= explore
; ex
->e_af
>= 0; ex
++) {
385 if (!MATCH_FAMILY(pai
->ai_family
, ex
->e_af
, WILD_AF(ex
)))
387 if (!MATCH(pai
->ai_socktype
, ex
->e_socktype
, WILD_SOCKTYPE(ex
)))
389 if (!MATCH(pai
->ai_protocol
, ex
->e_protocol
, WILD_PROTOCOL(ex
)))
392 if (pai
->ai_family
== PF_UNSPEC
)
393 pai
->ai_family
= ex
->e_af
;
394 if (pai
->ai_socktype
== ANY
&& ex
->e_socktype
!= ANY
)
395 pai
->ai_socktype
= ex
->e_socktype
;
396 if (pai
->ai_protocol
== ANY
&& ex
->e_protocol
!= ANY
)
397 pai
->ai_protocol
= ex
->e_protocol
;
399 if (hostname
== NULL
)
400 error
= explore_null(pai
, hostname
, servname
, &cur
->ai_next
);
402 error
= explore_numeric_scope(pai
, hostname
, servname
, &cur
->ai_next
);
407 while (cur
&& cur
->ai_next
)
413 * If numreic representation of AF1 can be interpreted as FQDN
414 * representation of AF2, we need to think again about the code below.
416 if (sentinel
.ai_next
)
419 if (pai
->ai_flags
& AI_NUMERICHOST
)
421 if (hostname
== NULL
)
425 * hostname as alphabetical name.
426 * we would like to prefer AF_INET6 than AF_INET, so we'll make a
429 for (afd
= afdl
; afd
->a_af
; afd
++) {
432 if (!MATCH_FAMILY(pai
->ai_family
, afd
->a_af
, 1))
435 for (ex
= explore
; ex
->e_af
>= 0; ex
++) {
438 if (pai
->ai_family
== PF_UNSPEC
)
439 pai
->ai_family
= afd
->a_af
;
441 if (!MATCH_FAMILY(pai
->ai_family
, ex
->e_af
, WILD_AF(ex
)))
443 if (!MATCH(pai
->ai_socktype
, ex
->e_socktype
,
444 WILD_SOCKTYPE(ex
))) {
447 if (!MATCH(pai
->ai_protocol
, ex
->e_protocol
,
448 WILD_PROTOCOL(ex
))) {
452 if (pai
->ai_family
== PF_UNSPEC
)
453 pai
->ai_family
= ex
->e_af
;
454 if (pai
->ai_socktype
== ANY
&& ex
->e_socktype
!= ANY
)
455 pai
->ai_socktype
= ex
->e_socktype
;
456 if (pai
->ai_protocol
== ANY
&& ex
->e_protocol
!= ANY
)
457 pai
->ai_protocol
= ex
->e_protocol
;
459 error
= explore_fqdn(pai
, hostname
, servname
,
462 while (cur
&& cur
->ai_next
)
468 if (sentinel
.ai_next
)
474 if (sentinel
.ai_next
) {
476 *res
= sentinel
.ai_next
;
483 if (sentinel
.ai_next
)
484 freeaddrinfo(sentinel
.ai_next
);
490 * FQDN hostname, DNS lookup
493 explore_fqdn(pai
, hostname
, servname
, res
)
494 const struct addrinfo
*pai
;
495 const char *hostname
;
496 const char *servname
;
497 struct addrinfo
**res
;
504 struct addrinfo sentinel
, *cur
;
506 const struct afd
*afd
;
510 sentinel
.ai_next
= NULL
;
514 * filter out AFs that are not supported by the kernel
517 s
= socket(pai
->ai_family
, SOCK_DGRAM
, 0);
523 * if the servname does not match socktype/protocol, ignore it.
525 if (get_portmatch(pai
, servname
) != 0)
528 afd
= find_afd(pai
->ai_family
);
530 #ifdef USE_GETIPNODEBY
531 hp
= getipnodebyname(hostname
, pai
->ai_family
, AI_ADDRCONFIG
, &h_error
);
533 hp
= gethostbyname2(hostname
, pai
->ai_family
);
552 } else if ((hp
->h_name
== NULL
) || (hp
->h_name
[0] == 0)
553 || (hp
->h_addr_list
[0] == NULL
)) {
554 #ifdef USE_GETIPNODEBY
564 for (i
= 0; hp
->h_addr_list
[i
] != NULL
; i
++) {
566 ap
= hp
->h_addr_list
[i
];
569 && IN6_IS_ADDR_V4MAPPED((struct in6_addr
*)ap
)) {
571 ap
= ap
+ sizeof(struct in6_addr
)
572 - sizeof(struct in_addr
);
576 if (af
!= pai
->ai_family
)
579 if ((pai
->ai_flags
& AI_CANONNAME
) == 0) {
580 GET_AI(cur
->ai_next
, afd
, ap
);
581 GET_PORT(cur
->ai_next
, servname
);
584 * if AI_CANONNAME and if reverse lookup
585 * fail, return ai anyway to pacify
586 * calling application.
588 * XXX getaddrinfo() is a name->address
589 * translation function, and it looks
590 * strange that we do addr->name
593 get_name(ap
, afd
, &cur
->ai_next
,
597 while (cur
&& cur
->ai_next
)
601 *res
= sentinel
.ai_next
;
605 #ifdef USE_GETIPNODEBY
609 if (sentinel
.ai_next
)
610 freeaddrinfo(sentinel
.ai_next
);
616 * passive socket -> anyaddr (0.0.0.0 or ::)
617 * non-passive socket -> localhost (127.0.0.1 or ::1)
620 explore_null(pai
, hostname
, servname
, res
)
621 const struct addrinfo
*pai
;
622 const char *hostname
;
623 const char *servname
;
624 struct addrinfo
**res
;
627 const struct afd
*afd
;
628 struct addrinfo
*cur
;
629 struct addrinfo sentinel
;
633 sentinel
.ai_next
= NULL
;
637 * filter out AFs that are not supported by the kernel
640 s
= socket(pai
->ai_family
, SOCK_DGRAM
, 0);
646 * if the servname does not match socktype/protocol, ignore it.
648 if (get_portmatch(pai
, servname
) != 0)
651 afd
= find_afd(pai
->ai_family
);
653 if (pai
->ai_flags
& AI_PASSIVE
) {
654 GET_AI(cur
->ai_next
, afd
, afd
->a_addrany
);
656 * GET_CANONNAME(cur->ai_next, "anyaddr");
658 GET_PORT(cur
->ai_next
, servname
);
660 GET_AI(cur
->ai_next
, afd
, afd
->a_loopback
);
662 * GET_CANONNAME(cur->ai_next, "localhost");
664 GET_PORT(cur
->ai_next
, servname
);
668 *res
= sentinel
.ai_next
;
672 if (sentinel
.ai_next
)
673 freeaddrinfo(sentinel
.ai_next
);
681 explore_numeric(pai
, hostname
, servname
, res
)
682 const struct addrinfo
*pai
;
683 const char *hostname
;
684 const char *servname
;
685 struct addrinfo
**res
;
687 const struct afd
*afd
;
688 struct addrinfo
*cur
;
689 struct addrinfo sentinel
;
695 sentinel
.ai_next
= NULL
;
699 * if the servname does not match socktype/protocol, ignore it.
701 if (get_portmatch(pai
, servname
) != 0)
704 afd
= find_afd(pai
->ai_family
);
705 flags
= pai
->ai_flags
;
707 if (inet_pton(afd
->a_af
, hostname
, pton
) == 1) {
715 v4a
= (u_int32_t
)ntohl(((struct in_addr
*)pton
)->s_addr
);
716 if (IN_MULTICAST(v4a
) || IN_EXPERIMENTAL(v4a
))
717 flags
&= ~AI_CANONNAME
;
718 v4a
>>= IN_CLASSA_NSHIFT
;
719 if (v4a
== 0 || v4a
== IN_LOOPBACKNET
)
720 flags
&= ~AI_CANONNAME
;
724 pfx
= ((struct in6_addr
*)pton
)->s6_addr
[0];
725 if (pfx
== 0 || pfx
== 0xfe || pfx
== 0xff)
726 flags
&= ~AI_CANONNAME
;
731 if (pai
->ai_family
== afd
->a_af
||
732 pai
->ai_family
== PF_UNSPEC
/*?*/) {
733 if ((flags
& AI_CANONNAME
) == 0) {
734 GET_AI(cur
->ai_next
, afd
, pton
);
735 GET_PORT(cur
->ai_next
, servname
);
738 * if AI_CANONNAME and if reverse lookup
739 * fail, return ai anyway to pacify
740 * calling application.
742 * XXX getaddrinfo() is a name->address
743 * translation function, and it looks
744 * strange that we do addr->name
747 get_name(pton
, afd
, &cur
->ai_next
,
748 pton
, pai
, servname
);
750 while (cur
&& cur
->ai_next
)
753 ERR(EAI_FAMILY
); /*xxx*/
756 *res
= sentinel
.ai_next
;
761 if (sentinel
.ai_next
)
762 freeaddrinfo(sentinel
.ai_next
);
767 * numeric hostname with scope
770 explore_numeric_scope(pai
, hostname
, servname
, res
)
771 const struct addrinfo
*pai
;
772 const char *hostname
;
773 const char *servname
;
774 struct addrinfo
**res
;
776 #ifndef SCOPE_DELIMITER
777 return explore_numeric(pai
, hostname
, servname
, res
);
779 const struct afd
*afd
;
780 struct addrinfo
*cur
;
782 char *cp
, *hostname2
= NULL
;
784 struct sockaddr_in6
*sin6
;
787 * if the servname does not match socktype/protocol, ignore it.
789 if (get_portmatch(pai
, servname
) != 0)
792 afd
= find_afd(pai
->ai_family
);
794 return explore_numeric(pai
, hostname
, servname
, res
);
796 cp
= strchr(hostname
, SCOPE_DELIMITER
);
798 return explore_numeric(pai
, hostname
, servname
, res
);
801 * Handle special case of <scoped_address><delimiter><scope id>
803 hostname2
= strdup(hostname
);
804 if (hostname2
== NULL
)
806 /* terminate at the delimiter */
807 hostname2
[cp
- hostname
] = '\0';
810 switch (pai
->ai_family
) {
813 scope
= if_nametoindex(cp
);
818 error
= explore_numeric(pai
, hostname2
, servname
, res
);
820 for (cur
= *res
; cur
; cur
= cur
->ai_next
) {
821 if (cur
->ai_family
!= AF_INET6
)
823 sin6
= (struct sockaddr_in6
*)cur
->ai_addr
;
824 if (IN6_IS_ADDR_LINKLOCAL(&sin6
->sin6_addr
) ||
825 IN6_IS_ADDR_MC_LINKLOCAL(&sin6
->sin6_addr
))
826 sin6
->sin6_scope_id
= scope
;
837 get_name(addr
, afd
, res
, numaddr
, pai
, servname
)
839 const struct afd
*afd
;
840 struct addrinfo
**res
;
842 const struct addrinfo
*pai
;
843 const char *servname
;
846 struct addrinfo
*cur
;
848 #ifdef USE_GETIPNODEBY
851 hp
= getipnodebyaddr(addr
, afd
->a_addrlen
, afd
->a_af
, &h_error
);
853 hp
= gethostbyaddr(addr
, afd
->a_addrlen
, afd
->a_af
);
855 if (hp
&& hp
->h_name
&& hp
->h_name
[0] && hp
->h_addr_list
[0]) {
856 GET_AI(cur
, afd
, hp
->h_addr_list
[0]);
857 GET_PORT(cur
, servname
);
858 GET_CANONNAME(cur
, hp
->h_name
);
860 GET_AI(cur
, afd
, numaddr
);
861 GET_PORT(cur
, servname
);
864 #ifdef USE_GETIPNODEBY
873 #ifdef USE_GETIPNODEBY
883 get_canonname(pai
, ai
, str
)
884 const struct addrinfo
*pai
;
888 if ((pai
->ai_flags
& AI_CANONNAME
) != 0) {
889 ai
->ai_canonname
= (char *)malloc(strlen(str
) + 1);
890 if (ai
->ai_canonname
== NULL
)
892 strcpy(ai
->ai_canonname
, str
);
897 static struct addrinfo
*
898 get_ai(pai
, afd
, addr
)
899 const struct addrinfo
*pai
;
900 const struct afd
*afd
;
906 ai
= (struct addrinfo
*)malloc(sizeof(struct addrinfo
)
911 memcpy(ai
, pai
, sizeof(struct addrinfo
));
912 ai
->ai_addr
= (struct sockaddr
*)(ai
+ 1);
913 memset(ai
->ai_addr
, 0, afd
->a_socklen
);
914 #ifdef HAVE_SOCKADDR_SA_LEN
915 ai
->ai_addr
->sa_len
= afd
->a_socklen
;
917 ai
->ai_addrlen
= afd
->a_socklen
;
918 ai
->ai_addr
->sa_family
= ai
->ai_family
= afd
->a_af
;
919 p
= (char *)(ai
->ai_addr
);
920 memcpy(p
+ afd
->a_off
, addr
, afd
->a_addrlen
);
925 get_portmatch(ai
, servname
)
926 const struct addrinfo
*ai
;
927 const char *servname
;
929 /* get_port does not touch first argument. when matchonly == 1. */
930 return get_port((struct addrinfo
*)ai
, servname
, 1);
934 get_port(ai
, servname
, matchonly
)
936 const char *servname
;
944 if (servname
== NULL
)
946 if (ai
->ai_family
!= AF_INET
&& ai
->ai_family
!= AF_INET6
)
949 switch (ai
->ai_socktype
) {
963 if (str_isnumber(servname
)) {
966 port
= htons(atoi(servname
));
967 if (port
< 0 || port
> 65535)
970 switch (ai
->ai_socktype
) {
982 if ((sp
= getservbyname(servname
, proto
)) == NULL
)
988 switch (ai
->ai_family
) {
990 ((struct sockaddr_in
*)ai
->ai_addr
)->sin_port
= port
;
994 ((struct sockaddr_in6
*)ai
->ai_addr
)->sin6_port
= port
;
1003 static const struct afd
*
1007 const struct afd
*afd
;
1009 if (af
== PF_UNSPEC
)
1011 for (afd
= afdl
; afd
->a_af
; afd
++) {
1012 if (afd
->a_af
== af
)