1 /* $KAME: name6.c,v 1.25 2000/06/26 16:44:40 itojun Exp $ */
4 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * ++Copyright++ 1985, 1988, 1993
34 * Copyright (c) 1985, 1988, 1993
35 * The Regents of the University of California. All rights reserved.
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution.
45 * 3. All advertising materials mentioning features or use of this software
46 * must display the following acknowledgement:
47 * This product includes software developed by the University of
48 * California, Berkeley and its contributors.
49 * 4. Neither the name of the University nor the names of its contributors
50 * may be used to endorse or promote products derived from this software
51 * without specific prior written permission.
53 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
54 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
65 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
67 * Permission to use, copy, modify, and distribute this software for any
68 * purpose with or without fee is hereby granted, provided that the above
69 * copyright notice and this permission notice appear in all copies, and that
70 * the name of Digital Equipment Corporation not be used in advertising or
71 * publicity pertaining to distribution of the document or software without
72 * specific, written prior permission.
74 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
75 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
76 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
77 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
78 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
79 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
80 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
85 * $FreeBSD: src/lib/libc/net/name6.c,v 1.62 2007/07/31 16:09:41 bushman Exp $
89 * Atsushi Onoe <onoe@sm.sony.co.jp>
92 #include "namespace.h"
93 #include <sys/param.h>
94 #include <sys/socket.h>
96 #include <sys/queue.h>
97 #include <netinet/in.h>
100 #include <net/if_var.h>
101 #include <sys/sysctl.h>
102 #include <sys/ioctl.h>
103 #include <netinet6/in6_var.h> /* XXX */
106 #include <arpa/inet.h>
107 #include <arpa/nameser.h>
116 #include <nsswitch.h>
118 #include "un-namespace.h"
119 #include "netdb_private.h"
120 #include "res_private.h"
123 #define MAXALIASES 10
129 #define MAXDNAME 1025
133 #define ADDRLEN(af) ((af) == AF_INET6 ? sizeof(struct in6_addr) : \
134 sizeof(struct in_addr))
136 #define ADDRLEN(af) sizeof(struct in_addr)
139 #define MAPADDR(ab, ina) \
141 memcpy(&(ab)->map_inaddr, ina, sizeof(struct in_addr)); \
142 memset((ab)->map_zero, 0, sizeof((ab)->map_zero)); \
143 memset((ab)->map_one, 0xff, sizeof((ab)->map_one)); \
145 #define MAPADDRENABLED(flags) \
146 (((flags) & AI_V4MAPPED) || \
147 (((flags) & AI_V4MAPPED_CFG)))
150 struct in_addr in_addr
;
152 struct in6_addr in6_addr
;
157 struct in_addr mau_inaddr
;
159 #define map_zero map_addr_un.mau_zero
160 #define map_one map_addr_un.mau_one
161 #define map_inaddr map_addr_un.mau_inaddr
165 TAILQ_ENTRY(policyqueue
) pc_entry
;
167 struct in6_addrpolicy pc_policy
;
170 TAILQ_HEAD(policyhead
, policyqueue
);
172 #define AIO_SRCFLAG_DEPRECATED 0x1
176 struct sockaddr_storage aiou_ss
;
177 struct sockaddr aiou_sa
;
179 #define aio_srcsa aio_src_un.aiou_sa
180 u_int32_t aio_srcflag
;
183 struct policyqueue
*aio_srcpolicy
;
184 struct policyqueue
*aio_dstpolicy
;
186 struct sockaddr_storage aiou_ss
;
187 struct sockaddr aiou_sa
;
189 #define aio_sa aio_un.aiou_sa
194 static struct hostent
*_hpcopy(struct hostent
*, int *);
195 static struct hostent
*_hpaddr(int, const char *, void *, int *);
197 static struct hostent
*_hpmerge(struct hostent
*, struct hostent
*, int *);
198 static struct hostent
*_hpmapv6(struct hostent
*, int *);
200 static struct hostent
*_hpsort(struct hostent
*, res_state
);
202 static struct hostent
*_hpreorder(struct hostent
*);
203 static int get_addrselectpolicy(struct policyhead
*);
204 static void free_addrselectpolicy(struct policyhead
*);
205 static struct policyqueue
*match_addrselectpolicy(struct sockaddr
*,
206 struct policyhead
*);
207 static void set_source(struct hp_order
*, struct policyhead
*);
208 static int matchlen(struct sockaddr
*, struct sockaddr
*);
209 static int comp_dst(const void *, const void *);
210 static int gai_addr2scopetype(struct sockaddr
*);
213 * Functions defined in RFC2553
214 * getipnodebyname, getipnodebyaddr, freehostent
218 getipnodebyname(const char *name
, int af
, int flags
, int *errp
)
221 union inx_addr addrbuf
;
236 if (flags
& AI_ADDRCONFIG
) {
239 if ((s
= _socket(af
, SOCK_DGRAM
, 0)) < 0)
243 * Note that implementation dependent test for address
244 * configuration should be done everytime called
245 * (or apropriate interval),
246 * because addresses will be dynamically assigned or deleted.
252 /* special case for literal address */
253 if (inet_pton(AF_INET6
, name
, &addrbuf
) == 1) {
254 if (af
!= AF_INET6
) {
255 *errp
= HOST_NOT_FOUND
;
258 return _hpaddr(af
, name
, &addrbuf
, errp
);
261 if (inet_aton(name
, (struct in_addr
*)&addrbuf
) == 1) {
263 if (MAPADDRENABLED(flags
)) {
264 MAPADDR(&addrbuf
, &addrbuf
.in_addr
);
266 *errp
= HOST_NOT_FOUND
;
270 return _hpaddr(af
, name
, &addrbuf
, errp
);
274 statp
= __res_state();
275 if ((statp
->options
& RES_INIT
) == 0) {
276 if (res_ninit(statp
) < 0) {
277 *errp
= NETDB_INTERNAL
;
282 options
= statp
->options
;
283 statp
->options
&= ~RES_USE_INET6
;
285 hp
= gethostbyname2(name
, af
);
286 hp
= _hpcopy(hp
, errp
);
289 if (af
== AF_INET6
&& ((flags
& AI_ALL
) || hp
== NULL
) &&
290 MAPADDRENABLED(flags
)) {
291 struct hostent
*hp2
= gethostbyname2(name
, AF_INET
);
294 *errp
= statp
->res_h_errno
;
296 hp
= _hpmapv6(hp2
, errp
);
298 if (hp2
&& strcmp(hp
->h_name
, hp2
->h_name
) == 0) {
299 struct hostent
*hpb
= hp
;
300 hp
= _hpmerge(hpb
, hp2
, errp
);
308 *errp
= statp
->res_h_errno
;
310 statp
->options
= options
;
311 return _hpreorder(_hpsort(hp
, statp
));
315 getipnodebyaddr(const void *src
, size_t len
, int af
, int *errp
)
322 struct in6_addr addrbuf
;
324 struct in_addr addrbuf
;
329 if (len
!= sizeof(struct in_addr
)) {
333 if ((long)src
& ~(sizeof(struct in_addr
) - 1)) {
334 memcpy(&addrbuf
, src
, len
);
337 if (((struct in_addr
*)src
)->s_addr
== 0)
342 if (len
!= sizeof(struct in6_addr
)) {
346 if ((long)src
& ~(sizeof(struct in6_addr
) / 2 - 1)) { /*XXX*/
347 memcpy(&addrbuf
, src
, len
);
350 if (IN6_IS_ADDR_UNSPECIFIED((struct in6_addr
*)src
))
352 if (IN6_IS_ADDR_V4MAPPED((struct in6_addr
*)src
)
353 || IN6_IS_ADDR_V4COMPAT((struct in6_addr
*)src
)) {
355 (sizeof(struct in6_addr
) - sizeof(struct in_addr
));
357 len
= sizeof(struct in_addr
);
366 statp
= __res_state();
367 if ((statp
->options
& RES_INIT
) == 0) {
368 if (res_ninit(statp
) < 0) {
369 RES_SET_H_ERRNO(statp
, NETDB_INTERNAL
);
374 options
= statp
->options
;
375 statp
->options
&= ~RES_USE_INET6
;
377 hp
= gethostbyaddr(src
, len
, af
);
379 *errp
= statp
->res_h_errno
;
381 statp
->options
= options
;
382 return (_hpcopy(hp
, errp
));
386 freehostent(struct hostent
*ptr
)
392 * Private utility functions
396 * _hpcopy: allocate and copy hostent structure
398 static struct hostent
*
399 _hpcopy(struct hostent
*hp
, int *errp
)
404 int nalias
= 0, naddr
= 0;
411 /* count size to be allocated */
412 size
= sizeof(struct hostent
);
413 if (hp
->h_name
!= NULL
)
414 size
+= strlen(hp
->h_name
) + 1;
415 if ((pp
= hp
->h_aliases
) != NULL
) {
416 for (i
= 0; *pp
!= NULL
; i
++, pp
++) {
418 size
+= strlen(*pp
) + 1;
423 /* adjust alignment */
426 size
+= sizeof(char *) * (nalias
+ 1);
427 addrsize
= ALIGN(hp
->h_length
);
428 if ((pp
= hp
->h_addr_list
) != NULL
) {
429 while (*pp
++ != NULL
)
432 size
+= addrsize
* naddr
;
433 size
+= sizeof(char *) * (naddr
+ 1);
436 if ((nhp
= (struct hostent
*)malloc(size
)) == NULL
) {
440 cp
= (char *)&nhp
[1];
441 if (hp
->h_name
!= NULL
) {
443 strcpy(cp
, hp
->h_name
);
444 cp
+= strlen(cp
) + 1;
447 nhp
->h_aliases
= (char **)((char *)nhp
+ al_off
);
448 if ((pp
= hp
->h_aliases
) != NULL
) {
449 for (i
= 0; *pp
!= NULL
; pp
++) {
451 nhp
->h_aliases
[i
++] = cp
;
453 cp
+= strlen(cp
) + 1;
457 nhp
->h_aliases
[nalias
] = NULL
;
458 cp
= (char *)&nhp
->h_aliases
[nalias
+ 1];
459 nhp
->h_addrtype
= hp
->h_addrtype
;
460 nhp
->h_length
= hp
->h_length
;
461 nhp
->h_addr_list
= (char **)cp
;
462 if ((pp
= hp
->h_addr_list
) != NULL
) {
463 cp
= (char *)&nhp
->h_addr_list
[naddr
+ 1];
464 for (i
= 0; *pp
!= NULL
; pp
++) {
465 nhp
->h_addr_list
[i
++] = cp
;
466 memcpy(cp
, *pp
, hp
->h_length
);
470 nhp
->h_addr_list
[naddr
] = NULL
;
475 * _hpaddr: construct hostent structure with one address
477 static struct hostent
*
478 _hpaddr(int af
, const char *name
, void *addr
, int *errp
)
480 struct hostent
*hp
, hpbuf
;
484 hp
->h_name
= (char *)name
;
485 hp
->h_aliases
= NULL
;
487 hp
->h_length
= ADDRLEN(af
);
488 hp
->h_addr_list
= addrs
;
489 addrs
[0] = (char *)addr
;
491 return (_hpcopy(hp
, errp
));
496 * _hpmerge: merge 2 hostent structure, arguments will be freed
498 static struct hostent
*
499 _hpmerge(struct hostent
*hp1
, struct hostent
*hp2
, int *errp
)
504 struct hostent
*hp
, hpbuf
;
505 char *aliases
[MAXALIASES
+ 1], *addrs
[MAXADDRS
+ 1];
506 union inx_addr addrbuf
[MAXADDRS
];
509 return _hpcopy(hp2
, errp
);
511 return _hpcopy(hp1
, errp
);
513 #define HP(i) (i == 1 ? hp1 : hp2)
515 hp
->h_name
= (hp1
->h_name
!= NULL
? hp1
->h_name
: hp2
->h_name
);
516 hp
->h_aliases
= aliases
;
518 for (i
= 1; i
<= 2; i
++) {
519 if ((pp
= HP(i
)->h_aliases
) == NULL
)
521 for (; nalias
< MAXALIASES
&& *pp
!= NULL
; pp
++) {
522 /* check duplicates */
523 for (j
= 0; j
< nalias
; j
++)
524 if (strcasecmp(*pp
, aliases
[j
]) == 0)
527 aliases
[nalias
++] = *pp
;
530 aliases
[nalias
] = NULL
;
531 if (hp1
->h_length
!= hp2
->h_length
) {
532 hp
->h_addrtype
= AF_INET6
;
533 hp
->h_length
= sizeof(struct in6_addr
);
535 hp
->h_addrtype
= hp1
->h_addrtype
;
536 hp
->h_length
= hp1
->h_length
;
539 hp
->h_addr_list
= addrs
;
541 for (i
= 1; i
<= 2; i
++) {
542 if ((pp
= HP(i
)->h_addr_list
) == NULL
)
544 if (HP(i
)->h_length
== hp
->h_length
) {
545 while (naddr
< MAXADDRS
&& *pp
!= NULL
)
546 addrs
[naddr
++] = *pp
++;
548 /* copy IPv4 addr as mapped IPv6 addr */
549 while (naddr
< MAXADDRS
&& *pp
!= NULL
) {
550 MAPADDR(&addrbuf
[naddr
], *pp
++);
551 addrs
[naddr
] = (char *)&addrbuf
[naddr
];
557 return (_hpcopy(hp
, errp
));
562 * _hpmapv6: convert IPv4 hostent into IPv4-mapped IPv6 addresses
565 static struct hostent
*
566 _hpmapv6(struct hostent
*hp
, int *errp
)
572 if (hp
->h_addrtype
== AF_INET6
)
573 return _hpcopy(hp
, errp
);
575 memset(&hp6
, 0, sizeof(struct hostent
));
576 hp6
.h_addrtype
= AF_INET6
;
577 hp6
.h_length
= sizeof(struct in6_addr
);
578 return _hpmerge(&hp6
, hp
, errp
);
583 * _hpsort: sort address by sortlist
585 static struct hostent
*
586 _hpsort(struct hostent
*hp
, res_state statp
)
589 u_char
*ap
, *sp
, *mp
, **pp
;
591 char order
[MAXADDRS
];
592 int nsort
= statp
->nsort
;
594 if (hp
== NULL
|| hp
->h_addr_list
[1] == NULL
|| nsort
== 0)
596 for (i
= 0; (ap
= (u_char
*)hp
->h_addr_list
[i
]); i
++) {
597 for (j
= 0; j
< nsort
; j
++) {
599 if (statp
->_u
._ext
.ext
->sort_list
[j
].af
!=
602 sp
= (u_char
*)&statp
->_u
._ext
.ext
->sort_list
[j
].addr
;
603 mp
= (u_char
*)&statp
->_u
._ext
.ext
->sort_list
[j
].mask
;
605 sp
= (u_char
*)&statp
->sort_list
[j
].addr
;
606 mp
= (u_char
*)&statp
->sort_list
[j
].mask
;
608 for (n
= 0; n
< hp
->h_length
; n
++) {
609 if ((ap
[n
] & mp
[n
]) != sp
[n
])
612 if (n
== hp
->h_length
)
618 pp
= (u_char
**)hp
->h_addr_list
;
619 for (i
= 0; i
< n
- 1; i
++) {
620 for (j
= i
+ 1; j
< n
; j
++) {
621 if (order
[i
] > order
[j
]) {
635 * _hpreorder: sort address by default address selection
637 static struct hostent
*
638 _hpreorder(struct hostent
*hp
)
640 struct hp_order
*aio
;
644 struct policyhead policyhead
;
649 switch (hp
->h_addrtype
) {
656 free_addrselectpolicy(&policyhead
);
660 /* count the number of addrinfo elements for sorting. */
661 for (n
= 0; hp
->h_addr_list
[n
] != NULL
; n
++)
665 * If the number is small enough, we can skip the reordering process.
670 /* allocate a temporary array for sort and initialization of it. */
671 if ((aio
= malloc(sizeof(*aio
) * n
)) == NULL
)
672 return hp
; /* give up reordering */
673 memset(aio
, 0, sizeof(*aio
) * n
);
675 /* retrieve address selection policy from the kernel */
676 TAILQ_INIT(&policyhead
);
677 if (!get_addrselectpolicy(&policyhead
)) {
678 /* no policy is installed into kernel, we don't sort. */
683 for (i
= 0; i
< n
; i
++) {
684 ap
= hp
->h_addr_list
[i
];
685 aio
[i
].aio_h_addr
= ap
;
687 switch (hp
->h_addrtype
) {
689 sa
->sa_family
= AF_INET
;
690 sa
->sa_len
= sizeof(struct sockaddr_in
);
691 memcpy(&((struct sockaddr_in
*)sa
)->sin_addr
, ap
,
692 sizeof(struct in_addr
));
696 if (IN6_IS_ADDR_V4MAPPED((struct in6_addr
*)ap
)) {
697 sa
->sa_family
= AF_INET
;
698 sa
->sa_len
= sizeof(struct sockaddr_in
);
699 memcpy(&((struct sockaddr_in
*)sa
)->sin_addr
,
700 &ap
[12], sizeof(struct in_addr
));
702 sa
->sa_family
= AF_INET6
;
703 sa
->sa_len
= sizeof(struct sockaddr_in6
);
704 memcpy(&((struct sockaddr_in6
*)sa
)->sin6_addr
,
705 ap
, sizeof(struct in6_addr
));
710 aio
[i
].aio_dstscope
= gai_addr2scopetype(sa
);
711 aio
[i
].aio_dstpolicy
= match_addrselectpolicy(sa
, &policyhead
);
712 set_source(&aio
[i
], &policyhead
);
715 /* perform sorting. */
716 qsort(aio
, n
, sizeof(*aio
), comp_dst
);
718 /* reorder the h_addr_list. */
719 for (i
= 0; i
< n
; i
++)
720 hp
->h_addr_list
[i
] = aio
[i
].aio_h_addr
;
722 /* cleanup and return */
724 free_addrselectpolicy(&policyhead
);
729 get_addrselectpolicy(struct policyhead
*head
)
732 int mib
[] = { CTL_NET
, PF_INET6
, IPPROTO_IPV6
, IPV6CTL_ADDRCTLPOLICY
};
735 struct in6_addrpolicy
*pol
, *ep
;
737 if (sysctl(mib
, sizeof(mib
) / sizeof(mib
[0]), NULL
, &l
, NULL
, 0) < 0)
739 if ((buf
= malloc(l
)) == NULL
)
741 if (sysctl(mib
, sizeof(mib
) / sizeof(mib
[0]), buf
, &l
, NULL
, 0) < 0) {
746 ep
= (struct in6_addrpolicy
*)(buf
+ l
);
747 for (pol
= (struct in6_addrpolicy
*)buf
; pol
+ 1 <= ep
; pol
++) {
748 struct policyqueue
*new;
750 if ((new = malloc(sizeof(*new))) == NULL
) {
751 free_addrselectpolicy(head
); /* make the list empty */
754 new->pc_policy
= *pol
;
755 TAILQ_INSERT_TAIL(head
, new, pc_entry
);
766 free_addrselectpolicy(struct policyhead
*head
)
768 struct policyqueue
*ent
, *nent
;
770 for (ent
= TAILQ_FIRST(head
); ent
; ent
= nent
) {
771 nent
= TAILQ_NEXT(ent
, pc_entry
);
772 TAILQ_REMOVE(head
, ent
, pc_entry
);
777 static struct policyqueue
*
778 match_addrselectpolicy(struct sockaddr
*addr
, struct policyhead
*head
)
781 struct policyqueue
*ent
, *bestent
= NULL
;
782 struct in6_addrpolicy
*pol
;
783 int matchlen
, bestmatchlen
= -1;
784 u_char
*mp
, *ep
, *k
, *p
, m
;
785 struct sockaddr_in6 key
;
787 switch(addr
->sa_family
) {
789 key
= *(struct sockaddr_in6
*)addr
;
792 /* convert the address into IPv4-mapped IPv6 address. */
793 memset(&key
, 0, sizeof(key
));
794 key
.sin6_family
= AF_INET6
;
795 key
.sin6_len
= sizeof(key
);
796 key
.sin6_addr
.s6_addr
[10] = 0xff;
797 key
.sin6_addr
.s6_addr
[11] = 0xff;
798 memcpy(&key
.sin6_addr
.s6_addr
[12],
799 &((struct sockaddr_in
*)addr
)->sin_addr
, 4);
805 for (ent
= TAILQ_FIRST(head
); ent
; ent
= TAILQ_NEXT(ent
, pc_entry
)) {
806 pol
= &ent
->pc_policy
;
809 mp
= (u_char
*)&pol
->addrmask
.sin6_addr
;
810 ep
= mp
+ 16; /* XXX: scope field? */
811 k
= (u_char
*)&key
.sin6_addr
;
812 p
= (u_char
*)&pol
->addr
.sin6_addr
;
813 for (; mp
< ep
&& *mp
; mp
++, k
++, p
++) {
816 goto next
; /* not match */
817 if (m
== 0xff) /* short cut for a typical case */
827 /* matched. check if this is better than the current best. */
828 if (matchlen
> bestmatchlen
) {
830 bestmatchlen
= matchlen
;
845 set_source(struct hp_order
*aio
, struct policyhead
*ph
)
847 struct sockaddr_storage ss
= aio
->aio_un
.aiou_ss
;
851 /* set unspec ("no source is available"), just in case */
852 aio
->aio_srcsa
.sa_family
= AF_UNSPEC
;
853 aio
->aio_srcscope
= -1;
855 switch(ss
.ss_family
) {
857 ((struct sockaddr_in
*)&ss
)->sin_port
= htons(1);
861 ((struct sockaddr_in6
*)&ss
)->sin6_port
= htons(1);
864 default: /* ignore unsupported AFs explicitly */
868 /* open a socket to get the source address for the given dst */
869 if ((s
= _socket(ss
.ss_family
, SOCK_DGRAM
, IPPROTO_UDP
)) < 0)
870 return; /* give up */
871 if (_connect(s
, (struct sockaddr
*)&ss
, ss
.ss_len
) < 0)
874 if (_getsockname(s
, &aio
->aio_srcsa
, &srclen
) < 0) {
875 aio
->aio_srcsa
.sa_family
= AF_UNSPEC
;
878 aio
->aio_srcscope
= gai_addr2scopetype(&aio
->aio_srcsa
);
879 aio
->aio_srcpolicy
= match_addrselectpolicy(&aio
->aio_srcsa
, ph
);
880 aio
->aio_matchlen
= matchlen(&aio
->aio_srcsa
, (struct sockaddr
*)&ss
);
882 if (ss
.ss_family
== AF_INET6
) {
883 struct in6_ifreq ifr6
;
886 /* XXX: interface name should not be hardcoded */
887 strncpy(ifr6
.ifr_name
, "lo0", sizeof(ifr6
.ifr_name
));
888 memset(&ifr6
, 0, sizeof(ifr6
));
889 memcpy(&ifr6
.ifr_addr
, &ss
, ss
.ss_len
);
890 if (_ioctl(s
, SIOCGIFAFLAG_IN6
, &ifr6
) == 0) {
891 flags6
= ifr6
.ifr_ifru
.ifru_flags6
;
892 if ((flags6
& IN6_IFF_DEPRECATED
))
893 aio
->aio_srcflag
|= AIO_SRCFLAG_DEPRECATED
;
904 matchlen(struct sockaddr
*src
, struct sockaddr
*dst
)
911 switch (src
->sa_family
) {
914 s
= (u_char
*)&((struct sockaddr_in6
*)src
)->sin6_addr
;
915 d
= (u_char
*)&((struct sockaddr_in6
*)dst
)->sin6_addr
;
916 addrlen
= sizeof(struct in6_addr
);
921 s
= (u_char
*)&((struct sockaddr_in
*)src
)->sin_addr
;
922 d
= (u_char
*)&((struct sockaddr_in
*)dst
)->sin_addr
;
923 addrlen
= sizeof(struct in_addr
);
931 if ((r
= (*d
++ ^ *s
++)) != 0) {
932 while (r
< addrlen
* 8) {
943 comp_dst(const void *arg1
, const void *arg2
)
945 const struct hp_order
*dst1
= arg1
, *dst2
= arg2
;
948 * Rule 1: Avoid unusable destinations.
949 * XXX: we currently do not consider if an appropriate route exists.
951 if (dst1
->aio_srcsa
.sa_family
!= AF_UNSPEC
&&
952 dst2
->aio_srcsa
.sa_family
== AF_UNSPEC
) {
955 if (dst1
->aio_srcsa
.sa_family
== AF_UNSPEC
&&
956 dst2
->aio_srcsa
.sa_family
!= AF_UNSPEC
) {
960 /* Rule 2: Prefer matching scope. */
961 if (dst1
->aio_dstscope
== dst1
->aio_srcscope
&&
962 dst2
->aio_dstscope
!= dst2
->aio_srcscope
) {
965 if (dst1
->aio_dstscope
!= dst1
->aio_srcscope
&&
966 dst2
->aio_dstscope
== dst2
->aio_srcscope
) {
970 /* Rule 3: Avoid deprecated addresses. */
971 if (dst1
->aio_srcsa
.sa_family
!= AF_UNSPEC
&&
972 dst2
->aio_srcsa
.sa_family
!= AF_UNSPEC
) {
973 if (!(dst1
->aio_srcflag
& AIO_SRCFLAG_DEPRECATED
) &&
974 (dst2
->aio_srcflag
& AIO_SRCFLAG_DEPRECATED
)) {
977 if ((dst1
->aio_srcflag
& AIO_SRCFLAG_DEPRECATED
) &&
978 !(dst2
->aio_srcflag
& AIO_SRCFLAG_DEPRECATED
)) {
983 /* Rule 4: Prefer home addresses. */
984 /* XXX: not implemented yet */
986 /* Rule 5: Prefer matching label. */
988 if (dst1
->aio_srcpolicy
&& dst1
->aio_dstpolicy
&&
989 dst1
->aio_srcpolicy
->pc_policy
.label
==
990 dst1
->aio_dstpolicy
->pc_policy
.label
&&
991 (dst2
->aio_srcpolicy
== NULL
|| dst2
->aio_dstpolicy
== NULL
||
992 dst2
->aio_srcpolicy
->pc_policy
.label
!=
993 dst2
->aio_dstpolicy
->pc_policy
.label
)) {
996 if (dst2
->aio_srcpolicy
&& dst2
->aio_dstpolicy
&&
997 dst2
->aio_srcpolicy
->pc_policy
.label
==
998 dst2
->aio_dstpolicy
->pc_policy
.label
&&
999 (dst1
->aio_srcpolicy
== NULL
|| dst1
->aio_dstpolicy
== NULL
||
1000 dst1
->aio_srcpolicy
->pc_policy
.label
!=
1001 dst1
->aio_dstpolicy
->pc_policy
.label
)) {
1006 /* Rule 6: Prefer higher precedence. */
1008 if (dst1
->aio_dstpolicy
&&
1009 (dst2
->aio_dstpolicy
== NULL
||
1010 dst1
->aio_dstpolicy
->pc_policy
.preced
>
1011 dst2
->aio_dstpolicy
->pc_policy
.preced
)) {
1014 if (dst2
->aio_dstpolicy
&&
1015 (dst1
->aio_dstpolicy
== NULL
||
1016 dst2
->aio_dstpolicy
->pc_policy
.preced
>
1017 dst1
->aio_dstpolicy
->pc_policy
.preced
)) {
1022 /* Rule 7: Prefer native transport. */
1023 /* XXX: not implemented yet */
1025 /* Rule 8: Prefer smaller scope. */
1026 if (dst1
->aio_dstscope
>= 0 &&
1027 dst1
->aio_dstscope
< dst2
->aio_dstscope
) {
1030 if (dst2
->aio_dstscope
>= 0 &&
1031 dst2
->aio_dstscope
< dst1
->aio_dstscope
) {
1036 * Rule 9: Use longest matching prefix.
1037 * We compare the match length in a same AF only.
1039 if (dst1
->aio_sa
.sa_family
== dst2
->aio_sa
.sa_family
) {
1040 if (dst1
->aio_matchlen
> dst2
->aio_matchlen
) {
1043 if (dst1
->aio_matchlen
< dst2
->aio_matchlen
) {
1048 /* Rule 10: Otherwise, leave the order unchanged. */
1053 * Copy from scope.c.
1054 * XXX: we should standardize the functions and link them as standard
1058 gai_addr2scopetype(struct sockaddr
*sa
)
1061 struct sockaddr_in6
*sa6
;
1063 struct sockaddr_in
*sa4
;
1065 switch(sa
->sa_family
) {
1068 sa6
= (struct sockaddr_in6
*)sa
;
1069 if (IN6_IS_ADDR_MULTICAST(&sa6
->sin6_addr
)) {
1070 /* just use the scope field of the multicast address */
1071 return(sa6
->sin6_addr
.s6_addr
[2] & 0x0f);
1074 * Unicast addresses: map scope type to corresponding scope
1075 * value defined for multcast addresses.
1076 * XXX: hardcoded scope type values are bad...
1078 if (IN6_IS_ADDR_LOOPBACK(&sa6
->sin6_addr
))
1079 return(1); /* node local scope */
1080 if (IN6_IS_ADDR_LINKLOCAL(&sa6
->sin6_addr
))
1081 return(2); /* link-local scope */
1082 if (IN6_IS_ADDR_SITELOCAL(&sa6
->sin6_addr
))
1083 return(5); /* site-local scope */
1084 return(14); /* global scope */
1089 * IPv4 pseudo scoping according to RFC 3484.
1091 sa4
= (struct sockaddr_in
*)sa
;
1092 /* IPv4 autoconfiguration addresses have link-local scope. */
1093 if (((u_char
*)&sa4
->sin_addr
)[0] == 169 &&
1094 ((u_char
*)&sa4
->sin_addr
)[1] == 254)
1096 /* Private addresses have site-local scope. */
1097 if (((u_char
*)&sa4
->sin_addr
)[0] == 10 ||
1098 (((u_char
*)&sa4
->sin_addr
)[0] == 172 &&
1099 (((u_char
*)&sa4
->sin_addr
)[1] & 0xf0) == 16) ||
1100 (((u_char
*)&sa4
->sin_addr
)[0] == 192 &&
1101 ((u_char
*)&sa4
->sin_addr
)[1] == 168))
1102 return(14); /* XXX: It should be 5 unless NAT */
1103 /* Loopback addresses have link-local scope. */
1104 if (((u_char
*)&sa4
->sin_addr
)[0] == 127)
1109 errno
= EAFNOSUPPORT
; /* is this a good error? */