]> git.saurik.com Git - apple/xnu.git/blob - bsd/netinet6/in6_pcb.c
xnu-1699.22.73.tar.gz
[apple/xnu.git] / bsd / netinet6 / in6_pcb.c
1 /*
2 * Copyright (c) 2003-2011 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28 /*
29 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
30 * All rights reserved.
31 *
32 * Redistribution and use in source and binary forms, with or without
33 * modification, are permitted provided that the following conditions
34 * are met:
35 * 1. Redistributions of source code must retain the above copyright
36 * notice, this list of conditions and the following disclaimer.
37 * 2. Redistributions in binary form must reproduce the above copyright
38 * notice, this list of conditions and the following disclaimer in the
39 * documentation and/or other materials provided with the distribution.
40 * 3. Neither the name of the project nor the names of its contributors
41 * may be used to endorse or promote products derived from this software
42 * without specific prior written permission.
43 *
44 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
45 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
48 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54 * SUCH DAMAGE.
55 *
56 */
57
58 /*
59 * Copyright (c) 1982, 1986, 1991, 1993
60 * The Regents of the University of California. All rights reserved.
61 *
62 * Redistribution and use in source and binary forms, with or without
63 * modification, are permitted provided that the following conditions
64 * are met:
65 * 1. Redistributions of source code must retain the above copyright
66 * notice, this list of conditions and the following disclaimer.
67 * 2. Redistributions in binary form must reproduce the above copyright
68 * notice, this list of conditions and the following disclaimer in the
69 * documentation and/or other materials provided with the distribution.
70 * 3. All advertising materials mentioning features or use of this software
71 * must display the following acknowledgement:
72 * This product includes software developed by the University of
73 * California, Berkeley and its contributors.
74 * 4. Neither the name of the University nor the names of its contributors
75 * may be used to endorse or promote products derived from this software
76 * without specific prior written permission.
77 *
78 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
79 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
80 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
81 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
82 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
83 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
84 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
85 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
86 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
87 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
88 * SUCH DAMAGE.
89 *
90 * @(#)in_pcb.c 8.2 (Berkeley) 1/4/94
91 */
92
93 #include <sys/param.h>
94 #include <sys/systm.h>
95 #include <sys/malloc.h>
96 #include <sys/mbuf.h>
97 #include <sys/domain.h>
98 #include <sys/protosw.h>
99 #include <sys/socket.h>
100 #include <sys/socketvar.h>
101 #include <sys/sockio.h>
102 #include <sys/errno.h>
103 #include <sys/time.h>
104 #include <sys/proc.h>
105 #include <sys/kauth.h>
106 #include <sys/priv.h>
107
108 #include <net/if.h>
109 #include <net/if_types.h>
110 #include <net/route.h>
111
112 #include <netinet/in.h>
113 #include <netinet/in_var.h>
114 #include <netinet/in_systm.h>
115 #include <netinet/ip6.h>
116 #include <netinet/ip_var.h>
117 #include <netinet6/ip6_var.h>
118 #include <netinet6/nd6.h>
119 #include <netinet/in_pcb.h>
120 #include <netinet6/in6_pcb.h>
121 #include <net/if_types.h>
122
123 #include <kern/kern_types.h>
124 #include <kern/zalloc.h>
125
126 #if IPSEC
127 #include <netinet6/ipsec.h>
128 #if INET6
129 #include <netinet6/ipsec6.h>
130 #endif
131 #include <netinet6/ah.h>
132 #if INET6
133 #include <netinet6/ah6.h>
134 #endif
135 #include <netkey/key.h>
136 #endif /* IPSEC */
137
138 struct in6_addr zeroin6_addr;
139
140 /*
141 in6_pcblookup_local_and_cleanup does everything
142 in6_pcblookup_local does but it checks for a socket
143 that's going away. Since we know that the lock is
144 held read+write when this function is called, we
145 can safely dispose of this socket like the slow
146 timer would usually do and return NULL. This is
147 great for bind.
148 */
149 static struct inpcb*
150 in6_pcblookup_local_and_cleanup(
151 struct inpcbinfo *pcbinfo,
152 struct in6_addr *laddr,
153 u_int lport_arg,
154 int wild_okay)
155 {
156 struct inpcb *inp;
157
158 /* Perform normal lookup */
159 inp = in6_pcblookup_local(pcbinfo, laddr, lport_arg, wild_okay);
160
161 /* Check if we found a match but it's waiting to be disposed */
162 if (inp && inp->inp_wantcnt == WNT_STOPUSING) {
163 struct socket *so = inp->inp_socket;
164
165 lck_mtx_lock(&inp->inpcb_mtx);
166
167 if (so->so_usecount == 0) {
168 if (inp->inp_state != INPCB_STATE_DEAD)
169 in6_pcbdetach(inp);
170 in_pcbdispose(inp);
171 inp = NULL;
172 }
173 else {
174 lck_mtx_unlock(&inp->inpcb_mtx);
175 }
176 }
177
178 return inp;
179 }
180
181 int
182 in6_pcbbind(struct inpcb *inp, struct sockaddr *nam, struct proc *p)
183 {
184 struct socket *so = inp->inp_socket;
185 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)NULL;
186 struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
187 u_short lport = 0;
188 int wild = 0, reuseport = (so->so_options & SO_REUSEPORT);
189 int error;
190 kauth_cred_t cred;
191
192 if (!in6_ifaddrs) /* XXX broken! */
193 return (EADDRNOTAVAIL);
194 if (inp->inp_lport || !IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
195 return(EINVAL);
196 if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0)
197 wild = 1;
198 socket_unlock(so, 0); /* keep reference */
199 lck_rw_lock_exclusive(pcbinfo->mtx);
200 if (nam) {
201 unsigned int outif = 0;
202
203 sin6 = (struct sockaddr_in6 *)nam;
204 if (nam->sa_len != sizeof(*sin6)) {
205 lck_rw_done(pcbinfo->mtx);
206 socket_lock(so, 0);
207 return(EINVAL);
208 }
209 /*
210 * family check.
211 */
212 if (nam->sa_family != AF_INET6) {
213 lck_rw_done(pcbinfo->mtx);
214 socket_lock(so, 0);
215 return(EAFNOSUPPORT);
216 }
217
218 /* KAME hack: embed scopeid */
219 if (in6_embedscope(&sin6->sin6_addr, sin6, inp, NULL,
220 NULL) != 0) {
221 lck_rw_done(pcbinfo->mtx);
222 socket_lock(so, 0);
223 return EINVAL;
224 }
225 /* this must be cleared for ifa_ifwithaddr() */
226 sin6->sin6_scope_id = 0;
227
228 lport = sin6->sin6_port;
229 if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
230 /*
231 * Treat SO_REUSEADDR as SO_REUSEPORT for multicast;
232 * allow compepte duplication of binding if
233 * SO_REUSEPORT is set, or if SO_REUSEADDR is set
234 * and a multicast address is bound on both
235 * new and duplicated sockets.
236 */
237 if (so->so_options & SO_REUSEADDR)
238 reuseport = SO_REUSEADDR|SO_REUSEPORT;
239 } else if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
240 struct ifaddr *ifa;
241
242 sin6->sin6_port = 0; /* yech... */
243 if ((ifa = ifa_ifwithaddr((struct sockaddr *)sin6)) == 0) {
244 lck_rw_done(pcbinfo->mtx);
245 socket_lock(so, 0);
246 return(EADDRNOTAVAIL);
247 }
248
249 /*
250 * XXX: bind to an anycast address might accidentally
251 * cause sending a packet with anycast source address.
252 * We should allow to bind to a deprecated address, since
253 * the application dare to use it.
254 */
255 if (ifa != NULL) {
256 IFA_LOCK_SPIN(ifa);
257 if (((struct in6_ifaddr *)ifa)->ia6_flags &
258 (IN6_IFF_ANYCAST|IN6_IFF_NOTREADY|IN6_IFF_DETACHED)) {
259 IFA_UNLOCK(ifa);
260 IFA_REMREF(ifa);
261 lck_rw_done(pcbinfo->mtx);
262 socket_lock(so, 0);
263 return(EADDRNOTAVAIL);
264 }
265 outif = ifa->ifa_ifp->if_index;
266 IFA_UNLOCK(ifa);
267 IFA_REMREF(ifa);
268 }
269 }
270 if (lport) {
271 struct inpcb *t;
272
273 /* GROSS */
274 if (ntohs(lport) < IPV6PORT_RESERVED) {
275 cred = kauth_cred_proc_ref(p);
276 error = priv_check_cred(cred, PRIV_NETINET_RESERVEDPORT, 0);
277 kauth_cred_unref(&cred);
278 if (error != 0) {
279 lck_rw_done(pcbinfo->mtx);
280 socket_lock(so, 0);
281 return(EACCES);
282 }
283 }
284
285 if (so->so_uid &&
286 !IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
287 t = in6_pcblookup_local_and_cleanup(pcbinfo,
288 &sin6->sin6_addr, lport,
289 INPLOOKUP_WILDCARD);
290 if (t &&
291 (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) ||
292 !IN6_IS_ADDR_UNSPECIFIED(&t->in6p_laddr) ||
293 (t->inp_socket->so_options &
294 SO_REUSEPORT) == 0) &&
295 (so->so_uid != t->inp_socket->so_uid) &&
296 ((t->inp_socket->so_flags & SOF_REUSESHAREUID) == 0)) {
297 lck_rw_done(pcbinfo->mtx);
298 socket_lock(so, 0);
299 return (EADDRINUSE);
300 }
301 if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0 &&
302 IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
303 struct sockaddr_in sin;
304
305 in6_sin6_2_sin(&sin, sin6);
306 t = in_pcblookup_local_and_cleanup(pcbinfo,
307 sin.sin_addr, lport,
308 INPLOOKUP_WILDCARD);
309 if (t && (t->inp_socket->so_options & SO_REUSEPORT) == 0 &&
310 (so->so_uid !=
311 t->inp_socket->so_uid) &&
312 (ntohl(t->inp_laddr.s_addr) !=
313 INADDR_ANY ||
314 INP_SOCKAF(so) ==
315 INP_SOCKAF(t->inp_socket))) {
316
317 lck_rw_done(pcbinfo->mtx);
318 socket_lock(so, 0);
319 return (EADDRINUSE);
320 }
321 }
322 }
323 t = in6_pcblookup_local_and_cleanup(pcbinfo, &sin6->sin6_addr,
324 lport, wild);
325 if (t && (reuseport & t->inp_socket->so_options) == 0) {
326 lck_rw_done(pcbinfo->mtx);
327 socket_lock(so, 0);
328 return(EADDRINUSE);
329 }
330 if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0 &&
331 IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
332 struct sockaddr_in sin;
333
334 in6_sin6_2_sin(&sin, sin6);
335 t = in_pcblookup_local_and_cleanup(pcbinfo, sin.sin_addr,
336 lport, wild);
337 if (t &&
338 (reuseport & t->inp_socket->so_options)
339 == 0 &&
340 (ntohl(t->inp_laddr.s_addr)
341 != INADDR_ANY ||
342 INP_SOCKAF(so) ==
343 INP_SOCKAF(t->inp_socket))) {
344 lck_rw_done(pcbinfo->mtx);
345 socket_lock(so, 0);
346 return (EADDRINUSE);
347 }
348 }
349 }
350 inp->in6p_laddr = sin6->sin6_addr;
351 inp->in6p_last_outif = outif;
352 }
353 socket_lock(so, 0);
354 if (lport == 0) {
355 int e;
356 if ((e = in6_pcbsetport(&inp->in6p_laddr, inp, p, 1)) != 0) {
357 lck_rw_done(pcbinfo->mtx);
358 return(e);
359 }
360 }
361 else {
362 inp->inp_lport = lport;
363 if (in_pcbinshash(inp, 1) != 0) {
364 inp->in6p_laddr = in6addr_any;
365 inp->inp_lport = 0;
366 inp->in6p_last_outif = 0;
367 lck_rw_done(pcbinfo->mtx);
368 return (EAGAIN);
369 }
370 }
371 lck_rw_done(pcbinfo->mtx);
372 sflt_notify(so, sock_evt_bound, NULL);
373 return(0);
374 }
375
376 /*
377 * Transform old in6_pcbconnect() into an inner subroutine for new
378 * in6_pcbconnect(): Do some validity-checking on the remote
379 * address (in mbuf 'nam') and then determine local host address
380 * (i.e., which interface) to use to access that remote host.
381 *
382 * This preserves definition of in6_pcbconnect(), while supporting a
383 * slightly different version for T/TCP. (This is more than
384 * a bit of a kludge, but cleaning up the internal interfaces would
385 * have forced minor changes in every protocol).
386 */
387
388 int
389 in6_pcbladdr(struct inpcb *inp, struct sockaddr *nam,
390 struct in6_addr *plocal_addr6, unsigned int *poutif)
391 {
392 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)nam;
393 struct in6_addr *addr6 = NULL;
394 struct in6_addr src_storage;
395 int error = 0;
396 unsigned int ifscope;
397
398 if (nam->sa_len != sizeof (*sin6))
399 return (EINVAL);
400 if (sin6->sin6_family != AF_INET6)
401 return (EAFNOSUPPORT);
402 if (sin6->sin6_port == 0)
403 return (EADDRNOTAVAIL);
404
405 /* KAME hack: embed scopeid */
406 if (in6_embedscope(&sin6->sin6_addr, sin6, inp, NULL, NULL) != 0)
407 return EINVAL;
408
409 if (in6_ifaddrs) {
410 /*
411 * If the destination address is UNSPECIFIED addr,
412 * use the loopback addr, e.g ::1.
413 */
414 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
415 sin6->sin6_addr = in6addr_loopback;
416 }
417
418 ifscope = (inp->inp_flags & INP_BOUND_IF) ?
419 inp->inp_boundif : IFSCOPE_NONE;
420
421 /*
422 * XXX: in6_selectsrc might replace the bound local address
423 * with the address specified by setsockopt(IPV6_PKTINFO).
424 * Is it the intended behavior?
425 */
426 addr6 = in6_selectsrc(sin6, inp->in6p_outputopts, inp,
427 &inp->in6p_route, NULL, &src_storage, ifscope, &error);
428 if (addr6 == 0) {
429 if (error == 0)
430 error = EADDRNOTAVAIL;
431 return(error);
432 }
433
434 if (poutif != NULL) {
435 struct rtentry *rt;
436 if ((rt = inp->in6p_route.ro_rt) != NULL)
437 *poutif = rt->rt_ifp->if_index;
438 else
439 *poutif = 0;
440 }
441
442 *plocal_addr6 = *addr6;
443 /*
444 * Don't do pcblookup call here; return interface in
445 * plocal_addr6
446 * and exit to caller, that will do the lookup.
447 */
448 return(0);
449 }
450
451 /*
452 * Outer subroutine:
453 * Connect from a socket to a specified address.
454 * Both address and port must be specified in argument sin.
455 * If don't have a local address for this socket yet,
456 * then pick one.
457 */
458 int
459 in6_pcbconnect(
460 struct inpcb *inp,
461 struct sockaddr *nam,
462 struct proc *p)
463 {
464 struct in6_addr addr6;
465 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)nam;
466 struct inpcb *pcb;
467 int error;
468 unsigned int outif = 0;
469
470 /*
471 * Call inner routine, to assign local interface address.
472 * in6_pcbladdr() may automatically fill in sin6_scope_id.
473 */
474 if ((error = in6_pcbladdr(inp, nam, &addr6, &outif)) != 0)
475 return(error);
476 socket_unlock(inp->inp_socket, 0);
477 pcb = in6_pcblookup_hash(inp->inp_pcbinfo, &sin6->sin6_addr,
478 sin6->sin6_port,
479 IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)
480 ? &addr6 : &inp->in6p_laddr,
481 inp->inp_lport, 0, NULL);
482 socket_lock(inp->inp_socket, 0);
483 if (pcb != NULL) {
484 in_pcb_checkstate(pcb, WNT_RELEASE, pcb == inp ? 1 : 0);
485 return (EADDRINUSE);
486 }
487 if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) {
488 if (inp->inp_lport == 0) {
489 error = in6_pcbbind(inp, (struct sockaddr *)0, p);
490 if (error)
491 return (error);
492 }
493 inp->in6p_laddr = addr6;
494 inp->in6p_last_outif = outif;
495 }
496 if (!lck_rw_try_lock_exclusive(inp->inp_pcbinfo->mtx)) {
497 /*lock inversion issue, mostly with udp multicast packets */
498 socket_unlock(inp->inp_socket, 0);
499 lck_rw_lock_exclusive(inp->inp_pcbinfo->mtx);
500 socket_lock(inp->inp_socket, 0);
501 }
502 inp->in6p_faddr = sin6->sin6_addr;
503 inp->inp_fport = sin6->sin6_port;
504 /* update flowinfo - draft-itojun-ipv6-flowlabel-api-00 */
505 inp->in6p_flowinfo &= ~IPV6_FLOWLABEL_MASK;
506 if (inp->in6p_flags & IN6P_AUTOFLOWLABEL)
507 inp->in6p_flowinfo |=
508 (htonl(ip6_flow_seq++) & IPV6_FLOWLABEL_MASK);
509
510 in_pcbrehash(inp);
511 lck_rw_done(inp->inp_pcbinfo->mtx);
512 return (0);
513 }
514
515 void
516 in6_pcbdisconnect(
517 struct inpcb *inp)
518 {
519 if (!lck_rw_try_lock_exclusive(inp->inp_pcbinfo->mtx)) {
520 /*lock inversion issue, mostly with udp multicast packets */
521 socket_unlock(inp->inp_socket, 0);
522 lck_rw_lock_exclusive(inp->inp_pcbinfo->mtx);
523 socket_lock(inp->inp_socket, 0);
524 }
525 bzero((caddr_t)&inp->in6p_faddr, sizeof(inp->in6p_faddr));
526 inp->inp_fport = 0;
527 /* clear flowinfo - draft-itojun-ipv6-flowlabel-api-00 */
528 inp->in6p_flowinfo &= ~IPV6_FLOWLABEL_MASK;
529 in_pcbrehash(inp);
530 lck_rw_done(inp->inp_pcbinfo->mtx);
531 if (inp->inp_socket->so_state & SS_NOFDREF)
532 in6_pcbdetach(inp);
533 }
534
535 void
536 in6_pcbdetach(
537 struct inpcb *inp)
538 {
539 struct socket *so = inp->inp_socket;
540 struct inpcbinfo *ipi = inp->inp_pcbinfo;
541
542 #if IPSEC
543 if (inp->in6p_sp != NULL) {
544 ipsec6_delete_pcbpolicy(inp);
545 }
546 #endif /* IPSEC */
547
548 if (in_pcb_checkstate(inp, WNT_STOPUSING, 1) != WNT_STOPUSING)
549 printf("in6_pcbdetach so=%p can't be marked dead ok\n", so);
550
551 inp->inp_state = INPCB_STATE_DEAD;
552
553 if ((so->so_flags & SOF_PCBCLEARING) == 0) {
554 struct ip_moptions *imo;
555 struct ip6_moptions *im6o;
556
557 inp->inp_vflag = 0;
558 so->so_flags |= SOF_PCBCLEARING;
559 inp->inp_gencnt = ++ipi->ipi_gencnt;
560 if (inp->in6p_options)
561 m_freem(inp->in6p_options);
562 ip6_freepcbopts(inp->in6p_outputopts);
563 if (inp->in6p_route.ro_rt) {
564 rtfree(inp->in6p_route.ro_rt);
565 inp->in6p_route.ro_rt = NULL;
566 }
567 /* Check and free IPv4 related resources in case of mapped addr */
568 if (inp->inp_options)
569 (void)m_free(inp->inp_options);
570
571 im6o = inp->in6p_moptions;
572 inp->in6p_moptions = NULL;
573 if (im6o != NULL)
574 IM6O_REMREF(im6o);
575
576 imo = inp->inp_moptions;
577 inp->inp_moptions = NULL;
578 if (imo != NULL)
579 IMO_REMREF(imo);
580 }
581 }
582
583 struct sockaddr *
584 in6_sockaddr(
585 in_port_t port,
586 struct in6_addr *addr_p)
587 {
588 struct sockaddr_in6 *sin6;
589
590 MALLOC(sin6, struct sockaddr_in6 *, sizeof *sin6, M_SONAME, M_WAITOK);
591 if (sin6 == NULL)
592 return NULL;
593 bzero(sin6, sizeof *sin6);
594 sin6->sin6_family = AF_INET6;
595 sin6->sin6_len = sizeof(*sin6);
596 sin6->sin6_port = port;
597 sin6->sin6_addr = *addr_p;
598 if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr))
599 sin6->sin6_scope_id = ntohs(sin6->sin6_addr.s6_addr16[1]);
600 else
601 sin6->sin6_scope_id = 0; /*XXX*/
602 if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr))
603 sin6->sin6_addr.s6_addr16[1] = 0;
604
605 return (struct sockaddr *)sin6;
606 }
607
608 struct sockaddr *
609 in6_v4mapsin6_sockaddr(
610 in_port_t port,
611 struct in_addr *addr_p)
612 {
613 struct sockaddr_in sin;
614 struct sockaddr_in6 *sin6_p;
615
616 bzero(&sin, sizeof sin);
617 sin.sin_family = AF_INET;
618 sin.sin_len = sizeof(sin);
619 sin.sin_port = port;
620 sin.sin_addr = *addr_p;
621
622 MALLOC(sin6_p, struct sockaddr_in6 *, sizeof *sin6_p, M_SONAME,
623 M_WAITOK);
624 if (sin6_p == NULL)
625 return NULL;
626 in6_sin_2_v4mapsin6(&sin, sin6_p);
627
628 return (struct sockaddr *)sin6_p;
629 }
630
631 /*
632 * The calling convention of in6_setsockaddr() and in6_setpeeraddr() was
633 * modified to match the pru_sockaddr() and pru_peeraddr() entry points
634 * in struct pr_usrreqs, so that protocols can just reference then directly
635 * without the need for a wrapper function. The socket must have a valid
636 * (i.e., non-nil) PCB, but it should be impossible to get an invalid one
637 * except through a kernel programming error, so it is acceptable to panic
638 * (or in this case trap) if the PCB is invalid. (Actually, we don't trap
639 * because there actually /is/ a programming error somewhere... XXX)
640 */
641 int
642 in6_setsockaddr(
643 struct socket *so,
644 struct sockaddr **nam)
645 {
646 struct inpcb *inp;
647 struct in6_addr addr;
648 in_port_t port;
649
650 inp = sotoinpcb(so);
651 if (!inp) {
652 return EINVAL;
653 }
654 port = inp->inp_lport;
655 addr = inp->in6p_laddr;
656
657 *nam = in6_sockaddr(port, &addr);
658 if (*nam == NULL)
659 return ENOBUFS;
660 return 0;
661 }
662
663 int
664 in6_setpeeraddr(
665 struct socket *so,
666 struct sockaddr **nam)
667 {
668 struct inpcb *inp;
669 struct in6_addr addr;
670 in_port_t port;
671
672 inp = sotoinpcb(so);
673 if (!inp) {
674 return EINVAL;
675 }
676 port = inp->inp_fport;
677 addr = inp->in6p_faddr;
678
679 *nam = in6_sockaddr(port, &addr);
680 if (*nam == NULL)
681 return ENOBUFS;
682 return 0;
683 }
684
685 int
686 in6_mapped_sockaddr(struct socket *so, struct sockaddr **nam)
687 {
688 struct inpcb *inp = sotoinpcb(so);
689 int error;
690
691 if (inp == NULL)
692 return EINVAL;
693 if (inp->inp_vflag & INP_IPV4) {
694 error = in_setsockaddr(so, nam);
695 if (error == 0)
696 error = in6_sin_2_v4mapsin6_in_sock(nam);
697 } else {
698 /* scope issues will be handled in in6_setsockaddr(). */
699 error = in6_setsockaddr(so, nam);
700 }
701 return error;
702 }
703
704 int
705 in6_mapped_peeraddr(struct socket *so, struct sockaddr **nam)
706 {
707 struct inpcb *inp = sotoinpcb(so);
708 int error;
709
710 if (inp == NULL)
711 return EINVAL;
712 if (inp->inp_vflag & INP_IPV4) {
713 error = in_setpeeraddr(so, nam);
714 if (error == 0)
715 error = in6_sin_2_v4mapsin6_in_sock(nam);
716 } else {
717 /* scope issues will be handled in in6_setpeeraddr(). */
718 error = in6_setpeeraddr(so, nam);
719 }
720 return error;
721 }
722
723 /*
724 * Pass some notification to all connections of a protocol
725 * associated with address dst. The local address and/or port numbers
726 * may be specified to limit the search. The "usual action" will be
727 * taken, depending on the ctlinput cmd. The caller must filter any
728 * cmds that are uninteresting (e.g., no error in the map).
729 * Call the protocol specific routine (if any) to report
730 * any errors for each matching socket.
731 */
732 void
733 in6_pcbnotify(pcbinfo, dst, fport_arg, src, lport_arg, cmd, cmdarg, notify)
734 struct inpcbinfo *pcbinfo;
735 struct sockaddr *dst;
736 const struct sockaddr *src;
737 u_int fport_arg, lport_arg;
738 int cmd;
739 void *cmdarg;
740 void (*notify)(struct inpcb *, int);
741 {
742 struct inpcb *inp, *ninp;
743 struct sockaddr_in6 sa6_src, *sa6_dst;
744 u_short fport = fport_arg, lport = lport_arg;
745 u_int32_t flowinfo;
746 int errno;
747 struct inpcbhead *head = pcbinfo->listhead;
748
749 if ((unsigned)cmd > PRC_NCMDS || dst->sa_family != AF_INET6)
750 return;
751
752 sa6_dst = (struct sockaddr_in6 *)dst;
753 if (IN6_IS_ADDR_UNSPECIFIED(&sa6_dst->sin6_addr))
754 return;
755
756 /*
757 * note that src can be NULL when we get notify by local fragmentation.
758 */
759 sa6_src = (src == NULL) ? sa6_any : *(const struct sockaddr_in6 *)src;
760 flowinfo = sa6_src.sin6_flowinfo;
761
762 /*
763 * Redirects go to all references to the destination,
764 * and use in6_rtchange to invalidate the route cache.
765 * Dead host indications: also use in6_rtchange to invalidate
766 * the cache, and deliver the error to all the sockets.
767 * Otherwise, if we have knowledge of the local port and address,
768 * deliver only to that socket.
769 */
770 if (PRC_IS_REDIRECT(cmd) || cmd == PRC_HOSTDEAD) {
771 fport = 0;
772 lport = 0;
773 bzero((caddr_t)&sa6_src.sin6_addr, sizeof(sa6_src.sin6_addr));
774
775 if (cmd != PRC_HOSTDEAD)
776 notify = in6_rtchange;
777 }
778 errno = inet6ctlerrmap[cmd];
779 lck_rw_lock_shared(pcbinfo->mtx);
780 for (inp = LIST_FIRST(head); inp != NULL; inp = ninp) {
781 ninp = LIST_NEXT(inp, inp_list);
782
783 if ((inp->inp_vflag & INP_IPV6) == 0)
784 continue;
785
786 /*
787 * If the error designates a new path MTU for a destination
788 * and the application (associated with this socket) wanted to
789 * know the value, notify. Note that we notify for all
790 * disconnected sockets if the corresponding application
791 * wanted. This is because some UDP applications keep sending
792 * sockets disconnected.
793 * XXX: should we avoid to notify the value to TCP sockets?
794 */
795 if (cmd == PRC_MSGSIZE && (inp->inp_flags & IN6P_MTU) != 0 &&
796 (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr) ||
797 IN6_ARE_ADDR_EQUAL(&inp->in6p_faddr, &sa6_dst->sin6_addr))) {
798 ip6_notify_pmtu(inp, (struct sockaddr_in6 *)dst,
799 (u_int32_t *)cmdarg);
800 }
801
802 /*
803 * Detect if we should notify the error. If no source and
804 * destination ports are specifed, but non-zero flowinfo and
805 * local address match, notify the error. This is the case
806 * when the error is delivered with an encrypted buffer
807 * by ESP. Otherwise, just compare addresses and ports
808 * as usual.
809 */
810 if (lport == 0 && fport == 0 && flowinfo &&
811 inp->inp_socket != NULL &&
812 flowinfo == (inp->in6p_flowinfo & IPV6_FLOWLABEL_MASK) &&
813 IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, &sa6_src.sin6_addr))
814 goto do_notify;
815 else if (!IN6_ARE_ADDR_EQUAL(&inp->in6p_faddr,
816 &sa6_dst->sin6_addr) ||
817 inp->inp_socket == 0 ||
818 (lport && inp->inp_lport != lport) ||
819 (!IN6_IS_ADDR_UNSPECIFIED(&sa6_src.sin6_addr) &&
820 !IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr,
821 &sa6_src.sin6_addr)) ||
822 (fport && inp->inp_fport != fport))
823 continue;
824
825
826 do_notify:
827 if (notify) {
828 if (in_pcb_checkstate(inp, WNT_ACQUIRE, 0) == WNT_STOPUSING)
829 continue;
830 socket_lock(inp->inp_socket, 1);
831 (*notify)(inp, errno);
832 (void)in_pcb_checkstate(inp, WNT_RELEASE, 1);
833 socket_unlock(inp->inp_socket, 1);
834 }
835 }
836 lck_rw_done(pcbinfo->mtx);
837 }
838
839 /*
840 * Lookup a PCB based on the local address and port.
841 */
842 struct inpcb *
843 in6_pcblookup_local(
844 struct inpcbinfo *pcbinfo,
845 struct in6_addr *laddr,
846 u_int lport_arg,
847 int wild_okay)
848 {
849 struct inpcb *inp;
850 int matchwild = 3, wildcard;
851 u_short lport = lport_arg;
852
853 if (!wild_okay) {
854 struct inpcbhead *head;
855 /*
856 * Look for an unconnected (wildcard foreign addr) PCB that
857 * matches the local address and port we're looking for.
858 */
859 head = &pcbinfo->hashbase[INP_PCBHASH(INADDR_ANY, lport, 0,
860 pcbinfo->hashmask)];
861 LIST_FOREACH(inp, head, inp_hash) {
862 if ((inp->inp_vflag & INP_IPV6) == 0)
863 continue;
864 if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr) &&
865 IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, laddr) &&
866 inp->inp_lport == lport) {
867 /*
868 * Found.
869 */
870 return (inp);
871 }
872 }
873 /*
874 * Not found.
875 */
876 return (NULL);
877 } else {
878 struct inpcbporthead *porthash;
879 struct inpcbport *phd;
880 struct inpcb *match = NULL;
881 /*
882 * Best fit PCB lookup.
883 *
884 * First see if this local port is in use by looking on the
885 * port hash list.
886 */
887 porthash = &pcbinfo->porthashbase[INP_PCBPORTHASH(lport,
888 pcbinfo->porthashmask)];
889 LIST_FOREACH(phd, porthash, phd_hash) {
890 if (phd->phd_port == lport)
891 break;
892 }
893 if (phd != NULL) {
894 /*
895 * Port is in use by one or more PCBs. Look for best
896 * fit.
897 */
898 LIST_FOREACH(inp, &phd->phd_pcblist, inp_portlist) {
899 wildcard = 0;
900 if ((inp->inp_vflag & INP_IPV6) == 0)
901 continue;
902 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr))
903 wildcard++;
904 if (!IN6_IS_ADDR_UNSPECIFIED(
905 &inp->in6p_laddr)) {
906 if (IN6_IS_ADDR_UNSPECIFIED(laddr))
907 wildcard++;
908 else if (!IN6_ARE_ADDR_EQUAL(
909 &inp->in6p_laddr, laddr))
910 continue;
911 } else {
912 if (!IN6_IS_ADDR_UNSPECIFIED(laddr))
913 wildcard++;
914 }
915 if (wildcard < matchwild) {
916 match = inp;
917 matchwild = wildcard;
918 if (matchwild == 0) {
919 break;
920 }
921 }
922 }
923 }
924 return (match);
925 }
926 }
927
928 /*
929 * Check for alternatives when higher level complains
930 * about service problems. For now, invalidate cached
931 * routing information. If the route was created dynamically
932 * (by a redirect), time to try a default gateway again.
933 */
934 void
935 in6_losing(
936 struct inpcb *in6p)
937 {
938 struct rtentry *rt;
939 struct rt_addrinfo info;
940
941 if ((rt = in6p->in6p_route.ro_rt) != NULL) {
942 in6p->in6p_route.ro_rt = NULL;
943 RT_LOCK(rt);
944 bzero((caddr_t)&info, sizeof(info));
945 info.rti_info[RTAX_DST] =
946 (struct sockaddr *)&in6p->in6p_route.ro_dst;
947 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
948 info.rti_info[RTAX_NETMASK] = rt_mask(rt);
949 rt_missmsg(RTM_LOSING, &info, rt->rt_flags, 0);
950 if (rt->rt_flags & RTF_DYNAMIC) {
951 /*
952 * Prevent another thread from modifying rt_key,
953 * rt_gateway via rt_setgate() after the rt_lock
954 * is dropped by marking the route as defunct.
955 */
956 rt->rt_flags |= RTF_CONDEMNED;
957 RT_UNLOCK(rt);
958 (void) rtrequest(RTM_DELETE, rt_key(rt),
959 rt->rt_gateway, rt_mask(rt), rt->rt_flags, NULL);
960 } else {
961 RT_UNLOCK(rt);
962 }
963 /*
964 * A new route can be allocated
965 * the next time output is attempted.
966 */
967 rtfree(rt);
968 }
969 }
970
971 /*
972 * After a routing change, flush old routing
973 * and allocate a (hopefully) better one.
974 */
975 void
976 in6_rtchange(
977 struct inpcb *inp,
978 __unused int errno)
979 {
980 if (inp->in6p_route.ro_rt) {
981 rtfree(inp->in6p_route.ro_rt);
982 inp->in6p_route.ro_rt = 0;
983 /*
984 * A new route can be allocated the next time
985 * output is attempted.
986 */
987 }
988 }
989
990 /*
991 * Check if PCB exists hash list. Also returns uid and gid of socket
992 */
993 int
994 in6_pcblookup_hash_exists(
995 struct inpcbinfo *pcbinfo,
996 struct in6_addr *faddr,
997 u_int fport_arg,
998 struct in6_addr *laddr,
999 u_int lport_arg,
1000 int wildcard,
1001 uid_t *uid,
1002 gid_t *gid,
1003 __unused struct ifnet *ifp)
1004 {
1005 struct inpcbhead *head;
1006 struct inpcb *inp;
1007 u_short fport = fport_arg, lport = lport_arg;
1008 int faith;
1009 int found;
1010
1011 #if defined(NFAITH) && NFAITH > 0
1012 faith = faithprefix(laddr);
1013 #else
1014 faith = 0;
1015 #endif
1016
1017 *uid = UID_MAX;
1018 *gid = GID_MAX;
1019
1020 lck_rw_lock_shared(pcbinfo->mtx);
1021
1022 /*
1023 * First look for an exact match.
1024 */
1025 head = &pcbinfo->hashbase[INP_PCBHASH(faddr->s6_addr32[3] /* XXX */,
1026 lport, fport,
1027 pcbinfo->hashmask)];
1028 LIST_FOREACH(inp, head, inp_hash) {
1029 if ((inp->inp_vflag & INP_IPV6) == 0)
1030 continue;
1031 if (IN6_ARE_ADDR_EQUAL(&inp->in6p_faddr, faddr) &&
1032 IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, laddr) &&
1033 inp->inp_fport == fport &&
1034 inp->inp_lport == lport) {
1035 if ((found = (inp->inp_socket != NULL))) {
1036 /*
1037 * Found. Check if pcb is still valid
1038 */
1039 *uid = inp->inp_socket->so_uid;
1040 *gid = inp->inp_socket->so_gid;
1041 }
1042 lck_rw_done(pcbinfo->mtx);
1043 return (found);
1044 }
1045 }
1046 if (wildcard) {
1047 struct inpcb *local_wild = NULL;
1048
1049 head = &pcbinfo->hashbase[INP_PCBHASH(INADDR_ANY, lport, 0,
1050 pcbinfo->hashmask)];
1051 LIST_FOREACH(inp, head, inp_hash) {
1052 if ((inp->inp_vflag & INP_IPV6) == 0)
1053 continue;
1054 if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr) &&
1055 inp->inp_lport == lport) {
1056 if (faith && (inp->inp_flags & INP_FAITH) == 0)
1057 continue;
1058 if (IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr,
1059 laddr)) {
1060 if ((found = (inp->inp_socket != NULL))) {
1061 *uid = inp->inp_socket->so_uid;
1062 *gid = inp->inp_socket->so_gid;
1063 }
1064 lck_rw_done(pcbinfo->mtx);
1065 return (found);
1066 }
1067 else if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
1068 local_wild = inp;
1069 }
1070 }
1071 if (local_wild) {
1072 if ((found = (local_wild->inp_socket != NULL))) {
1073 *uid = local_wild->inp_socket->so_uid;
1074 *gid = local_wild->inp_socket->so_gid;
1075 }
1076 lck_rw_done(pcbinfo->mtx);
1077 return (found);
1078 }
1079 }
1080
1081 /*
1082 * Not found.
1083 */
1084 lck_rw_done(pcbinfo->mtx);
1085 return (0);
1086 }
1087
1088 /*
1089 * Lookup PCB in hash list.
1090 */
1091 struct inpcb *
1092 in6_pcblookup_hash(
1093 struct inpcbinfo *pcbinfo,
1094 struct in6_addr *faddr,
1095 u_int fport_arg,
1096 struct in6_addr *laddr,
1097 u_int lport_arg,
1098 int wildcard,
1099 __unused struct ifnet *ifp)
1100 {
1101 struct inpcbhead *head;
1102 struct inpcb *inp;
1103 u_short fport = fport_arg, lport = lport_arg;
1104 int faith;
1105
1106 #if defined(NFAITH) && NFAITH > 0
1107 faith = faithprefix(laddr);
1108 #else
1109 faith = 0;
1110 #endif
1111
1112 lck_rw_lock_shared(pcbinfo->mtx);
1113
1114 /*
1115 * First look for an exact match.
1116 */
1117 head = &pcbinfo->hashbase[INP_PCBHASH(faddr->s6_addr32[3] /* XXX */,
1118 lport, fport,
1119 pcbinfo->hashmask)];
1120 LIST_FOREACH(inp, head, inp_hash) {
1121 if ((inp->inp_vflag & INP_IPV6) == 0)
1122 continue;
1123 if (IN6_ARE_ADDR_EQUAL(&inp->in6p_faddr, faddr) &&
1124 IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, laddr) &&
1125 inp->inp_fport == fport &&
1126 inp->inp_lport == lport) {
1127 /*
1128 * Found. Check if pcb is still valid
1129 */
1130 if (in_pcb_checkstate(inp, WNT_ACQUIRE, 0) != WNT_STOPUSING) {
1131 lck_rw_done(pcbinfo->mtx);
1132 return (inp);
1133 }
1134 else { /* it's there but dead, say it isn't found */
1135 lck_rw_done(pcbinfo->mtx);
1136 return(NULL);
1137 }
1138 }
1139 }
1140 if (wildcard) {
1141 struct inpcb *local_wild = NULL;
1142
1143 head = &pcbinfo->hashbase[INP_PCBHASH(INADDR_ANY, lport, 0,
1144 pcbinfo->hashmask)];
1145 LIST_FOREACH(inp, head, inp_hash) {
1146 if ((inp->inp_vflag & INP_IPV6) == 0)
1147 continue;
1148 if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr) &&
1149 inp->inp_lport == lport) {
1150 if (faith && (inp->inp_flags & INP_FAITH) == 0)
1151 continue;
1152 if (IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr,
1153 laddr)) {
1154 if (in_pcb_checkstate(inp, WNT_ACQUIRE, 0) != WNT_STOPUSING) {
1155 lck_rw_done(pcbinfo->mtx);
1156 return (inp);
1157 }
1158 else { /* it's there but dead, say it isn't found */
1159 lck_rw_done(pcbinfo->mtx);
1160 return(NULL);
1161 }
1162 }
1163 else if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
1164 local_wild = inp;
1165 }
1166 }
1167 if (local_wild && in_pcb_checkstate(local_wild, WNT_ACQUIRE, 0) != WNT_STOPUSING) {
1168 lck_rw_done(pcbinfo->mtx);
1169 return (local_wild);
1170 }
1171 else {
1172 lck_rw_done(pcbinfo->mtx);
1173 return (NULL);
1174 }
1175 }
1176
1177 /*
1178 * Not found.
1179 */
1180 lck_rw_done(pcbinfo->mtx);
1181 return (NULL);
1182 }
1183
1184 void
1185 init_sin6(struct sockaddr_in6 *sin6, struct mbuf *m)
1186 {
1187 struct ip6_hdr *ip;
1188
1189 ip = mtod(m, struct ip6_hdr *);
1190 bzero(sin6, sizeof(*sin6));
1191 sin6->sin6_len = sizeof(*sin6);
1192 sin6->sin6_family = AF_INET6;
1193 sin6->sin6_addr = ip->ip6_src;
1194 if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr))
1195 sin6->sin6_addr.s6_addr16[1] = 0;
1196 sin6->sin6_scope_id =
1197 (m->m_pkthdr.rcvif && IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr))
1198 ? m->m_pkthdr.rcvif->if_index : 0;
1199
1200 return;
1201 }