in6_pcb.c revision 1.18 1 /* $NetBSD: in6_pcb.c,v 1.18 2000/02/03 13:17:39 itojun Exp $ */
2
3 /*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
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.
18 *
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
29 * SUCH DAMAGE.
30 */
31
32 /*
33 * Copyright (c) 1982, 1986, 1991, 1993
34 * The Regents of the University of California. All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. All advertising materials mentioning features or use of this software
45 * must display the following acknowledgement:
46 * This product includes software developed by the University of
47 * California, Berkeley and its contributors.
48 * 4. Neither the name of the University nor the names of its contributors
49 * may be used to endorse or promote products derived from this software
50 * without specific prior written permission.
51 *
52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62 * SUCH DAMAGE.
63 *
64 * @(#)in_pcb.c 8.2 (Berkeley) 1/4/94
65 */
66
67 #include "opt_ipsec.h"
68
69 #include <sys/param.h>
70 #include <sys/systm.h>
71 #include <sys/malloc.h>
72 #include <sys/mbuf.h>
73 #include <sys/protosw.h>
74 #include <sys/socket.h>
75 #include <sys/socketvar.h>
76 #include <sys/ioctl.h>
77 #include <sys/errno.h>
78 #include <sys/time.h>
79 #include <sys/proc.h>
80
81 #include <net/if.h>
82 #include <net/route.h>
83
84 #include <netinet/in.h>
85 #include <netinet/in_var.h>
86 #include <netinet/in_systm.h>
87 #include <netinet/ip.h>
88 #include <netinet/in_pcb.h>
89 #include <netinet6/ip6.h>
90 #include <netinet6/ip6_var.h>
91 #include <netinet6/in6_pcb.h>
92 #include <netinet6/nd6.h>
93
94 #include "loop.h"
95 extern struct ifnet loif[NLOOP];
96 #include "faith.h"
97
98 #ifdef IPSEC
99 #include <netinet6/ipsec.h>
100 #include <netkey/key.h>
101 #include <netkey/key_debug.h>
102 #endif /* IPSEC */
103
104 struct in6_addr zeroin6_addr;
105
106 int
107 in6_pcballoc(so, head)
108 struct socket *so;
109 struct in6pcb *head;
110 {
111 struct in6pcb *in6p;
112
113 MALLOC(in6p, struct in6pcb *, sizeof(*in6p), M_PCB, M_NOWAIT);
114 if (in6p == NULL)
115 return(ENOBUFS);
116 bzero((caddr_t)in6p, sizeof(*in6p));
117 in6p->in6p_head = head;
118 in6p->in6p_socket = so;
119 in6p->in6p_hops = -1; /* use kernel default */
120 in6p->in6p_icmp6filt = NULL;
121 in6p->in6p_next = head->in6p_next;
122 head->in6p_next = in6p;
123 in6p->in6p_prev = head;
124 in6p->in6p_next->in6p_prev = in6p;
125 #ifndef INET6_BINDV6ONLY
126 if (ip6_bindv6only)
127 in6p->in6p_flags |= IN6P_BINDV6ONLY;
128 #else
129 in6p->in6p_flags |= IN6P_BINDV6ONLY; /*just for safety*/
130 #endif
131 so->so_pcb = (caddr_t)in6p;
132 return(0);
133 }
134
135 int
136 in6_pcbbind(in6p, nam)
137 register struct in6pcb *in6p;
138 struct mbuf *nam;
139 {
140 struct socket *so = in6p->in6p_socket;
141 struct in6pcb *head = in6p->in6p_head;
142 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)NULL;
143 struct proc *p = curproc; /* XXX */
144 u_int16_t lport = 0;
145 int wild = 0, reuseport = (so->so_options & SO_REUSEPORT);
146 int error;
147
148 if (in6p->in6p_lport || !IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr))
149 return(EINVAL);
150 if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0 &&
151 ((so->so_proto->pr_flags & PR_CONNREQUIRED) == 0 ||
152 (so->so_options & SO_ACCEPTCONN) == 0))
153 wild = IN6PLOOKUP_WILDCARD;
154 if (nam) {
155 sin6 = mtod(nam, struct sockaddr_in6 *);
156 if (nam->m_len != sizeof(*sin6))
157 return(EINVAL);
158 /*
159 * We should check the family, but old programs
160 * incorrectly fail to intialize it.
161 */
162 if (sin6->sin6_family != AF_INET6)
163 return(EAFNOSUPPORT);
164
165 /*
166 * If the scope of the destination is link-local, embed the
167 * interface index in the address.
168 */
169 if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr)) {
170 /* XXX boundary check is assumed to be already done. */
171 /* XXX sin6_scope_id is weaker than advanced-api. */
172 struct in6_pktinfo *pi;
173 if (in6p->in6p_outputopts &&
174 (pi = in6p->in6p_outputopts->ip6po_pktinfo) &&
175 pi->ipi6_ifindex) {
176 sin6->sin6_addr.s6_addr16[1]
177 = htons(pi->ipi6_ifindex);
178 } else if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)
179 && in6p->in6p_moptions
180 && in6p->in6p_moptions->im6o_multicast_ifp) {
181 sin6->sin6_addr.s6_addr16[1] =
182 htons(in6p->in6p_moptions->im6o_multicast_ifp->if_index);
183 } else if (sin6->sin6_scope_id) {
184 /* boundary check */
185 if (sin6->sin6_scope_id < 0
186 || if_index < sin6->sin6_scope_id) {
187 return ENXIO; /* XXX EINVAL? */
188 }
189 sin6->sin6_addr.s6_addr16[1]
190 = htons(sin6->sin6_scope_id & 0xffff);/*XXX*/
191 /* this must be cleared for ifa_ifwithaddr() */
192 sin6->sin6_scope_id = 0;
193 }
194 }
195
196 lport = sin6->sin6_port;
197 if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
198 /*
199 * Treat SO_REUSEADDR as SO_REUSEPORT for multicast;
200 * allow compepte duplication of binding if
201 * SO_REUSEPORT is set, or if SO_REUSEADDR is set
202 * and a multicast address is bound on both
203 * new and duplicated sockets.
204 */
205 if (so->so_options & SO_REUSEADDR)
206 reuseport = SO_REUSEADDR|SO_REUSEPORT;
207 } else if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
208 struct sockaddr_in sin;
209
210 bzero(&sin, sizeof(sin));
211 sin.sin_len = sizeof(sin);
212 sin.sin_family = AF_INET;
213 bcopy(&sin6->sin6_addr.s6_addr32[3], &sin.sin_addr,
214 sizeof(sin.sin_addr));
215 if (ifa_ifwithaddr((struct sockaddr *)&sin) == 0)
216 return EADDRNOTAVAIL;
217 } else if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
218 struct ifaddr *ia = NULL;
219
220 sin6->sin6_port = 0; /* yech... */
221 #if defined(NFAITH) && NFAITH > 0
222 if ((in6p->in6p_flags & IN6P_FAITH) == 0
223 && (ia = ifa_ifwithaddr((struct sockaddr *)sin6)) == 0)
224 #else
225 if ((ia = ifa_ifwithaddr((struct sockaddr *)sin6)) == 0)
226 #endif
227 return(EADDRNOTAVAIL);
228
229 /*
230 * XXX: bind to an anycast address might accidentally
231 * cause sending a packet with anycast source address.
232 */
233 if (ia != NULL) {
234 struct in6_ifaddr *ia6 = (void *)ia;
235
236 if (ia6->ia6_flags &
237 (IN6_IFF_ANYCAST|IN6_IFF_NOTREADY|
238 IN6_IFF_DETACHED|IN6_IFF_DEPRECATED))
239 return (EADDRNOTAVAIL);
240 }
241 }
242 if (lport) {
243 #ifndef IPNOPRIVPORTS
244 /* GROSS */
245 if (ntohs(lport) < IPV6PORT_RESERVED &&
246 (p == 0 ||
247 (error = suser(p->p_ucred, &p->p_acflag))))
248 return(EACCES);
249 #endif
250
251 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
252 /* should check this but we can't ... */
253 #if 0
254 struct inpcb *t;
255
256 t = in_pcblookup_bind(&tcbtable,
257 (struct in_addr *)&sin6->sin6_addr.s6_addr32[3],
258 lport);
259 if (t && (reuseport & t->inp_socket->so_options) == 0)
260 return EADDRINUSE;
261 #endif
262 } else {
263 struct in6pcb *t;
264
265 t = in6_pcblookup(head, &zeroin6_addr, 0,
266 &sin6->sin6_addr, lport, wild);
267 if (t && (reuseport & t->in6p_socket->so_options) == 0)
268 return(EADDRINUSE);
269 }
270 }
271 in6p->in6p_laddr = sin6->sin6_addr;
272 }
273
274 if (lport == 0) {
275 int e;
276 if ((e = in6_pcbsetport(&in6p->in6p_laddr, in6p)) != 0)
277 return(e);
278 }
279 else
280 in6p->in6p_lport = lport;
281
282 in6p->in6p_flowinfo = sin6 ? sin6->sin6_flowinfo : 0; /*XXX*/
283 return(0);
284 }
285
286 /*
287 * Find an empty port and set it to the specified PCB.
288 */
289 int
290 in6_pcbsetport(laddr, in6p)
291 struct in6_addr *laddr;
292 struct in6pcb *in6p;
293 {
294 struct socket *so = in6p->in6p_socket;
295 struct in6pcb *head = in6p->in6p_head;
296 u_int16_t last_port, lport = 0;
297 int wild = 0;
298 void *t;
299 u_int16_t min, max;
300 #ifndef IPNOPRIVPORTS
301 struct proc *p = curproc; /*XXX*/
302 #endif
303
304 /* XXX: this is redundant when called from in6_pcbbind */
305 if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0 &&
306 ((so->so_proto->pr_flags & PR_CONNREQUIRED) == 0 ||
307 (so->so_options & SO_ACCEPTCONN) == 0))
308 wild = IN6PLOOKUP_WILDCARD;
309
310 if (in6p->in6p_flags & IN6P_LOWPORT) {
311 #ifndef IPNOPRIVPORTS
312 if (p == 0 || (suser(p->p_ucred, &p->p_acflag) != 0))
313 return (EACCES);
314 #endif
315 min = IPV6PORT_RESERVEDMIN;
316 max = IPV6PORT_RESERVEDMAX;
317 } else {
318 min = IPV6PORT_ANONMIN;
319 max = IPV6PORT_ANONMAX;
320 }
321
322 /* value out of range */
323 if (head->in6p_lport < min)
324 head->in6p_lport = min;
325 else if (head->in6p_lport > max)
326 head->in6p_lport = min;
327 last_port = head->in6p_lport;
328 goto startover; /*to randomize*/
329 for (;;) {
330 lport = htons(head->in6p_lport);
331 if (IN6_IS_ADDR_V4MAPPED(laddr)) {
332 #if 0
333 t = in_pcblookup_bind(&tcbtable,
334 (struct in_addr *)&in6p->in6p_laddr.s6_addr32[3],
335 lport);
336 #else
337 t = NULL;
338 #endif
339 } else {
340 t = in6_pcblookup(head, &zeroin6_addr, 0, laddr,
341 lport, wild);
342 }
343 if (t == 0)
344 break;
345 startover:
346 if (head->in6p_lport >= max)
347 head->in6p_lport = min;
348 else
349 head->in6p_lport++;
350 if (head->in6p_lport == last_port)
351 return (EADDRINUSE);
352 }
353
354 in6p->in6p_lport = lport;
355 return(0); /* success */
356 }
357
358 /*
359 * Connect from a socket to a specified address.
360 * Both address and port must be specified in argument sin6.
361 * If don't have a local address for this socket yet,
362 * then pick one.
363 */
364 int
365 in6_pcbconnect(in6p, nam)
366 struct in6pcb *in6p;
367 struct mbuf *nam;
368 {
369 struct in6_addr *in6a = NULL;
370 struct sockaddr_in6 *sin6 = mtod(nam, struct sockaddr_in6 *);
371 struct in6_pktinfo *pi;
372 struct ifnet *ifp = NULL; /* outgoing interface */
373 int error = 0;
374 struct in6_addr mapped;
375
376 (void)&in6a; /* XXX fool gcc */
377
378 if (nam->m_len != sizeof(*sin6))
379 return(EINVAL);
380 if (sin6->sin6_family != AF_INET6)
381 return(EAFNOSUPPORT);
382 if (sin6->sin6_port == 0)
383 return(EADDRNOTAVAIL);
384
385 /* sanity check for mapped address case */
386 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
387 if (IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr))
388 in6p->in6p_laddr.s6_addr16[5] = htons(0xffff);
389 if (!IN6_IS_ADDR_V4MAPPED(&in6p->in6p_laddr))
390 return EINVAL;
391 } else {
392 if (IN6_IS_ADDR_V4MAPPED(&in6p->in6p_laddr))
393 return EINVAL;
394 }
395
396 /*
397 * If the scope of the destination is link-local, embed the interface
398 * index in the address.
399 */
400 if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr)) {
401 /* XXX boundary check is assumed to be already done. */
402 /* XXX sin6_scope_id is weaker than advanced-api. */
403 if (in6p->in6p_outputopts &&
404 (pi = in6p->in6p_outputopts->ip6po_pktinfo) &&
405 pi->ipi6_ifindex) {
406 sin6->sin6_addr.s6_addr16[1] = htons(pi->ipi6_ifindex);
407 ifp = ifindex2ifnet[pi->ipi6_ifindex];
408 }
409 else if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr) &&
410 in6p->in6p_moptions &&
411 in6p->in6p_moptions->im6o_multicast_ifp) {
412 sin6->sin6_addr.s6_addr16[1] =
413 htons(in6p->in6p_moptions->im6o_multicast_ifp->if_index);
414 ifp = ifindex2ifnet[in6p->in6p_moptions->im6o_multicast_ifp->if_index];
415 } else if (sin6->sin6_scope_id) {
416 /* boundary check */
417 if (sin6->sin6_scope_id < 0
418 || if_index < sin6->sin6_scope_id) {
419 return ENXIO; /* XXX EINVAL? */
420 }
421 sin6->sin6_addr.s6_addr16[1]
422 = htons(sin6->sin6_scope_id & 0xffff);/*XXX*/
423 ifp = ifindex2ifnet[sin6->sin6_scope_id];
424 }
425 }
426
427 /* Source address selection. */
428 if (IN6_IS_ADDR_V4MAPPED(&in6p->in6p_laddr)
429 && in6p->in6p_laddr.s6_addr32[3] == 0) {
430 struct sockaddr_in sin, *sinp;
431
432 bzero(&sin, sizeof(sin));
433 sin.sin_len = sizeof(sin);
434 sin.sin_family = AF_INET;
435 bcopy(&sin6->sin6_addr.s6_addr32[3], &sin.sin_addr,
436 sizeof(sin.sin_addr));
437 sinp = in_selectsrc(&sin, (struct route *)&in6p->in6p_route,
438 in6p->in6p_socket->so_options, NULL, &error);
439 if (sinp == 0) {
440 if (error == 0)
441 error = EADDRNOTAVAIL;
442 return(error);
443 }
444 bzero(&mapped, sizeof(mapped));
445 mapped.s6_addr16[5] = htons(0xffff);
446 bcopy(&sinp->sin_addr, &mapped.s6_addr32[3], sizeof(sinp->sin_addr));
447 in6a = &mapped;
448 } else {
449 /*
450 * XXX: in6_selectsrc might replace the bound local address
451 * with the address specified by setsockopt(IPV6_PKTINFO).
452 * Is it the intended behavior?
453 */
454 in6a = in6_selectsrc(sin6, in6p->in6p_outputopts,
455 in6p->in6p_moptions,
456 &in6p->in6p_route,
457 &in6p->in6p_laddr, &error);
458 if (in6a == 0) {
459 if (error == 0)
460 error = EADDRNOTAVAIL;
461 return(error);
462 }
463 }
464 if (in6p->in6p_route.ro_rt)
465 ifp = in6p->in6p_route.ro_rt->rt_ifp;
466
467 in6p->in6p_ip6.ip6_hlim = (u_int8_t)in6_selecthlim(in6p, ifp);
468
469 if (in6_pcblookup(in6p->in6p_head,
470 &sin6->sin6_addr,
471 sin6->sin6_port,
472 IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr) ?
473 in6a : &in6p->in6p_laddr,
474 in6p->in6p_lport,
475 0))
476 return(EADDRINUSE);
477 if (IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr)
478 || (IN6_IS_ADDR_V4MAPPED(&in6p->in6p_laddr)
479 && in6p->in6p_laddr.s6_addr32[3] == 0)) {
480 if (in6p->in6p_lport == 0)
481 (void)in6_pcbbind(in6p, (struct mbuf *)0);
482 in6p->in6p_laddr = *in6a;
483 }
484 in6p->in6p_faddr = sin6->sin6_addr;
485 in6p->in6p_fport = sin6->sin6_port;
486 /*
487 * xxx kazu flowlabel is necessary for connect?
488 * but if this line is missing, the garbage value remains.
489 */
490 in6p->in6p_flowinfo = sin6->sin6_flowinfo;
491 return(0);
492 }
493
494 /*
495 * Return an IPv6 address, which is the most appropriate for given
496 * destination and user specified options.
497 * If necessary, this function lookups the routing table and return
498 * an entry to the caller for later use.
499 */
500 struct in6_addr *
501 in6_selectsrc(dstsock, opts, mopts, ro, laddr, errorp)
502 struct sockaddr_in6 *dstsock;
503 struct ip6_pktopts *opts;
504 struct ip6_moptions *mopts;
505 struct route_in6 *ro;
506 struct in6_addr *laddr;
507 int *errorp;
508 {
509 struct in6_addr *dst;
510 struct in6_ifaddr *ia6 = 0;
511 struct in6_pktinfo *pi = NULL;
512
513 dst = &dstsock->sin6_addr;
514 *errorp = 0;
515
516 /*
517 * If the source address is explicitly specified by the caller,
518 * use it.
519 */
520 if (opts && (pi = opts->ip6po_pktinfo) &&
521 !IN6_IS_ADDR_UNSPECIFIED(&pi->ipi6_addr))
522 return(&pi->ipi6_addr);
523
524 /*
525 * If the source address is not specified but the socket(if any)
526 * is already bound, use the bound address.
527 */
528 if (laddr && !IN6_IS_ADDR_UNSPECIFIED(laddr))
529 return(laddr);
530
531 /*
532 * If the caller doesn't specify the source address but
533 * the outgoing interface, use an address associated with
534 * the interface.
535 */
536 if (pi && pi->ipi6_ifindex) {
537 /* XXX boundary check is assumed to be already done. */
538 ia6 = in6_ifawithscope(ifindex2ifnet[pi->ipi6_ifindex],
539 dst);
540 if (ia6 == 0) {
541 *errorp = EADDRNOTAVAIL;
542 return(0);
543 }
544 return(&satosin6(&ia6->ia_addr)->sin6_addr);
545 }
546
547 /*
548 * If the destination address is a link-local unicast address or
549 * a multicast address, and if the outgoing interface is specified
550 * by the sin6_scope_id filed, use an address associated with the
551 * interface.
552 * XXX: We're now trying to define more specific semantics of
553 * sin6_scope_id field, so this part will be rewritten in
554 * the near future.
555 */
556 if ((IN6_IS_ADDR_LINKLOCAL(dst) || IN6_IS_ADDR_MULTICAST(dst)) &&
557 dstsock->sin6_scope_id) {
558 /*
559 * I'm not sure if boundary check for scope_id is done
560 * somewhere...
561 */
562 if (dstsock->sin6_scope_id < 0 ||
563 if_index < dstsock->sin6_scope_id) {
564 *errorp = ENXIO; /* XXX: better error? */
565 return(0);
566 }
567 ia6 = in6_ifawithscope(ifindex2ifnet[dstsock->sin6_scope_id],
568 dst);
569 if (ia6 == 0) {
570 *errorp = EADDRNOTAVAIL;
571 return(0);
572 }
573 return(&satosin6(&ia6->ia_addr)->sin6_addr);
574 }
575
576 /*
577 * If the destination address is a multicast address and
578 * the outgoing interface for the address is specified
579 * by the caller, use an address associated with the interface.
580 * There is a sanity check here; if the destination has node-local
581 * scope, the outgoing interfacde should be a loopback address.
582 * Even if the outgoing interface is not specified, we also
583 * choose a loopback interface as the outgoing interface.
584 */
585 if (IN6_IS_ADDR_MULTICAST(dst)) {
586 struct ifnet *ifp = mopts ? mopts->im6o_multicast_ifp : NULL;
587
588 if (ifp == NULL && IN6_IS_ADDR_MC_NODELOCAL(dst)) {
589 ifp = &loif[0];
590 }
591
592 if (ifp) {
593 ia6 = in6_ifawithscope(ifp, dst);
594 if (ia6 == 0) {
595 *errorp = EADDRNOTAVAIL;
596 return(0);
597 }
598 return(&satosin6(&ia6->ia_addr)->sin6_addr);
599 }
600 }
601
602 /*
603 * If the next hop address for the packet is specified
604 * by caller, use an address associated with the route
605 * to the next hop.
606 */
607 {
608 struct sockaddr_in6 *sin6_next;
609 struct rtentry *rt;
610
611 if (opts && opts->ip6po_nexthop) {
612 sin6_next = satosin6(opts->ip6po_nexthop);
613 rt = nd6_lookup(&sin6_next->sin6_addr, 1, NULL);
614 if (rt) {
615 ia6 = in6_ifawithscope(rt->rt_ifp, dst);
616 if (ia6 == 0)
617 ia6 = ifatoia6(rt->rt_ifa);
618 }
619 if (ia6 == 0) {
620 *errorp = EADDRNOTAVAIL;
621 return(0);
622 }
623 return(&satosin6(&ia6->ia_addr)->sin6_addr);
624 }
625 }
626
627 /*
628 * If route is known or can be allocated now,
629 * our src addr is taken from the i/f, else punt.
630 */
631 if (ro) {
632 if (ro->ro_rt &&
633 !IN6_ARE_ADDR_EQUAL(&satosin6(&ro->ro_dst)->sin6_addr, dst)) {
634 RTFREE(ro->ro_rt);
635 ro->ro_rt = (struct rtentry *)0;
636 }
637 if (ro->ro_rt == (struct rtentry *)0 ||
638 ro->ro_rt->rt_ifp == (struct ifnet *)0) {
639 /* No route yet, so try to acquire one */
640 bzero(&ro->ro_dst, sizeof(struct sockaddr_in6));
641 ro->ro_dst.sin6_family = AF_INET6;
642 ro->ro_dst.sin6_len = sizeof(struct sockaddr_in6);
643 ro->ro_dst.sin6_addr = *dst;
644 if (IN6_IS_ADDR_MULTICAST(dst)) {
645 ro->ro_rt = rtalloc1(&((struct route *)ro)
646 ->ro_dst, 0);
647 } else {
648 rtalloc((struct route *)ro);
649 }
650
651 }
652
653 /*
654 * in_pcbconnect() checks out IFF_LOOPBACK to skip using
655 * the address. But we don't know why it does so.
656 * It is necessary to ensure the scope even for lo0
657 * so doesn't check out IFF_LOOPBACK.
658 */
659
660 if (ro->ro_rt) {
661 ia6 = in6_ifawithscope(ro->ro_rt->rt_ifa->ifa_ifp, dst);
662 if (ia6 == 0) /* xxx scope error ?*/
663 ia6 = ifatoia6(ro->ro_rt->rt_ifa);
664 }
665 #if 0
666 /*
667 * xxx The followings are necessary? (kazu)
668 * I don't think so.
669 * It's for SO_DONTROUTE option in IPv4.(jinmei)
670 */
671 if (ia6 == 0) {
672 struct sockaddr_in6 sin6 = {sizeof(sin6), AF_INET6, 0};
673
674 sin6->sin6_addr = *dst;
675
676 ia6 = ifatoia6(ifa_ifwithdstaddr(sin6tosa(&sin6)));
677 if (ia6 == 0)
678 ia6 = ifatoia6(ifa_ifwithnet(sin6tosa(&sin6)));
679 if (ia6 == 0)
680 return(0);
681 return(&satosin6(&ia6->ia_addr)->sin6_addr);
682 }
683 #endif /* 0 */
684 if (ia6 == 0) {
685 *errorp = EHOSTUNREACH; /* no route */
686 return(0);
687 }
688 return(&satosin6(&ia6->ia_addr)->sin6_addr);
689 }
690
691 *errorp = EADDRNOTAVAIL;
692 return(0);
693 }
694
695 /*
696 * Default hop limit selection. The precedence is as follows:
697 * 1. Hoplimit valued specified via ioctl.
698 * 2. (If the outgoing interface is detected) the current
699 * hop limit of the interface specified by router advertisement.
700 * 3. The system default hoplimit.
701 */
702 int
703 in6_selecthlim(in6p, ifp)
704 struct in6pcb *in6p;
705 struct ifnet *ifp;
706 {
707 if (in6p && in6p->in6p_hops >= 0)
708 return(in6p->in6p_hops);
709 else if (ifp)
710 return(nd_ifinfo[ifp->if_index].chlim);
711 else
712 return(ip6_defhlim);
713 }
714
715 void
716 in6_pcbdisconnect(in6p)
717 struct in6pcb *in6p;
718 {
719 bzero((caddr_t)&in6p->in6p_faddr, sizeof(in6p->in6p_faddr));
720 in6p->in6p_fport = 0;
721 if (in6p->in6p_socket->so_state & SS_NOFDREF)
722 in6_pcbdetach(in6p);
723 }
724
725 void
726 in6_pcbdetach(in6p)
727 struct in6pcb *in6p;
728 {
729 struct socket *so = in6p->in6p_socket;
730
731 #ifdef IPSEC
732 ipsec6_delete_pcbpolicy(in6p);
733 #endif /* IPSEC */
734 sotoin6pcb(so) = 0;
735 sofree(so);
736 if (in6p->in6p_options)
737 m_freem(in6p->in6p_options);
738 if (in6p->in6p_outputopts) {
739 if (in6p->in6p_outputopts->ip6po_rthdr &&
740 in6p->in6p_outputopts->ip6po_route.ro_rt)
741 RTFREE(in6p->in6p_outputopts->ip6po_route.ro_rt);
742 if (in6p->in6p_outputopts->ip6po_m)
743 (void)m_free(in6p->in6p_outputopts->ip6po_m);
744 free(in6p->in6p_outputopts, M_IP6OPT);
745 }
746 if (in6p->in6p_route.ro_rt)
747 rtfree(in6p->in6p_route.ro_rt);
748 ip6_freemoptions(in6p->in6p_moptions);
749 in6p->in6p_next->in6p_prev = in6p->in6p_prev;
750 in6p->in6p_prev->in6p_next = in6p->in6p_next;
751 in6p->in6p_prev = NULL;
752 FREE(in6p, M_PCB);
753 }
754
755 void
756 in6_setsockaddr(in6p, nam)
757 struct in6pcb *in6p;
758 struct mbuf *nam;
759 {
760 struct sockaddr_in6 *sin6;
761
762 nam->m_len = sizeof(*sin6);
763 sin6 = mtod(nam, struct sockaddr_in6 *);
764 bzero((caddr_t)sin6, sizeof(*sin6));
765 sin6->sin6_family = AF_INET6;
766 sin6->sin6_len = sizeof(struct sockaddr_in6);
767 sin6->sin6_port = in6p->in6p_lport;
768 sin6->sin6_addr = in6p->in6p_laddr;
769 if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr))
770 sin6->sin6_scope_id = ntohs(sin6->sin6_addr.s6_addr16[1]);
771 else
772 sin6->sin6_scope_id = 0; /*XXX*/
773 if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr))
774 sin6->sin6_addr.s6_addr16[1] = 0;
775 }
776
777 void
778 in6_setpeeraddr(in6p, nam)
779 struct in6pcb *in6p;
780 struct mbuf *nam;
781 {
782 struct sockaddr_in6 *sin6;
783
784 nam->m_len = sizeof(*sin6);
785 sin6 = mtod(nam, struct sockaddr_in6 *);
786 bzero((caddr_t)sin6, sizeof(*sin6));
787 sin6->sin6_family = AF_INET6;
788 sin6->sin6_len = sizeof(struct sockaddr_in6);
789 sin6->sin6_port = in6p->in6p_fport;
790 sin6->sin6_addr = in6p->in6p_faddr;
791 if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr))
792 sin6->sin6_scope_id = ntohs(sin6->sin6_addr.s6_addr16[1]);
793 else
794 sin6->sin6_scope_id = 0; /*XXX*/
795 if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr))
796 sin6->sin6_addr.s6_addr16[1] = 0;
797 }
798
799 /*
800 * Pass some notification to all connections of a protocol
801 * associated with address dst. The local address and/or port numbers
802 * may be specified to limit the search. The "usual action" will be
803 * taken, depending on the ctlinput cmd. The caller must filter any
804 * cmds that are uninteresting (e.g., no error in the map).
805 * Call the protocol specific routine (if any) to report
806 * any errors for each matching socket.
807 *
808 * Must be called at splsoftnet.
809 */
810 int
811 in6_pcbnotify(head, dst, fport_arg, laddr6, lport_arg, cmd, notify)
812 struct in6pcb *head;
813 struct sockaddr *dst;
814 u_int fport_arg, lport_arg;
815 struct in6_addr *laddr6;
816 int cmd;
817 void (*notify) __P((struct in6pcb *, int));
818 {
819 struct in6pcb *in6p, *oin6p;
820 struct in6_addr faddr6;
821 u_int16_t fport = fport_arg, lport = lport_arg;
822 int errno;
823 int nmatch = 0;
824
825 if ((unsigned)cmd > PRC_NCMDS || dst->sa_family != AF_INET6)
826 return 0;
827 faddr6 = ((struct sockaddr_in6 *)dst)->sin6_addr;
828 if (IN6_IS_ADDR_UNSPECIFIED(&faddr6))
829 return 0;
830
831 /*
832 * Redirects go to all references to the destination,
833 * and use in_rtchange to invalidate the route cache.
834 * Dead host indications: notify all references to the destination.
835 * Otherwise, if we have knowledge of the local port and address,
836 * deliver only to that socket.
837 */
838 if (PRC_IS_REDIRECT(cmd) || cmd == PRC_HOSTDEAD) {
839 fport = 0;
840 lport = 0;
841 bzero((caddr_t)laddr6, sizeof(*laddr6));
842 if (cmd != PRC_HOSTDEAD)
843 notify = in6_rtchange;
844 }
845 if (notify == NULL)
846 return 0;
847 errno = inet6ctlerrmap[cmd];
848 for (in6p = head->in6p_next; in6p != head;) {
849 if (!IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr,&faddr6) ||
850 in6p->in6p_socket == 0 ||
851 (lport && in6p->in6p_lport != lport) ||
852 (!IN6_IS_ADDR_UNSPECIFIED(laddr6) &&
853 !IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr, laddr6)) ||
854 (fport && in6p->in6p_fport != fport)) {
855 in6p = in6p->in6p_next;
856 continue;
857 }
858 oin6p = in6p;
859 in6p = in6p->in6p_next;
860 (*notify)(oin6p, errno);
861 nmatch++;
862 }
863 return nmatch;
864 }
865
866 void
867 in6_pcbpurgeif(head, ifp)
868 struct in6pcb *head;
869 struct ifnet *ifp;
870 {
871 struct in6pcb *in6p, *nin6p;
872
873 for (in6p = head->in6p_next; in6p != head; in6p = nin6p) {
874 nin6p = in6p->in6p_next;
875 if (in6p->in6p_route.ro_rt != NULL &&
876 in6p->in6p_route.ro_rt->rt_ifp == ifp)
877 in6_rtchange(in6p, 0);
878 }
879 }
880
881 /*
882 * Check for alternatives when higher level complains
883 * about service problems. For now, invalidate cached
884 * routing information. If the route was created dynamically
885 * (by a redirect), time to try a default gateway again.
886 */
887 void
888 in6_losing(in6p)
889 struct in6pcb *in6p;
890 {
891 struct rtentry *rt;
892 struct rt_addrinfo info;
893
894 if ((rt = in6p->in6p_route.ro_rt) != NULL) {
895 in6p->in6p_route.ro_rt = 0;
896 bzero((caddr_t)&info, sizeof(info));
897 info.rti_info[RTAX_DST] =
898 (struct sockaddr *)&in6p->in6p_route.ro_dst;
899 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
900 info.rti_info[RTAX_NETMASK] = rt_mask(rt);
901 rt_missmsg(RTM_LOSING, &info, rt->rt_flags, 0);
902 if (rt->rt_flags & RTF_DYNAMIC)
903 (void)rtrequest(RTM_DELETE, rt_key(rt),
904 rt->rt_gateway, rt_mask(rt), rt->rt_flags,
905 (struct rtentry **)0);
906 else
907 /*
908 * A new route can be allocated
909 * the next time output is attempted.
910 */
911 rtfree(rt);
912 }
913 }
914
915 /*
916 * After a routing change, flush old routing
917 * and allocate a (hopefully) better one.
918 */
919 void
920 in6_rtchange(in6p, errno)
921 struct in6pcb *in6p;
922 int errno;
923 {
924 if (in6p->in6p_route.ro_rt) {
925 rtfree(in6p->in6p_route.ro_rt);
926 in6p->in6p_route.ro_rt = 0;
927 /*
928 * A new route can be allocated the next time
929 * output is attempted.
930 */
931 }
932 }
933
934 struct in6pcb *
935 in6_pcblookup(head, faddr6, fport_arg, laddr6, lport_arg, flags)
936 struct in6pcb *head;
937 struct in6_addr *faddr6, *laddr6;
938 u_int fport_arg, lport_arg;
939 int flags;
940 {
941 struct in6pcb *in6p, *match = 0;
942 int matchwild = 3, wildcard;
943 u_int16_t fport = fport_arg, lport = lport_arg;
944
945 for (in6p = head->in6p_next; in6p != head; in6p = in6p->in6p_next) {
946 if (in6p->in6p_lport != lport)
947 continue;
948 wildcard = 0;
949 if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr)) {
950 if (IN6_IS_ADDR_UNSPECIFIED(laddr6))
951 wildcard++;
952 else if (!IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr, laddr6))
953 continue;
954 }
955 #ifndef TCP6
956 else if (IN6_IS_ADDR_V4MAPPED(&in6p->in6p_laddr)
957 && in6p->in6p_laddr.s6_addr32[3] == 0) {
958 if (!IN6_IS_ADDR_V4MAPPED(laddr6))
959 continue;
960 if (laddr6->s6_addr32[3] == 0)
961 ;
962 else
963 wildcard++;
964 }
965 #endif
966 else {
967 if (IN6_IS_ADDR_V4MAPPED(laddr6)) {
968 #if !defined(TCP6) && !defined(INET6_BINDV6ONLY)
969 if (in6p->in6p_flags & IN6P_BINDV6ONLY)
970 continue;
971 else
972 wildcard++;
973 #else
974 continue;
975 #endif
976 } else if (!IN6_IS_ADDR_UNSPECIFIED(laddr6))
977 wildcard++;
978 }
979 if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr)) {
980 if (IN6_IS_ADDR_UNSPECIFIED(faddr6))
981 wildcard++;
982 else if (!IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr, faddr6)
983 || in6p->in6p_fport != fport)
984 continue;
985 }
986 #ifndef TCP6
987 else if (IN6_IS_ADDR_V4MAPPED(&in6p->in6p_faddr)
988 && in6p->in6p_faddr.s6_addr32[3] == 0) {
989 if (!IN6_IS_ADDR_V4MAPPED(faddr6))
990 continue;
991 if (faddr6->s6_addr32[3] == 0)
992 ;
993 else
994 wildcard++;
995 }
996 #endif
997 else {
998 if (IN6_IS_ADDR_V4MAPPED(faddr6)) {
999 #if !defined(TCP6) && !defined(INET6_BINDV6ONLY)
1000 if (in6p->in6p_flags & IN6P_BINDV6ONLY)
1001 continue;
1002 else
1003 wildcard++;
1004 #else
1005 continue;
1006 #endif
1007 } else if (!IN6_IS_ADDR_UNSPECIFIED(faddr6))
1008 wildcard++;
1009 }
1010
1011 if (wildcard && (flags & IN6PLOOKUP_WILDCARD) == 0)
1012 continue;
1013 if (wildcard < matchwild) {
1014 match = in6p;
1015 matchwild = wildcard;
1016 if (matchwild == 0)
1017 break;
1018 }
1019 }
1020 return(match);
1021 }
1022
1023 #ifndef TCP6
1024 struct rtentry *
1025 in6_pcbrtentry(in6p)
1026 struct in6pcb *in6p;
1027 {
1028 struct route_in6 *ro;
1029
1030 ro = &in6p->in6p_route;
1031
1032 if (ro->ro_rt == NULL) {
1033 /*
1034 * No route yet, so try to acquire one.
1035 */
1036 if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr)) {
1037 bzero(&ro->ro_dst, sizeof(ro->ro_dst));
1038 ro->ro_dst.sin6_family = AF_INET6;
1039 ro->ro_dst.sin6_len = sizeof(struct sockaddr_in6);
1040 satosin6(&ro->ro_dst)->sin6_addr = in6p->in6p_faddr;
1041 rtalloc((struct route *)ro);
1042 }
1043 }
1044 return (ro->ro_rt);
1045 }
1046
1047 struct in6pcb *
1048 in6_pcblookup_connect(head, faddr6, fport_arg, laddr6, lport_arg, faith)
1049 struct in6pcb *head;
1050 struct in6_addr *faddr6, *laddr6;
1051 u_int fport_arg, lport_arg;
1052 int faith;
1053 {
1054 struct in6pcb *in6p;
1055 u_int16_t fport = fport_arg, lport = lport_arg;
1056
1057 for (in6p = head->in6p_next; in6p != head; in6p = in6p->in6p_next) {
1058 #if defined(NFAITH) && NFAITH > 0
1059 if (faith && (in6p->in6p_flags & IN6P_FAITH) == 0)
1060 continue;
1061 #endif
1062 /* find exact match on both source and dest */
1063 if (in6p->in6p_fport != fport)
1064 continue;
1065 if (in6p->in6p_lport != lport)
1066 continue;
1067 if (IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr))
1068 continue;
1069 if (!IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr, faddr6))
1070 continue;
1071 if (IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr))
1072 continue;
1073 if (!IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr, laddr6))
1074 continue;
1075 return in6p;
1076 }
1077 return NULL;
1078 }
1079
1080 struct in6pcb *
1081 in6_pcblookup_bind(head, laddr6, lport_arg, faith)
1082 struct in6pcb *head;
1083 struct in6_addr *laddr6;
1084 u_int lport_arg;
1085 int faith;
1086 {
1087 struct in6pcb *in6p, *match;
1088 u_int16_t lport = lport_arg;
1089
1090 match = NULL;
1091 for (in6p = head->in6p_next; in6p != head; in6p = in6p->in6p_next) {
1092 /*
1093 * find destination match. exact match is preferred
1094 * against wildcard match.
1095 */
1096 #if defined(NFAITH) && NFAITH > 0
1097 if (faith && (in6p->in6p_flags & IN6P_FAITH) == 0)
1098 continue;
1099 #endif
1100 if (in6p->in6p_fport != 0)
1101 continue;
1102 if (in6p->in6p_lport != lport)
1103 continue;
1104 if (IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr)) {
1105 if (IN6_IS_ADDR_V4MAPPED(laddr6)) {
1106 #ifndef INET6_BINDV6ONLY
1107 if (in6p->in6p_flags & IN6P_BINDV6ONLY)
1108 continue;
1109 else
1110 match = in6p;
1111 #else
1112 continue;
1113 #endif
1114 } else
1115 match = in6p;
1116 }
1117 else if (IN6_IS_ADDR_V4MAPPED(&in6p->in6p_laddr) &&
1118 in6p->in6p_laddr.s6_addr32[3] == 0) {
1119 if (IN6_IS_ADDR_V4MAPPED(laddr6)
1120 && laddr6->s6_addr32[3] != 0)
1121 match = in6p;
1122 }
1123 else if (IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr, laddr6))
1124 return in6p;
1125 }
1126 return match;
1127 }
1128 #endif
1129