2 * Copyright (C) 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
35 inet6_uvif2scopeid(struct sockaddr_in6 *sa, struct uvif *v)
37 if (IN6_IS_ADDR_MULTICAST(&sa->sin6_addr)) {
38 if (IN6_IS_ADDR_MC_LINKLOCAL(&sa->sin6_addr))
39 return(v->uv_ifindex);
40 if (IN6_IS_ADDR_MC_SITELOCAL(&sa->sin6_addr))
44 if (IN6_IS_ADDR_LINKLOCAL(&sa->sin6_addr))
45 return(v->uv_ifindex);
47 if (IN6_IS_ADDR_SITELOCAL(&sa->sin6_addr))
55 inet6_localif_address(struct sockaddr_in6 *sa, struct uvif *v)
59 for (pa = v->uv_addrs; pa; pa = pa->pa_next)
60 if (inet6_equal(sa, &pa->pa_addr))
67 inet6_valid_host(struct sockaddr_in6 *addr)
69 if (IN6_IS_ADDR_MULTICAST(&addr->sin6_addr))
76 inet6_equal(struct sockaddr_in6 *sa1, struct sockaddr_in6 *sa2)
78 if (sa1->sin6_scope_id == sa2->sin6_scope_id &&
79 IN6_ARE_ADDR_EQUAL(&sa1->sin6_addr, &sa2->sin6_addr))
86 inet6_lessthan(struct sockaddr_in6 *sa1, struct sockaddr_in6 *sa2)
88 u_int32_t s32_1, s32_2;
91 if (sa1->sin6_scope_id < sa2->sin6_scope_id)
93 if (sa1->sin6_scope_id == sa2->sin6_scope_id) {
94 for (i = 0; i < 4; i++) {
95 s32_1 = ntohl(*(u_int32_t *)&sa1->sin6_addr.s6_addr[i * 4]);
96 s32_2 = ntohl(*(u_int32_t *)&sa2->sin6_addr.s6_addr[i * 4]);
103 /* otherwide, continue to compare */
111 inet6_lessoreq(struct sockaddr_in6 *sa1, struct sockaddr_in6 *sa2)
113 u_int32_t s32_1, s32_2;
116 if (sa1->sin6_scope_id < sa2->sin6_scope_id)
118 if (sa1->sin6_scope_id == sa2->sin6_scope_id) {
119 for (i = 0; i < 4; i++) {
120 s32_1 = ntohl(*(u_int32_t *)&sa1->sin6_addr.s6_addr[i * 4]);
121 s32_2 = ntohl(*(u_int32_t *)&sa2->sin6_addr.s6_addr[i * 4]);
128 /* otherwide, continue to compare */
138 inet6_greaterthan(struct sockaddr_in6 *sa1, struct sockaddr_in6 *sa2)
140 u_int32_t s32_1, s32_2;
143 if (sa1->sin6_scope_id > sa2->sin6_scope_id)
145 if (sa1->sin6_scope_id == sa2->sin6_scope_id) {
146 for (i = 0; i < 4; i++) {
147 s32_1 = ntohl(*(u_int32_t *)&sa1->sin6_addr.s6_addr[i * 4]);
148 s32_2 = ntohl(*(u_int32_t *)&sa2->sin6_addr.s6_addr[i * 4]);
155 /* otherwide, continue to compare */
163 inet6_greateroreq(struct sockaddr_in6 *sa1, struct sockaddr_in6 *sa2)
165 u_int32_t s32_1, s32_2;
168 if (sa1->sin6_scope_id > sa2->sin6_scope_id)
170 if (sa1->sin6_scope_id == sa2->sin6_scope_id) {
171 for (i = 0; i < 4; i++) {
172 s32_1 = ntohl(*(u_int32_t *)&sa1->sin6_addr.s6_addr[i * 4]);
173 s32_2 = ntohl(*(u_int32_t *)&sa2->sin6_addr.s6_addr[i * 4]);
180 /* otherwide, continue to compare */
190 inet6_match_prefix(sa1, sa2, mask)
191 struct sockaddr_in6 *sa1, *sa2;
192 struct in6_addr *mask;
196 if (sa1->sin6_scope_id != sa2->sin6_scope_id)
199 for (i = 0; i < 16; i++) {
200 if ((sa1->sin6_addr.s6_addr[i] ^ sa2->sin6_addr.s6_addr[i]) &
209 inet6_fmt(struct in6_addr *addr)
211 static char ip6buf[8][INET6_ADDRSTRLEN];
212 static int ip6round = 0;
215 ip6round = (ip6round + 1) & 7;
216 cp = ip6buf[ip6round];
218 inet_ntop(AF_INET6, addr, cp, INET6_ADDRSTRLEN);
223 ifindex2str(int ifindex)
225 static char ifname[IFNAMSIZ];
227 return(if_indextoname(ifindex, ifname));
231 inet6_mask2plen(struct in6_addr *mask)
234 u_char *p = (u_char *)mask;
235 u_char *lim = p + 16;
237 for (masklen = 0; p < lim; p++) {
272 net6name(struct in6_addr *prefix, struct in6_addr *mask)
274 static char ip6buf[8][INET6_ADDRSTRLEN + 4]; /* length of addr/plen */
275 static int ip6round = 0;
278 ip6round = (ip6round + 1) & 7;
279 cp = ip6buf[ip6round];
281 inet_ntop(AF_INET6, prefix, cp, INET6_ADDRSTRLEN);
285 sprintf(cp, "%d", inet6_mask2plen(mask));
287 return(ip6buf[ip6round]);