xref: /freebsd/sys/netinet6/scope6.c (revision 33841545909f4a4ee94aa148b3a9cbcdc1abb02a)
1686cdd19SJun-ichiro itojun Hagino /*	$FreeBSD$	*/
233841545SHajimu UMEMOTO /*	$KAME: scope6.c,v 1.10 2000/07/24 13:29:31 itojun Exp $	*/
3686cdd19SJun-ichiro itojun Hagino 
4686cdd19SJun-ichiro itojun Hagino /*
5686cdd19SJun-ichiro itojun Hagino  * Copyright (C) 2000 WIDE Project.
6686cdd19SJun-ichiro itojun Hagino  * All rights reserved.
7686cdd19SJun-ichiro itojun Hagino  *
8686cdd19SJun-ichiro itojun Hagino  * Redistribution and use in source and binary forms, with or without
9686cdd19SJun-ichiro itojun Hagino  * modification, are permitted provided that the following conditions
10686cdd19SJun-ichiro itojun Hagino  * are met:
11686cdd19SJun-ichiro itojun Hagino  * 1. Redistributions of source code must retain the above copyright
12686cdd19SJun-ichiro itojun Hagino  *    notice, this list of conditions and the following disclaimer.
13686cdd19SJun-ichiro itojun Hagino  * 2. Redistributions in binary form must reproduce the above copyright
14686cdd19SJun-ichiro itojun Hagino  *    notice, this list of conditions and the following disclaimer in the
15686cdd19SJun-ichiro itojun Hagino  *    documentation and/or other materials provided with the distribution.
16686cdd19SJun-ichiro itojun Hagino  * 3. Neither the name of the project nor the names of its contributors
17686cdd19SJun-ichiro itojun Hagino  *    may be used to endorse or promote products derived from this software
18686cdd19SJun-ichiro itojun Hagino  *    without specific prior written permission.
19686cdd19SJun-ichiro itojun Hagino  *
20686cdd19SJun-ichiro itojun Hagino  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21686cdd19SJun-ichiro itojun Hagino  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22686cdd19SJun-ichiro itojun Hagino  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23686cdd19SJun-ichiro itojun Hagino  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24686cdd19SJun-ichiro itojun Hagino  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25686cdd19SJun-ichiro itojun Hagino  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26686cdd19SJun-ichiro itojun Hagino  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27686cdd19SJun-ichiro itojun Hagino  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28686cdd19SJun-ichiro itojun Hagino  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29686cdd19SJun-ichiro itojun Hagino  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30686cdd19SJun-ichiro itojun Hagino  * SUCH DAMAGE.
31686cdd19SJun-ichiro itojun Hagino  */
32686cdd19SJun-ichiro itojun Hagino 
33686cdd19SJun-ichiro itojun Hagino #include <sys/param.h>
34686cdd19SJun-ichiro itojun Hagino #include <sys/malloc.h>
35686cdd19SJun-ichiro itojun Hagino #include <sys/mbuf.h>
36686cdd19SJun-ichiro itojun Hagino #include <sys/socket.h>
37686cdd19SJun-ichiro itojun Hagino #include <sys/systm.h>
3833841545SHajimu UMEMOTO #include <sys/queue.h>
39686cdd19SJun-ichiro itojun Hagino 
40686cdd19SJun-ichiro itojun Hagino #include <net/route.h>
41686cdd19SJun-ichiro itojun Hagino #include <net/if.h>
42686cdd19SJun-ichiro itojun Hagino 
43686cdd19SJun-ichiro itojun Hagino #include <netinet/in.h>
44686cdd19SJun-ichiro itojun Hagino 
45686cdd19SJun-ichiro itojun Hagino #include <netinet6/in6_var.h>
46686cdd19SJun-ichiro itojun Hagino #include <netinet6/scope6_var.h>
47686cdd19SJun-ichiro itojun Hagino 
48686cdd19SJun-ichiro itojun Hagino struct scope6_id {
49686cdd19SJun-ichiro itojun Hagino 	/*
50686cdd19SJun-ichiro itojun Hagino 	 * 16 is correspondent to 4bit multicast scope field.
51686cdd19SJun-ichiro itojun Hagino 	 * i.e. from node-local to global with some reserved/unassigned types.
52686cdd19SJun-ichiro itojun Hagino 	 */
53686cdd19SJun-ichiro itojun Hagino 	u_int32_t s6id_list[16];
54686cdd19SJun-ichiro itojun Hagino };
55686cdd19SJun-ichiro itojun Hagino static size_t if_indexlim = 8;
56686cdd19SJun-ichiro itojun Hagino struct scope6_id *scope6_ids = NULL;
57686cdd19SJun-ichiro itojun Hagino 
58686cdd19SJun-ichiro itojun Hagino void
59686cdd19SJun-ichiro itojun Hagino scope6_ifattach(ifp)
60686cdd19SJun-ichiro itojun Hagino 	struct ifnet *ifp;
61686cdd19SJun-ichiro itojun Hagino {
62686cdd19SJun-ichiro itojun Hagino 	int s = splnet();
63686cdd19SJun-ichiro itojun Hagino 
64686cdd19SJun-ichiro itojun Hagino 	/*
65686cdd19SJun-ichiro itojun Hagino 	 * We have some arrays that should be indexed by if_index.
66686cdd19SJun-ichiro itojun Hagino 	 * since if_index will grow dynamically, they should grow too.
67686cdd19SJun-ichiro itojun Hagino 	 */
68686cdd19SJun-ichiro itojun Hagino 	if (scope6_ids == NULL || if_index >= if_indexlim) {
69686cdd19SJun-ichiro itojun Hagino 		size_t n;
70686cdd19SJun-ichiro itojun Hagino 		caddr_t q;
71686cdd19SJun-ichiro itojun Hagino 
72686cdd19SJun-ichiro itojun Hagino 		while (if_index >= if_indexlim)
73686cdd19SJun-ichiro itojun Hagino 			if_indexlim <<= 1;
74686cdd19SJun-ichiro itojun Hagino 
75686cdd19SJun-ichiro itojun Hagino 		/* grow scope index array */
76686cdd19SJun-ichiro itojun Hagino 		n = if_indexlim * sizeof(struct scope6_id);
77686cdd19SJun-ichiro itojun Hagino 		/* XXX: need new malloc type? */
78686cdd19SJun-ichiro itojun Hagino 		q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK);
79686cdd19SJun-ichiro itojun Hagino 		bzero(q, n);
80686cdd19SJun-ichiro itojun Hagino 		if (scope6_ids) {
81686cdd19SJun-ichiro itojun Hagino 			bcopy((caddr_t)scope6_ids, q, n/2);
82686cdd19SJun-ichiro itojun Hagino 			free((caddr_t)scope6_ids, M_IFADDR);
83686cdd19SJun-ichiro itojun Hagino 		}
84686cdd19SJun-ichiro itojun Hagino 		scope6_ids = (struct scope6_id *)q;
85686cdd19SJun-ichiro itojun Hagino 	}
86686cdd19SJun-ichiro itojun Hagino 
87686cdd19SJun-ichiro itojun Hagino #define SID scope6_ids[ifp->if_index]
88686cdd19SJun-ichiro itojun Hagino 
89686cdd19SJun-ichiro itojun Hagino 	/* don't initialize if called twice */
90686cdd19SJun-ichiro itojun Hagino 	if (SID.s6id_list[IPV6_ADDR_SCOPE_LINKLOCAL]) {
91686cdd19SJun-ichiro itojun Hagino 		splx(s);
92686cdd19SJun-ichiro itojun Hagino 		return;
93686cdd19SJun-ichiro itojun Hagino 	}
94686cdd19SJun-ichiro itojun Hagino 
95686cdd19SJun-ichiro itojun Hagino 	/*
96686cdd19SJun-ichiro itojun Hagino 	 * XXX: IPV6_ADDR_SCOPE_xxx macros are not standard.
97686cdd19SJun-ichiro itojun Hagino 	 * Should we rather hardcode here?
98686cdd19SJun-ichiro itojun Hagino 	 */
99686cdd19SJun-ichiro itojun Hagino 	SID.s6id_list[IPV6_ADDR_SCOPE_LINKLOCAL] = ifp->if_index;
100686cdd19SJun-ichiro itojun Hagino #ifdef MULTI_SCOPE
101686cdd19SJun-ichiro itojun Hagino 	/* by default, we don't care about scope boundary for these scopes. */
102686cdd19SJun-ichiro itojun Hagino 	SID.s6id_list[IPV6_ADDR_SCOPE_SITELOCAL] = 1;
103686cdd19SJun-ichiro itojun Hagino 	SID.s6id_list[IPV6_ADDR_SCOPE_ORGLOCAL] = 1;
104686cdd19SJun-ichiro itojun Hagino #endif
105686cdd19SJun-ichiro itojun Hagino #undef SID
106686cdd19SJun-ichiro itojun Hagino 
107686cdd19SJun-ichiro itojun Hagino 	splx(s);
108686cdd19SJun-ichiro itojun Hagino }
109686cdd19SJun-ichiro itojun Hagino 
110686cdd19SJun-ichiro itojun Hagino int
111686cdd19SJun-ichiro itojun Hagino scope6_set(ifp, idlist)
112686cdd19SJun-ichiro itojun Hagino 	struct ifnet *ifp;
113686cdd19SJun-ichiro itojun Hagino 	u_int32_t *idlist;
114686cdd19SJun-ichiro itojun Hagino {
115686cdd19SJun-ichiro itojun Hagino 	int i, s;
116686cdd19SJun-ichiro itojun Hagino 	int error = 0;
117686cdd19SJun-ichiro itojun Hagino 
118686cdd19SJun-ichiro itojun Hagino 	if (scope6_ids == NULL)	/* paranoid? */
119686cdd19SJun-ichiro itojun Hagino 		return(EINVAL);
120686cdd19SJun-ichiro itojun Hagino 
121686cdd19SJun-ichiro itojun Hagino 	/*
122686cdd19SJun-ichiro itojun Hagino 	 * XXX: We need more consistency checks of the relationship among
123686cdd19SJun-ichiro itojun Hagino 	 * scopes (e.g. an organization should be larger than a site).
124686cdd19SJun-ichiro itojun Hagino 	 */
125686cdd19SJun-ichiro itojun Hagino 
126686cdd19SJun-ichiro itojun Hagino 	/*
127686cdd19SJun-ichiro itojun Hagino 	 * TODO(XXX): after setting, we should reflect the changes to
128686cdd19SJun-ichiro itojun Hagino 	 * interface addresses, routing table entries, PCB entries...
129686cdd19SJun-ichiro itojun Hagino 	 */
130686cdd19SJun-ichiro itojun Hagino 
131686cdd19SJun-ichiro itojun Hagino 	s = splnet();
132686cdd19SJun-ichiro itojun Hagino 
133686cdd19SJun-ichiro itojun Hagino 	for (i = 0; i < 16; i++) {
134686cdd19SJun-ichiro itojun Hagino 		if (idlist[i] &&
135686cdd19SJun-ichiro itojun Hagino 		    idlist[i] != scope6_ids[ifp->if_index].s6id_list[i]) {
136686cdd19SJun-ichiro itojun Hagino 			if (i == IPV6_ADDR_SCOPE_LINKLOCAL &&
137686cdd19SJun-ichiro itojun Hagino 			    idlist[i] > if_index) {
138686cdd19SJun-ichiro itojun Hagino 				/*
139686cdd19SJun-ichiro itojun Hagino 				 * XXX: theoretically, there should be no
140686cdd19SJun-ichiro itojun Hagino 				 * relationship between link IDs and interface
141686cdd19SJun-ichiro itojun Hagino 				 * IDs, but we check the consistency for
142686cdd19SJun-ichiro itojun Hagino 				 * safety in later use.
143686cdd19SJun-ichiro itojun Hagino 				 */
144686cdd19SJun-ichiro itojun Hagino 				splx(s);
145686cdd19SJun-ichiro itojun Hagino 				return(EINVAL);
146686cdd19SJun-ichiro itojun Hagino 			}
147686cdd19SJun-ichiro itojun Hagino 
148686cdd19SJun-ichiro itojun Hagino 			/*
149686cdd19SJun-ichiro itojun Hagino 			 * XXX: we must need lots of work in this case,
150686cdd19SJun-ichiro itojun Hagino 			 * but we simply set the new value in this initial
151686cdd19SJun-ichiro itojun Hagino 			 * implementation.
152686cdd19SJun-ichiro itojun Hagino 			 */
153686cdd19SJun-ichiro itojun Hagino 			scope6_ids[ifp->if_index].s6id_list[i] = idlist[i];
154686cdd19SJun-ichiro itojun Hagino 		}
155686cdd19SJun-ichiro itojun Hagino 	}
156686cdd19SJun-ichiro itojun Hagino 	splx(s);
157686cdd19SJun-ichiro itojun Hagino 
158686cdd19SJun-ichiro itojun Hagino 	return(error);
159686cdd19SJun-ichiro itojun Hagino }
160686cdd19SJun-ichiro itojun Hagino 
161686cdd19SJun-ichiro itojun Hagino int
162686cdd19SJun-ichiro itojun Hagino scope6_get(ifp, idlist)
163686cdd19SJun-ichiro itojun Hagino 	struct ifnet *ifp;
164686cdd19SJun-ichiro itojun Hagino 	u_int32_t *idlist;
165686cdd19SJun-ichiro itojun Hagino {
166686cdd19SJun-ichiro itojun Hagino 	if (scope6_ids == NULL)	/* paranoid? */
167686cdd19SJun-ichiro itojun Hagino 		return(EINVAL);
168686cdd19SJun-ichiro itojun Hagino 
169686cdd19SJun-ichiro itojun Hagino 	bcopy(scope6_ids[ifp->if_index].s6id_list, idlist,
170686cdd19SJun-ichiro itojun Hagino 	      sizeof(scope6_ids[ifp->if_index].s6id_list));
171686cdd19SJun-ichiro itojun Hagino 
172686cdd19SJun-ichiro itojun Hagino 	return(0);
173686cdd19SJun-ichiro itojun Hagino }
174686cdd19SJun-ichiro itojun Hagino 
175686cdd19SJun-ichiro itojun Hagino 
176686cdd19SJun-ichiro itojun Hagino /*
177686cdd19SJun-ichiro itojun Hagino  * Get a scope of the address. Node-local, link-local, site-local or global.
178686cdd19SJun-ichiro itojun Hagino  */
179686cdd19SJun-ichiro itojun Hagino int
180686cdd19SJun-ichiro itojun Hagino in6_addrscope(addr)
181686cdd19SJun-ichiro itojun Hagino struct in6_addr *addr;
182686cdd19SJun-ichiro itojun Hagino {
183686cdd19SJun-ichiro itojun Hagino 	int scope;
184686cdd19SJun-ichiro itojun Hagino 
185686cdd19SJun-ichiro itojun Hagino 	if (addr->s6_addr8[0] == 0xfe) {
186686cdd19SJun-ichiro itojun Hagino 		scope = addr->s6_addr8[1] & 0xc0;
187686cdd19SJun-ichiro itojun Hagino 
188686cdd19SJun-ichiro itojun Hagino 		switch (scope) {
189686cdd19SJun-ichiro itojun Hagino 		case 0x80:
190686cdd19SJun-ichiro itojun Hagino 			return IPV6_ADDR_SCOPE_LINKLOCAL;
191686cdd19SJun-ichiro itojun Hagino 			break;
192686cdd19SJun-ichiro itojun Hagino 		case 0xc0:
193686cdd19SJun-ichiro itojun Hagino 			return IPV6_ADDR_SCOPE_SITELOCAL;
194686cdd19SJun-ichiro itojun Hagino 			break;
195686cdd19SJun-ichiro itojun Hagino 		default:
196686cdd19SJun-ichiro itojun Hagino 			return IPV6_ADDR_SCOPE_GLOBAL; /* just in case */
197686cdd19SJun-ichiro itojun Hagino 			break;
198686cdd19SJun-ichiro itojun Hagino 		}
199686cdd19SJun-ichiro itojun Hagino 	}
200686cdd19SJun-ichiro itojun Hagino 
201686cdd19SJun-ichiro itojun Hagino 
202686cdd19SJun-ichiro itojun Hagino 	if (addr->s6_addr8[0] == 0xff) {
203686cdd19SJun-ichiro itojun Hagino 		scope = addr->s6_addr8[1] & 0x0f;
204686cdd19SJun-ichiro itojun Hagino 
205686cdd19SJun-ichiro itojun Hagino 		/*
206686cdd19SJun-ichiro itojun Hagino 		 * due to other scope such as reserved,
207686cdd19SJun-ichiro itojun Hagino 		 * return scope doesn't work.
208686cdd19SJun-ichiro itojun Hagino 		 */
209686cdd19SJun-ichiro itojun Hagino 		switch (scope) {
210686cdd19SJun-ichiro itojun Hagino 		case IPV6_ADDR_SCOPE_NODELOCAL:
211686cdd19SJun-ichiro itojun Hagino 			return IPV6_ADDR_SCOPE_NODELOCAL;
212686cdd19SJun-ichiro itojun Hagino 			break;
213686cdd19SJun-ichiro itojun Hagino 		case IPV6_ADDR_SCOPE_LINKLOCAL:
214686cdd19SJun-ichiro itojun Hagino 			return IPV6_ADDR_SCOPE_LINKLOCAL;
215686cdd19SJun-ichiro itojun Hagino 			break;
216686cdd19SJun-ichiro itojun Hagino 		case IPV6_ADDR_SCOPE_SITELOCAL:
217686cdd19SJun-ichiro itojun Hagino 			return IPV6_ADDR_SCOPE_SITELOCAL;
218686cdd19SJun-ichiro itojun Hagino 			break;
219686cdd19SJun-ichiro itojun Hagino 		default:
220686cdd19SJun-ichiro itojun Hagino 			return IPV6_ADDR_SCOPE_GLOBAL;
221686cdd19SJun-ichiro itojun Hagino 			break;
222686cdd19SJun-ichiro itojun Hagino 		}
223686cdd19SJun-ichiro itojun Hagino 	}
224686cdd19SJun-ichiro itojun Hagino 
225686cdd19SJun-ichiro itojun Hagino 	if (bcmp(&in6addr_loopback, addr, sizeof(addr) - 1) == 0) {
226686cdd19SJun-ichiro itojun Hagino 		if (addr->s6_addr8[15] == 1) /* loopback */
227686cdd19SJun-ichiro itojun Hagino 			return IPV6_ADDR_SCOPE_NODELOCAL;
228686cdd19SJun-ichiro itojun Hagino 		if (addr->s6_addr8[15] == 0) /* unspecified */
229686cdd19SJun-ichiro itojun Hagino 			return IPV6_ADDR_SCOPE_LINKLOCAL;
230686cdd19SJun-ichiro itojun Hagino 	}
231686cdd19SJun-ichiro itojun Hagino 
232686cdd19SJun-ichiro itojun Hagino 	return IPV6_ADDR_SCOPE_GLOBAL;
233686cdd19SJun-ichiro itojun Hagino }
234686cdd19SJun-ichiro itojun Hagino 
235686cdd19SJun-ichiro itojun Hagino int
236686cdd19SJun-ichiro itojun Hagino in6_addr2scopeid(ifp, addr)
237686cdd19SJun-ichiro itojun Hagino 	struct ifnet *ifp;	/* must not be NULL */
238686cdd19SJun-ichiro itojun Hagino 	struct in6_addr *addr;	/* must not be NULL */
239686cdd19SJun-ichiro itojun Hagino {
240686cdd19SJun-ichiro itojun Hagino 	int scope = in6_addrscope(addr);
241686cdd19SJun-ichiro itojun Hagino 
242686cdd19SJun-ichiro itojun Hagino 	if (scope6_ids == NULL)	/* paranoid? */
243686cdd19SJun-ichiro itojun Hagino 		return(0);	/* XXX */
244686cdd19SJun-ichiro itojun Hagino 	if (ifp->if_index >= if_indexlim)
245686cdd19SJun-ichiro itojun Hagino 		return(0);	/* XXX */
246686cdd19SJun-ichiro itojun Hagino 
247686cdd19SJun-ichiro itojun Hagino #define SID scope6_ids[ifp->if_index]
248686cdd19SJun-ichiro itojun Hagino 	switch(scope) {
249686cdd19SJun-ichiro itojun Hagino 	case IPV6_ADDR_SCOPE_NODELOCAL:
250686cdd19SJun-ichiro itojun Hagino 		return(-1);	/* XXX: is this an appropriate value? */
251686cdd19SJun-ichiro itojun Hagino 
252686cdd19SJun-ichiro itojun Hagino 	case IPV6_ADDR_SCOPE_LINKLOCAL:
253686cdd19SJun-ichiro itojun Hagino 		return(SID.s6id_list[IPV6_ADDR_SCOPE_LINKLOCAL]);
254686cdd19SJun-ichiro itojun Hagino 
255686cdd19SJun-ichiro itojun Hagino 	case IPV6_ADDR_SCOPE_SITELOCAL:
256686cdd19SJun-ichiro itojun Hagino 		return(SID.s6id_list[IPV6_ADDR_SCOPE_SITELOCAL]);
257686cdd19SJun-ichiro itojun Hagino 
258686cdd19SJun-ichiro itojun Hagino 	case IPV6_ADDR_SCOPE_ORGLOCAL:
259686cdd19SJun-ichiro itojun Hagino 		return(SID.s6id_list[IPV6_ADDR_SCOPE_ORGLOCAL]);
260686cdd19SJun-ichiro itojun Hagino 
261686cdd19SJun-ichiro itojun Hagino 	default:
262686cdd19SJun-ichiro itojun Hagino 		return(0);	/* XXX: treat as global. */
263686cdd19SJun-ichiro itojun Hagino 	}
264686cdd19SJun-ichiro itojun Hagino #undef SID
265686cdd19SJun-ichiro itojun Hagino }
266686cdd19SJun-ichiro itojun Hagino 
267686cdd19SJun-ichiro itojun Hagino void
268686cdd19SJun-ichiro itojun Hagino scope6_setdefault(ifp)
269686cdd19SJun-ichiro itojun Hagino 	struct ifnet *ifp;	/* note that this might be NULL */
270686cdd19SJun-ichiro itojun Hagino {
271686cdd19SJun-ichiro itojun Hagino 	/*
272686cdd19SJun-ichiro itojun Hagino 	 * Currently, this function just set the default "link" according to
273686cdd19SJun-ichiro itojun Hagino 	 * the given interface.
274686cdd19SJun-ichiro itojun Hagino 	 * We might eventually have to separate the notion of "link" from
275686cdd19SJun-ichiro itojun Hagino 	 * "interface" and provide a user interface to set the default.
276686cdd19SJun-ichiro itojun Hagino 	 */
277686cdd19SJun-ichiro itojun Hagino 	if (ifp) {
278686cdd19SJun-ichiro itojun Hagino 		scope6_ids[0].s6id_list[IPV6_ADDR_SCOPE_LINKLOCAL] =
279686cdd19SJun-ichiro itojun Hagino 			ifp->if_index;
280686cdd19SJun-ichiro itojun Hagino 	}
281686cdd19SJun-ichiro itojun Hagino 	else
282686cdd19SJun-ichiro itojun Hagino 		scope6_ids[0].s6id_list[IPV6_ADDR_SCOPE_LINKLOCAL] = 0;
283686cdd19SJun-ichiro itojun Hagino }
284686cdd19SJun-ichiro itojun Hagino 
285686cdd19SJun-ichiro itojun Hagino int
286686cdd19SJun-ichiro itojun Hagino scope6_get_default(idlist)
287686cdd19SJun-ichiro itojun Hagino 	u_int32_t *idlist;
288686cdd19SJun-ichiro itojun Hagino {
289686cdd19SJun-ichiro itojun Hagino 	if (scope6_ids == NULL)	/* paranoid? */
290686cdd19SJun-ichiro itojun Hagino 		return(EINVAL);
291686cdd19SJun-ichiro itojun Hagino 
292686cdd19SJun-ichiro itojun Hagino 	bcopy(scope6_ids[0].s6id_list, idlist,
293686cdd19SJun-ichiro itojun Hagino 	      sizeof(scope6_ids[0].s6id_list));
294686cdd19SJun-ichiro itojun Hagino 
295686cdd19SJun-ichiro itojun Hagino 	return(0);
296686cdd19SJun-ichiro itojun Hagino }
297686cdd19SJun-ichiro itojun Hagino 
298686cdd19SJun-ichiro itojun Hagino u_int32_t
299686cdd19SJun-ichiro itojun Hagino scope6_addr2default(addr)
300686cdd19SJun-ichiro itojun Hagino 	struct in6_addr *addr;
301686cdd19SJun-ichiro itojun Hagino {
302686cdd19SJun-ichiro itojun Hagino 	return(scope6_ids[0].s6id_list[in6_addrscope(addr)]);
303686cdd19SJun-ichiro itojun Hagino }
304