]> git.saurik.com Git - apple/xnu.git/blob - bsd/netinet6/ip6_output.c
xnu-1504.9.37.tar.gz
[apple/xnu.git] / bsd / netinet6 / ip6_output.c
1 /*
2 * Copyright (c) 2008 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 /* $FreeBSD: src/sys/netinet6/ip6_output.c,v 1.43 2002/10/31 19:45:48 ume Exp $ */
30 /* $KAME: ip6_output.c,v 1.279 2002/01/26 06:12:30 jinmei Exp $ */
31
32 /*
33 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
34 * 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. Neither the name of the project nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
47 *
48 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE.
59 */
60
61 /*
62 * Copyright (c) 1982, 1986, 1988, 1990, 1993
63 * The Regents of the University of California. All rights reserved.
64 *
65 * Redistribution and use in source and binary forms, with or without
66 * modification, are permitted provided that the following conditions
67 * are met:
68 * 1. Redistributions of source code must retain the above copyright
69 * notice, this list of conditions and the following disclaimer.
70 * 2. Redistributions in binary form must reproduce the above copyright
71 * notice, this list of conditions and the following disclaimer in the
72 * documentation and/or other materials provided with the distribution.
73 * 3. All advertising materials mentioning features or use of this software
74 * must display the following acknowledgement:
75 * This product includes software developed by the University of
76 * California, Berkeley and its contributors.
77 * 4. Neither the name of the University nor the names of its contributors
78 * may be used to endorse or promote products derived from this software
79 * without specific prior written permission.
80 *
81 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
82 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
83 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
84 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
85 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
86 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
87 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
88 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
89 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
90 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
91 * SUCH DAMAGE.
92 *
93 * @(#)ip_output.c 8.3 (Berkeley) 1/21/94
94 */
95 /*
96 * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce
97 * support for mandatory and extensible security protections. This notice
98 * is included in support of clause 2.2 (b) of the Apple Public License,
99 * Version 2.0.
100 */
101
102 #include <sys/param.h>
103 #include <sys/malloc.h>
104 #include <sys/mbuf.h>
105 #include <sys/errno.h>
106 #include <sys/protosw.h>
107 #include <sys/socket.h>
108 #include <sys/socketvar.h>
109 #include <sys/systm.h>
110 #include <sys/kernel.h>
111 #include <sys/proc.h>
112 #include <sys/kauth.h>
113
114 #include <net/if.h>
115 #include <net/route.h>
116 #include <net/dlil.h>
117
118 #include <netinet/in.h>
119 #include <netinet/in_var.h>
120 #include <netinet/ip_var.h>
121 #include <netinet6/in6_var.h>
122 #include <netinet/ip6.h>
123 #include <netinet/icmp6.h>
124 #include <netinet6/ip6_var.h>
125 #include <netinet/in_pcb.h>
126 #include <netinet6/nd6.h>
127
128 #if IPSEC
129 #include <netinet6/ipsec.h>
130 #if INET6
131 #include <netinet6/ipsec6.h>
132 #endif
133 #include <netkey/key.h>
134 extern int ipsec_bypass;
135 #endif /* IPSEC */
136 extern lck_mtx_t *nd6_mutex;
137
138 #if CONFIG_MACF_NET
139 #include <security/mac.h>
140 #endif /* MAC_NET */
141
142 #include <netinet6/ip6_fw.h>
143
144 #include <net/net_osdep.h>
145
146 #include <netinet/kpi_ipfilter_var.h>
147
148 #if PF
149 #include <net/pfvar.h>
150 #endif /* PF */
151
152 #ifndef __APPLE__
153 static MALLOC_DEFINE(M_IPMOPTS, "ip6_moptions", "internet multicast options");
154 #endif
155
156 struct ip6_exthdrs {
157 struct mbuf *ip6e_ip6;
158 struct mbuf *ip6e_hbh;
159 struct mbuf *ip6e_dest1;
160 struct mbuf *ip6e_rthdr;
161 struct mbuf *ip6e_dest2;
162 };
163
164 static int ip6_pcbopts(struct ip6_pktopts **, struct mbuf *,
165 struct socket *, struct sockopt *sopt);
166 static int ip6_pcbopt(int optname, u_char *buf, int len, struct ip6_pktopts **pktopt);
167 static int ip6_getpcbopt(struct ip6_pktopts *pktopt, int optname, struct sockopt *sopt);
168 static int ip6_setpktopt(int optname, u_char *buf, int len, struct ip6_pktopts *opt);
169 static int ip6_setmoptions(int, struct inpcb *, struct mbuf *);
170 static int ip6_getmoptions(int, struct ip6_moptions *, struct mbuf **);
171 static int ip6_copyexthdr(struct mbuf **, caddr_t, int);
172 static int ip6_insertfraghdr(struct mbuf *, struct mbuf *, int,
173 struct ip6_frag **);
174 static int ip6_insert_jumboopt(struct ip6_exthdrs *, u_int32_t);
175 static int ip6_splithdr(struct mbuf *, struct ip6_exthdrs *);
176
177 extern int ip_createmoptions(struct ip_moptions **imop);
178 extern int ip_addmembership(struct ip_moptions *imo, struct ip_mreq *mreq);
179 extern int ip_dropmembership(struct ip_moptions *imo, struct ip_mreq *mreq);
180 extern lck_mtx_t *ip6_mutex;
181
182 /*
183 * IP6 output. The packet in mbuf chain m contains a skeletal IP6
184 * header (with pri, len, nxt, hlim, src, dst).
185 * This function may modify ver and hlim only.
186 * The mbuf chain containing the packet will be freed.
187 * The mbuf opt, if present, will not be freed.
188 *
189 * type of "mtu": rt_rmx.rmx_mtu is u_int32_t, ifnet.ifr_mtu is int, and
190 * nd_ifinfo.linkmtu is u_int32_t. so we use u_int32_t to hold largest one,
191 * which is rt_rmx.rmx_mtu.
192 */
193 int
194 ip6_output(
195 struct mbuf *m0,
196 struct ip6_pktopts *opt,
197 struct route_in6 *ro,
198 int flags,
199 struct ip6_moptions *im6o,
200 struct ifnet **ifpp, /* XXX: just for statistics */
201 int locked)
202 {
203 struct ip6_hdr *ip6, *mhip6;
204 struct ifnet *ifp, *origifp;
205 struct mbuf *m = m0;
206 int hlen, tlen, len, off;
207 struct route_in6 ip6route;
208 struct sockaddr_in6 *dst;
209 int error = 0;
210 struct in6_ifaddr *ia = NULL;
211 u_int32_t mtu;
212 u_int32_t optlen = 0, plen = 0, unfragpartlen = 0;
213 struct ip6_exthdrs exthdrs;
214 struct in6_addr finaldst;
215 struct route_in6 *ro_pmtu = NULL;
216 int hdrsplit = 0;
217 int needipsec = 0;
218 ipfilter_t inject_filter_ref;
219
220 #if IPSEC
221 int needipsectun = 0;
222 struct socket *so = NULL;
223 struct secpolicy *sp = NULL;
224
225 if (!locked)
226 lck_mtx_lock(ip6_mutex);
227 /* for AH processing. stupid to have "socket" variable in IP layer... */
228 if (ipsec_bypass == 0)
229 {
230 so = ipsec_getsocket(m);
231 (void)ipsec_setsocket(m, NULL);
232 }
233 #endif /* IPSEC */
234
235 ip6 = mtod(m, struct ip6_hdr *);
236 inject_filter_ref = ipf_get_inject_filter(m);
237 finaldst = ip6->ip6_dst;
238
239 #define MAKE_EXTHDR(hp, mp) \
240 do { \
241 if (hp) { \
242 struct ip6_ext *eh = (struct ip6_ext *)(hp); \
243 error = ip6_copyexthdr((mp), (caddr_t)(hp), \
244 ((eh)->ip6e_len + 1) << 3); \
245 if (error) \
246 goto freehdrs; \
247 } \
248 } while (0)
249
250 bzero(&exthdrs, sizeof(exthdrs));
251
252 if (opt) {
253 /* Hop-by-Hop options header */
254 MAKE_EXTHDR(opt->ip6po_hbh, &exthdrs.ip6e_hbh);
255 /* Destination options header(1st part) */
256 MAKE_EXTHDR(opt->ip6po_dest1, &exthdrs.ip6e_dest1);
257 /* Routing header */
258 MAKE_EXTHDR(opt->ip6po_rthdr, &exthdrs.ip6e_rthdr);
259 /* Destination options header(2nd part) */
260 MAKE_EXTHDR(opt->ip6po_dest2, &exthdrs.ip6e_dest2);
261 }
262
263 #if IPSEC
264 if (ipsec_bypass != 0)
265 goto skip_ipsec;
266
267 /* get a security policy for this packet */
268 if (so == NULL)
269 sp = ipsec6_getpolicybyaddr(m, IPSEC_DIR_OUTBOUND, 0, &error);
270 else
271 sp = ipsec6_getpolicybysock(m, IPSEC_DIR_OUTBOUND, so, &error);
272
273 if (sp == NULL) {
274 IPSEC_STAT_INCREMENT(ipsec6stat.out_inval);
275 goto freehdrs;
276 }
277
278 error = 0;
279
280 /* check policy */
281 switch (sp->policy) {
282 case IPSEC_POLICY_DISCARD:
283 case IPSEC_POLICY_GENERATE:
284 /*
285 * This packet is just discarded.
286 */
287 IPSEC_STAT_INCREMENT(ipsec6stat.out_polvio);
288 goto freehdrs;
289
290 case IPSEC_POLICY_BYPASS:
291 case IPSEC_POLICY_NONE:
292 /* no need to do IPsec. */
293 needipsec = 0;
294 break;
295
296 case IPSEC_POLICY_IPSEC:
297 if (sp->req == NULL) {
298 /* acquire a policy */
299 error = key_spdacquire(sp);
300 goto freehdrs;
301 }
302 needipsec = 1;
303 break;
304
305 case IPSEC_POLICY_ENTRUST:
306 default:
307 printf("ip6_output: Invalid policy found. %d\n", sp->policy);
308 }
309 skip_ipsec:
310 #endif /* IPSEC */
311
312 /*
313 * Calculate the total length of the extension header chain.
314 * Keep the length of the unfragmentable part for fragmentation.
315 */
316 optlen = 0;
317 if (exthdrs.ip6e_hbh) optlen += exthdrs.ip6e_hbh->m_len;
318 if (exthdrs.ip6e_dest1) optlen += exthdrs.ip6e_dest1->m_len;
319 if (exthdrs.ip6e_rthdr) optlen += exthdrs.ip6e_rthdr->m_len;
320 unfragpartlen = optlen + sizeof(struct ip6_hdr);
321 /* NOTE: we don't add AH/ESP length here. do that later. */
322 if (exthdrs.ip6e_dest2) optlen += exthdrs.ip6e_dest2->m_len;
323
324 /*
325 * If we need IPsec, or there is at least one extension header,
326 * separate IP6 header from the payload.
327 */
328 if ((needipsec || optlen) && !hdrsplit) {
329 if ((error = ip6_splithdr(m, &exthdrs)) != 0) {
330 m = NULL;
331 goto freehdrs;
332 }
333 m = exthdrs.ip6e_ip6;
334 hdrsplit++;
335 }
336
337 /* adjust pointer */
338 ip6 = mtod(m, struct ip6_hdr *);
339
340 /* adjust mbuf packet header length */
341 m->m_pkthdr.len += optlen;
342 plen = m->m_pkthdr.len - sizeof(*ip6);
343
344 /* If this is a jumbo payload, insert a jumbo payload option. */
345 if (plen > IPV6_MAXPACKET) {
346 if (!hdrsplit) {
347 if ((error = ip6_splithdr(m, &exthdrs)) != 0) {
348 m = NULL;
349 goto freehdrs;
350 }
351 m = exthdrs.ip6e_ip6;
352 hdrsplit++;
353 }
354 /* adjust pointer */
355 ip6 = mtod(m, struct ip6_hdr *);
356 if ((error = ip6_insert_jumboopt(&exthdrs, plen)) != 0)
357 goto freehdrs;
358 ip6->ip6_plen = 0;
359 } else
360 ip6->ip6_plen = htons(plen);
361
362 /*
363 * Concatenate headers and fill in next header fields.
364 * Here we have, on "m"
365 * IPv6 payload
366 * and we insert headers accordingly. Finally, we should be getting:
367 * IPv6 hbh dest1 rthdr ah* [esp* dest2 payload]
368 *
369 * during the header composing process, "m" points to IPv6 header.
370 * "mprev" points to an extension header prior to esp.
371 */
372 {
373 u_char *nexthdrp = &ip6->ip6_nxt;
374 struct mbuf *mprev = m;
375
376 /*
377 * we treat dest2 specially. this makes IPsec processing
378 * much easier. the goal here is to make mprev point the
379 * mbuf prior to dest2.
380 *
381 * result: IPv6 dest2 payload
382 * m and mprev will point to IPv6 header.
383 */
384 if (exthdrs.ip6e_dest2) {
385 if (!hdrsplit)
386 panic("assumption failed: hdr not split");
387 exthdrs.ip6e_dest2->m_next = m->m_next;
388 m->m_next = exthdrs.ip6e_dest2;
389 *mtod(exthdrs.ip6e_dest2, u_char *) = ip6->ip6_nxt;
390 ip6->ip6_nxt = IPPROTO_DSTOPTS;
391 }
392
393 #define MAKE_CHAIN(m, mp, p, i)\
394 do {\
395 if (m) {\
396 if (!hdrsplit) \
397 panic("assumption failed: hdr not split"); \
398 *mtod((m), u_char *) = *(p);\
399 *(p) = (i);\
400 p = mtod((m), u_char *);\
401 (m)->m_next = (mp)->m_next;\
402 (mp)->m_next = (m);\
403 (mp) = (m);\
404 }\
405 } while (0)
406 /*
407 * result: IPv6 hbh dest1 rthdr dest2 payload
408 * m will point to IPv6 header. mprev will point to the
409 * extension header prior to dest2 (rthdr in the above case).
410 */
411 MAKE_CHAIN(exthdrs.ip6e_hbh, mprev,
412 nexthdrp, IPPROTO_HOPOPTS);
413 MAKE_CHAIN(exthdrs.ip6e_dest1, mprev,
414 nexthdrp, IPPROTO_DSTOPTS);
415 MAKE_CHAIN(exthdrs.ip6e_rthdr, mprev,
416 nexthdrp, IPPROTO_ROUTING);
417
418 if (!TAILQ_EMPTY(&ipv6_filters)) {
419 struct ipfilter *filter;
420 int seen = (inject_filter_ref == 0);
421 int fixscope = 0;
422 struct ipf_pktopts *ippo = 0, ipf_pktopts;
423
424 if (im6o != NULL && IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
425 ippo = &ipf_pktopts;
426 ippo->ippo_flags = IPPOF_MCAST_OPTS;
427 ippo->ippo_mcast_ifnet = im6o->im6o_multicast_ifp;
428 ippo->ippo_mcast_ttl = im6o->im6o_multicast_hlim;
429 ippo->ippo_mcast_loop = im6o->im6o_multicast_loop;
430 }
431
432 /* Hack: embed the scope_id in the destination */
433 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst) &&
434 (ip6->ip6_dst.s6_addr16[1] == 0) && (ro != NULL)) {
435 fixscope = 1;
436 ip6->ip6_dst.s6_addr16[1] = htons(ro->ro_dst.sin6_scope_id);
437 }
438 {
439 lck_mtx_unlock(ip6_mutex);
440 ipf_ref();
441 TAILQ_FOREACH(filter, &ipv6_filters, ipf_link) {
442 /*
443 * No need to proccess packet twice if we've
444 * already seen it
445 */
446 if (seen == 0) {
447 if ((struct ipfilter *)inject_filter_ref == filter)
448 seen = 1;
449 } else if (filter->ipf_filter.ipf_output) {
450 errno_t result;
451
452 result = filter->ipf_filter.ipf_output(filter->ipf_filter.cookie, (mbuf_t*)&m, ippo);
453 if (result == EJUSTRETURN) {
454 ipf_unref();
455 locked = 1; /* Don't want to take lock to unlock it right away */
456 goto done;
457 }
458 if (result != 0) {
459 ipf_unref();
460 locked = 1; /* Don't want to take lock to unlock it right away */
461 goto bad;
462 }
463 }
464 }
465 ipf_unref();
466 lck_mtx_lock(ip6_mutex);
467 }
468 ip6 = mtod(m, struct ip6_hdr *);
469 /* Hack: cleanup embedded scope_id if we put it there */
470 if (fixscope)
471 ip6->ip6_dst.s6_addr16[1] = 0;
472 }
473
474 #if IPSEC
475 if (!needipsec)
476 goto skip_ipsec2;
477
478 /*
479 * pointers after IPsec headers are not valid any more.
480 * other pointers need a great care too.
481 * (IPsec routines should not mangle mbufs prior to AH/ESP)
482 */
483 exthdrs.ip6e_dest2 = NULL;
484
485 {
486 struct ip6_rthdr *rh = NULL;
487 int segleft_org = 0;
488 struct ipsec_output_state state;
489
490 if (exthdrs.ip6e_rthdr) {
491 rh = mtod(exthdrs.ip6e_rthdr, struct ip6_rthdr *);
492 segleft_org = rh->ip6r_segleft;
493 rh->ip6r_segleft = 0;
494 }
495
496 bzero(&state, sizeof(state));
497 state.m = m;
498 lck_mtx_unlock(ip6_mutex);
499 error = ipsec6_output_trans(&state, nexthdrp, mprev, sp, flags,
500 &needipsectun);
501 lck_mtx_lock(ip6_mutex);
502 m = state.m;
503 if (error) {
504 /* mbuf is already reclaimed in ipsec6_output_trans. */
505 m = NULL;
506 switch (error) {
507 case EHOSTUNREACH:
508 case ENETUNREACH:
509 case EMSGSIZE:
510 case ENOBUFS:
511 case ENOMEM:
512 break;
513 default:
514 printf("ip6_output (ipsec): error code %d\n", error);
515 /* fall through */
516 case ENOENT:
517 /* don't show these error codes to the user */
518 error = 0;
519 break;
520 }
521 goto bad;
522 }
523 if (exthdrs.ip6e_rthdr) {
524 /* ah6_output doesn't modify mbuf chain */
525 rh->ip6r_segleft = segleft_org;
526 }
527 }
528 skip_ipsec2:;
529 #endif
530 }
531
532 /*
533 * If there is a routing header, replace destination address field
534 * with the first hop of the routing header.
535 */
536 if (exthdrs.ip6e_rthdr) {
537 struct ip6_rthdr *rh =
538 (struct ip6_rthdr *)(mtod(exthdrs.ip6e_rthdr,
539 struct ip6_rthdr *));
540 struct ip6_rthdr0 *rh0;
541
542 finaldst = ip6->ip6_dst;
543 switch (rh->ip6r_type) {
544 case IPV6_RTHDR_TYPE_0:
545 rh0 = (struct ip6_rthdr0 *)rh;
546 ip6->ip6_dst = rh0->ip6r0_addr[0];
547 bcopy((caddr_t)&rh0->ip6r0_addr[1],
548 (caddr_t)&rh0->ip6r0_addr[0],
549 sizeof(struct in6_addr)*(rh0->ip6r0_segleft - 1)
550 );
551 rh0->ip6r0_addr[rh0->ip6r0_segleft - 1] = finaldst;
552 break;
553 default: /* is it possible? */
554 error = EINVAL;
555 goto bad;
556 }
557 }
558
559 /* Source address validation */
560 if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src) &&
561 (flags & IPV6_DADOUTPUT) == 0) {
562 error = EOPNOTSUPP;
563 ip6stat.ip6s_badscope++;
564 goto bad;
565 }
566 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_src)) {
567 error = EOPNOTSUPP;
568 ip6stat.ip6s_badscope++;
569 goto bad;
570 }
571
572 ip6stat.ip6s_localout++;
573
574 /*
575 * Route packet.
576 */
577 if (ro == 0) {
578 ro = &ip6route;
579 bzero((caddr_t)ro, sizeof(*ro));
580 }
581 ro_pmtu = ro;
582 if (opt && opt->ip6po_rthdr)
583 ro = &opt->ip6po_route;
584 dst = (struct sockaddr_in6 *)&ro->ro_dst;
585 /*
586 * If there is a cached route, check that it is to the same
587 * destination and is still up. If not, free it and try again.
588 * Test rt_flags without holding rt_lock for performance reasons;
589 * if the route is down it will hopefully be caught by the layer
590 * below (since it uses this route as a hint) or during the
591 * next transmit.
592 */
593 if (ro->ro_rt != NULL && (!(ro->ro_rt->rt_flags & RTF_UP) ||
594 dst->sin6_family != AF_INET6 ||
595 !IN6_ARE_ADDR_EQUAL(&dst->sin6_addr, &ip6->ip6_dst) ||
596 ro->ro_rt->generation_id != route_generation)) {
597 rtfree(ro->ro_rt);
598 ro->ro_rt = NULL;
599 }
600 if (ro->ro_rt == NULL) {
601 bzero(dst, sizeof(*dst));
602 dst->sin6_family = AF_INET6;
603 dst->sin6_len = sizeof(struct sockaddr_in6);
604 dst->sin6_addr = ip6->ip6_dst;
605 #if SCOPEDROUTING
606 /* XXX: sin6_scope_id should already be fixed at this point */
607 if (IN6_IS_SCOPE_LINKLOCAL(&dst->sin6_addr))
608 dst->sin6_scope_id = ntohs(dst->sin6_addr.s6_addr16[1]);
609 #endif
610 }
611 #if IPSEC
612 if (needipsec && needipsectun) {
613 struct ipsec_output_state state;
614 int tunneledv4 = 0;
615
616 /*
617 * All the extension headers will become inaccessible
618 * (since they can be encrypted).
619 * Don't panic, we need no more updates to extension headers
620 * on inner IPv6 packet (since they are now encapsulated).
621 *
622 * IPv6 [ESP|AH] IPv6 [extension headers] payload
623 */
624 bzero(&exthdrs, sizeof(exthdrs));
625 exthdrs.ip6e_ip6 = m;
626
627 bzero(&state, sizeof(state));
628 state.m = m;
629 state.ro = (struct route *)ro;
630 state.dst = (struct sockaddr *)dst;
631 lck_mtx_unlock(ip6_mutex);
632 error = ipsec6_output_tunnel(&state, sp, flags, &tunneledv4);
633 lck_mtx_lock(ip6_mutex);
634 if (tunneledv4) /* tunneled in IPv4 - packet is gone */
635 goto done;
636 m = state.m;
637 ro = (struct route_in6 *)state.ro;
638 dst = (struct sockaddr_in6 *)state.dst;
639 if (error) {
640 /* mbuf is already reclaimed in ipsec6_output_tunnel. */
641 m0 = m = NULL;
642 m = NULL;
643 switch (error) {
644 case EHOSTUNREACH:
645 case ENETUNREACH:
646 case EMSGSIZE:
647 case ENOBUFS:
648 case ENOMEM:
649 break;
650 default:
651 printf("ip6_output (ipsec): error code %d\n", error);
652 /* fall through */
653 case ENOENT:
654 /* don't show these error codes to the user */
655 error = 0;
656 break;
657 }
658 goto bad;
659 }
660
661 exthdrs.ip6e_ip6 = m;
662 }
663 #endif /* IPSEC */
664
665 if (!IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
666 /* Unicast */
667
668 #define ifatoia6(ifa) ((struct in6_ifaddr *)(ifa))
669 #define sin6tosa(sin6) ((struct sockaddr *)(sin6))
670 /* xxx
671 * interface selection comes here
672 * if an interface is specified from an upper layer,
673 * ifp must point it.
674 */
675 if (ro->ro_rt == NULL) {
676 /*
677 * non-bsdi always clone routes, if parent is
678 * PRF_CLONING.
679 */
680 rtalloc_ign((struct route *)ro, 0);
681 }
682 if (ro->ro_rt == NULL) {
683 ip6stat.ip6s_noroute++;
684 error = EHOSTUNREACH;
685 /* XXX in6_ifstat_inc(ifp, ifs6_out_discard); */
686 goto bad;
687 }
688 RT_LOCK_SPIN(ro->ro_rt);
689 ia = ifatoia6(ro->ro_rt->rt_ifa);
690 if (ia != NULL)
691 ifaref(&ia->ia_ifa);
692 ifp = ro->ro_rt->rt_ifp;
693 ro->ro_rt->rt_use++;
694 if (ro->ro_rt->rt_flags & RTF_GATEWAY)
695 dst = (struct sockaddr_in6 *)ro->ro_rt->rt_gateway;
696 RT_UNLOCK(ro->ro_rt);
697 m->m_flags &= ~(M_BCAST | M_MCAST); /* just in case */
698
699 in6_ifstat_inc(ifp, ifs6_out_request);
700
701 /*
702 * Check if the outgoing interface conflicts with
703 * the interface specified by ifi6_ifindex (if specified).
704 * Note that loopback interface is always okay.
705 * (this may happen when we are sending a packet to one of
706 * our own addresses.)
707 */
708 if (opt && opt->ip6po_pktinfo
709 && opt->ip6po_pktinfo->ipi6_ifindex) {
710 if (!(ifp->if_flags & IFF_LOOPBACK)
711 && ifp->if_index != opt->ip6po_pktinfo->ipi6_ifindex) {
712 ip6stat.ip6s_noroute++;
713 in6_ifstat_inc(ifp, ifs6_out_discard);
714 error = EHOSTUNREACH;
715 goto bad;
716 }
717 }
718
719 /*
720 * if specified, try to fill in the traffic class field.
721 * do not override if a non-zero value is already set.
722 * we check the diffserv field and the ecn field separately.
723 */
724 if (opt && opt->ip6po_tclass >= 0) {
725 int mask = 0;
726
727 if ((ip6->ip6_flow & htonl(0xfc << 20)) == 0)
728 mask |= 0xfc;
729 if ((ip6->ip6_flow & htonl(0x03 << 20)) == 0)
730 mask |= 0x03;
731 if (mask != 0)
732 ip6->ip6_flow |= htonl((opt->ip6po_tclass & mask) << 20);
733 }
734
735 if (opt && opt->ip6po_hlim != -1)
736 ip6->ip6_hlim = opt->ip6po_hlim & 0xff;
737 } else {
738 /* Multicast */
739 struct in6_multi *in6m;
740
741 m->m_flags = (m->m_flags & ~M_BCAST) | M_MCAST;
742
743 /*
744 * See if the caller provided any multicast options
745 */
746 ifp = NULL;
747 if (im6o != NULL) {
748 ip6->ip6_hlim = im6o->im6o_multicast_hlim;
749 if (im6o->im6o_multicast_ifp != NULL)
750 ifp = im6o->im6o_multicast_ifp;
751 } else
752 ip6->ip6_hlim = ip6_defmcasthlim;
753
754 /*
755 * See if the caller provided the outgoing interface
756 * as an ancillary data.
757 * Boundary check for ifindex is assumed to be already done.
758 */
759 if (opt && opt->ip6po_pktinfo && opt->ip6po_pktinfo->ipi6_ifindex) {
760 unsigned int index = opt->ip6po_pktinfo->ipi6_ifindex;
761 ifnet_head_lock_shared();
762 if (index > 0 && index <= if_index) {
763 ifp = ifindex2ifnet[index];
764 }
765 ifnet_head_done();
766 }
767
768 /*
769 * If the destination is a node-local scope multicast,
770 * the packet should be loop-backed only.
771 */
772 if (IN6_IS_ADDR_MC_NODELOCAL(&ip6->ip6_dst)) {
773 /*
774 * If the outgoing interface is already specified,
775 * it should be a loopback interface.
776 */
777 if (ifp && (ifp->if_flags & IFF_LOOPBACK) == 0) {
778 ip6stat.ip6s_badscope++;
779 error = ENETUNREACH; /* XXX: better error? */
780 /* XXX correct ifp? */
781 in6_ifstat_inc(ifp, ifs6_out_discard);
782 goto bad;
783 } else {
784 ifp = lo_ifp;
785 }
786 }
787
788 /*
789 * if specified, try to fill in the traffic class field.
790 * do not override if a non-zero value is already set.
791 * we check the diffserv field and the ecn field separately.
792 */
793 if (opt && opt->ip6po_tclass >= 0) {
794 int mask = 0;
795
796 if ((ip6->ip6_flow & htonl(0xfc << 20)) == 0)
797 mask |= 0xfc;
798 if ((ip6->ip6_flow & htonl(0x03 << 20)) == 0)
799 mask |= 0x03;
800 if (mask != 0)
801 ip6->ip6_flow |= htonl((opt->ip6po_tclass & mask) << 20);
802 }
803
804 if (opt && opt->ip6po_hlim != -1)
805 ip6->ip6_hlim = opt->ip6po_hlim & 0xff;
806
807 /*
808 * If caller did not provide an interface lookup a
809 * default in the routing table. This is either a
810 * default for the speicfied group (i.e. a host
811 * route), or a multicast default (a route for the
812 * ``net'' ff00::/8).
813 */
814 if (ifp == NULL) {
815 if (ro->ro_rt == NULL) {
816 ro->ro_rt = rtalloc1(
817 (struct sockaddr *)&ro->ro_dst, 0, 0);
818 }
819 if (ro->ro_rt == NULL) {
820 ip6stat.ip6s_noroute++;
821 error = EHOSTUNREACH;
822 /* XXX in6_ifstat_inc(ifp, ifs6_out_discard) */
823 goto bad;
824 }
825 RT_LOCK_SPIN(ro->ro_rt);
826 ia = ifatoia6(ro->ro_rt->rt_ifa);
827 if (ia != NULL)
828 ifaref(&ia->ia_ifa);
829 ifp = ro->ro_rt->rt_ifp;
830 ro->ro_rt->rt_use++;
831 RT_UNLOCK(ro->ro_rt);
832 }
833
834 if ((flags & IPV6_FORWARDING) == 0)
835 in6_ifstat_inc(ifp, ifs6_out_request);
836 in6_ifstat_inc(ifp, ifs6_out_mcast);
837
838 /*
839 * Confirm that the outgoing interface supports multicast.
840 */
841 if ((ifp->if_flags & IFF_MULTICAST) == 0) {
842 ip6stat.ip6s_noroute++;
843 in6_ifstat_inc(ifp, ifs6_out_discard);
844 error = ENETUNREACH;
845 goto bad;
846 }
847 ifnet_lock_shared(ifp);
848 IN6_LOOKUP_MULTI(ip6->ip6_dst, ifp, in6m);
849 ifnet_lock_done(ifp);
850 if (in6m != NULL &&
851 (im6o == NULL || im6o->im6o_multicast_loop)) {
852 /*
853 * If we belong to the destination multicast group
854 * on the outgoing interface, and the caller did not
855 * forbid loopback, loop back a copy.
856 */
857 ip6_mloopback(ifp, m, dst);
858 } else {
859 /*
860 * If we are acting as a multicast router, perform
861 * multicast forwarding as if the packet had just
862 * arrived on the interface to which we are about
863 * to send. The multicast forwarding function
864 * recursively calls this function, using the
865 * IPV6_FORWARDING flag to prevent infinite recursion.
866 *
867 * Multicasts that are looped back by ip6_mloopback(),
868 * above, will be forwarded by the ip6_input() routine,
869 * if necessary.
870 */
871 #if MROUTING
872 if (ip6_mrouter && (flags & IPV6_FORWARDING) == 0) {
873 if (ip6_mforward(ip6, ifp, m) != 0) {
874 m_freem(m);
875 goto done;
876 }
877 }
878 #endif
879 }
880 /*
881 * Multicasts with a hoplimit of zero may be looped back,
882 * above, but must not be transmitted on a network.
883 * Also, multicasts addressed to the loopback interface
884 * are not sent -- the above call to ip6_mloopback() will
885 * loop back a copy if this host actually belongs to the
886 * destination group on the loopback interface.
887 */
888 if (ip6->ip6_hlim == 0 || (ifp->if_flags & IFF_LOOPBACK)) {
889 m_freem(m);
890 goto done;
891 }
892 }
893
894 /*
895 * Fill the outgoing inteface to tell the upper layer
896 * to increment per-interface statistics.
897 */
898 if (ifpp)
899 *ifpp = ifp;
900
901 /*
902 * Determine path MTU.
903 */
904 if (ro_pmtu != ro) {
905 /* The first hop and the final destination may differ. */
906 struct sockaddr_in6 *sin6_fin =
907 (struct sockaddr_in6 *)&ro_pmtu->ro_dst;
908 if (ro_pmtu->ro_rt != NULL &&
909 (!(ro_pmtu->ro_rt->rt_flags & RTF_UP) ||
910 ro_pmtu->ro_rt->generation_id != route_generation ||
911 !IN6_ARE_ADDR_EQUAL(&sin6_fin->sin6_addr, &finaldst))) {
912 rtfree(ro_pmtu->ro_rt);
913 ro_pmtu->ro_rt = NULL;
914 }
915 if (ro_pmtu->ro_rt == NULL) {
916 bzero(sin6_fin, sizeof(*sin6_fin));
917 sin6_fin->sin6_family = AF_INET6;
918 sin6_fin->sin6_len = sizeof(struct sockaddr_in6);
919 sin6_fin->sin6_addr = finaldst;
920
921 rtalloc((struct route *)ro_pmtu);
922 }
923 }
924 if (ro_pmtu->ro_rt != NULL) {
925 u_int32_t ifmtu;
926
927 lck_rw_lock_shared(nd_if_rwlock);
928 ifmtu = IN6_LINKMTU(ifp);
929 lck_rw_done(nd_if_rwlock);
930
931 RT_LOCK_SPIN(ro_pmtu->ro_rt);
932 mtu = ro_pmtu->ro_rt->rt_rmx.rmx_mtu;
933 if (mtu > ifmtu || mtu == 0) {
934 /*
935 * The MTU on the route is larger than the MTU on
936 * the interface! This shouldn't happen, unless the
937 * MTU of the interface has been changed after the
938 * interface was brought up. Change the MTU in the
939 * route to match the interface MTU (as long as the
940 * field isn't locked).
941 *
942 * if MTU on the route is 0, we need to fix the MTU.
943 * this case happens with path MTU discovery timeouts.
944 */
945 mtu = ifmtu;
946 if ((ro_pmtu->ro_rt->rt_rmx.rmx_locks & RTV_MTU) == 0)
947 ro_pmtu->ro_rt->rt_rmx.rmx_mtu = mtu; /* XXX */
948 }
949 RT_UNLOCK(ro_pmtu->ro_rt);
950 } else {
951 lck_rw_lock_shared(nd_if_rwlock);
952 mtu = IN6_LINKMTU(ifp);
953 lck_rw_done(nd_if_rwlock);
954 }
955
956 /*
957 * advanced API (IPV6_USE_MIN_MTU) overrides mtu setting
958 */
959 if ((flags & IPV6_MINMTU) != 0 && mtu > IPV6_MMTU)
960 mtu = IPV6_MMTU;
961
962 /* Fake scoped addresses */
963 if ((ifp->if_flags & IFF_LOOPBACK) != 0) {
964 /*
965 * If source or destination address is a scoped address, and
966 * the packet is going to be sent to a loopback interface,
967 * we should keep the original interface.
968 */
969
970 /*
971 * XXX: this is a very experimental and temporary solution.
972 * We eventually have sockaddr_in6 and use the sin6_scope_id
973 * field of the structure here.
974 * We rely on the consistency between two scope zone ids
975 * of source and destination, which should already be assured.
976 * Larger scopes than link will be supported in the future.
977 */
978 u_short index = 0;
979 origifp = NULL;
980 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src))
981 index = ntohs(ip6->ip6_src.s6_addr16[1]);
982 else if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst))
983 index = ntohs(ip6->ip6_dst.s6_addr16[1]);
984 ifnet_head_lock_shared();
985 if (index > 0 && index <= if_index) {
986 origifp = ifindex2ifnet[index];
987 }
988 ifnet_head_done();
989 /*
990 * XXX: origifp can be NULL even in those two cases above.
991 * For example, if we remove the (only) link-local address
992 * from the loopback interface, and try to send a link-local
993 * address without link-id information. Then the source
994 * address is ::1, and the destination address is the
995 * link-local address with its s6_addr16[1] being zero.
996 * What is worse, if the packet goes to the loopback interface
997 * by a default rejected route, the null pointer would be
998 * passed to looutput, and the kernel would hang.
999 * The following last resort would prevent such disaster.
1000 */
1001 if (origifp == NULL)
1002 origifp = ifp;
1003 }
1004 else
1005 origifp = ifp;
1006 #ifndef SCOPEDROUTING
1007 /*
1008 * clear embedded scope identifiers if necessary.
1009 * in6_clearscope will touch the addresses only when necessary.
1010 */
1011 in6_clearscope(&ip6->ip6_src);
1012 in6_clearscope(&ip6->ip6_dst);
1013 #endif
1014
1015 #if IPFW2
1016 /*
1017 * Check with the firewall...
1018 */
1019 if (ip6_fw_enable && ip6_fw_chk_ptr) {
1020 u_short port = 0;
1021 m->m_pkthdr.rcvif = NULL; /* XXX */
1022 /* If ipfw says divert, we have to just drop packet */
1023 if (ip6_fw_chk_ptr(&ip6, ifp, &port, &m)) {
1024 m_freem(m);
1025 goto done;
1026 }
1027 if (!m) {
1028 error = EACCES;
1029 goto done;
1030 }
1031 }
1032 #endif
1033
1034 /*
1035 * If the outgoing packet contains a hop-by-hop options header,
1036 * it must be examined and processed even by the source node.
1037 * (RFC 2460, section 4.)
1038 */
1039 if (exthdrs.ip6e_hbh) {
1040 struct ip6_hbh *hbh = mtod(exthdrs.ip6e_hbh, struct ip6_hbh *);
1041 u_int32_t dummy1; /* XXX unused */
1042 u_int32_t dummy2; /* XXX unused */
1043
1044 #if DIAGNOSTIC
1045 if ((hbh->ip6h_len + 1) << 3 > exthdrs.ip6e_hbh->m_len)
1046 panic("ip6e_hbh is not continuous");
1047 #endif
1048 /*
1049 * XXX: if we have to send an ICMPv6 error to the sender,
1050 * we need the M_LOOP flag since icmp6_error() expects
1051 * the IPv6 and the hop-by-hop options header are
1052 * continuous unless the flag is set.
1053 */
1054 m->m_flags |= M_LOOP;
1055 m->m_pkthdr.rcvif = ifp;
1056 if (ip6_process_hopopts(m,
1057 (u_int8_t *)(hbh + 1),
1058 ((hbh->ip6h_len + 1) << 3) -
1059 sizeof(struct ip6_hbh),
1060 &dummy1, &dummy2) < 0) {
1061 /* m was already freed at this point */
1062 error = EINVAL;/* better error? */
1063 goto done;
1064 }
1065 m->m_flags &= ~M_LOOP; /* XXX */
1066 m->m_pkthdr.rcvif = NULL;
1067 }
1068
1069 #if PF
1070 lck_mtx_unlock(ip6_mutex);
1071
1072 /* Invoke outbound packet filter */
1073 error = pf_af_hook(ifp, NULL, &m, AF_INET6, FALSE);
1074
1075 lck_mtx_lock(ip6_mutex);
1076
1077 if (error) {
1078 if (m != NULL) {
1079 panic("%s: unexpected packet %p\n", __func__, m);
1080 /* NOTREACHED */
1081 }
1082 /* Already freed by callee */
1083 goto done;
1084 }
1085 ip6 = mtod(m, struct ip6_hdr *);
1086 #endif /* PF */
1087
1088 /*
1089 * Send the packet to the outgoing interface.
1090 * If necessary, do IPv6 fragmentation before sending.
1091 */
1092 tlen = m->m_pkthdr.len;
1093 if (tlen <= mtu
1094 #if notyet
1095 /*
1096 * On any link that cannot convey a 1280-octet packet in one piece,
1097 * link-specific fragmentation and reassembly must be provided at
1098 * a layer below IPv6. [RFC 2460, sec.5]
1099 * Thus if the interface has ability of link-level fragmentation,
1100 * we can just send the packet even if the packet size is
1101 * larger than the link's MTU.
1102 * XXX: IFF_FRAGMENTABLE (or such) flag has not been defined yet...
1103 */
1104
1105 || ifp->if_flags & IFF_FRAGMENTABLE
1106 #endif
1107 )
1108 {
1109 /* Record statistics for this interface address. */
1110 if (ia && !(flags & IPV6_FORWARDING)) {
1111 #ifndef __APPLE__
1112 ia->ia_ifa.if_opackets++;
1113 ia->ia_ifa.if_obytes += m->m_pkthdr.len;
1114 #endif
1115 }
1116 #ifdef IPSEC
1117 /* clean ipsec history once it goes out of the node */
1118 ipsec_delaux(m);
1119 #endif
1120
1121 error = nd6_output(ifp, origifp, m, dst, ro->ro_rt, 1);
1122 goto done;
1123 } else if (mtu < IPV6_MMTU) {
1124 /*
1125 * note that path MTU is never less than IPV6_MMTU
1126 * (see icmp6_input).
1127 */
1128 error = EMSGSIZE;
1129 in6_ifstat_inc(ifp, ifs6_out_fragfail);
1130 goto bad;
1131 } else if (ip6->ip6_plen == 0) { /* jumbo payload cannot be fragmented */
1132 error = EMSGSIZE;
1133 in6_ifstat_inc(ifp, ifs6_out_fragfail);
1134 goto bad;
1135 } else {
1136 struct mbuf **mnext, *m_frgpart;
1137 struct ip6_frag *ip6f = NULL;
1138 u_int32_t id = htonl(ip6_id++);
1139 u_char nextproto;
1140
1141 /*
1142 * Too large for the destination or interface;
1143 * fragment if possible.
1144 * Must be able to put at least 8 bytes per fragment.
1145 */
1146 hlen = unfragpartlen;
1147 if (mtu > IPV6_MAXPACKET)
1148 mtu = IPV6_MAXPACKET;
1149
1150 len = (mtu - hlen - sizeof(struct ip6_frag)) & ~7;
1151 if (len < 8) {
1152 error = EMSGSIZE;
1153 in6_ifstat_inc(ifp, ifs6_out_fragfail);
1154 goto bad;
1155 }
1156
1157 mnext = &m->m_nextpkt;
1158
1159 /*
1160 * Change the next header field of the last header in the
1161 * unfragmentable part.
1162 */
1163 if (exthdrs.ip6e_rthdr) {
1164 nextproto = *mtod(exthdrs.ip6e_rthdr, u_char *);
1165 *mtod(exthdrs.ip6e_rthdr, u_char *) = IPPROTO_FRAGMENT;
1166 } else if (exthdrs.ip6e_dest1) {
1167 nextproto = *mtod(exthdrs.ip6e_dest1, u_char *);
1168 *mtod(exthdrs.ip6e_dest1, u_char *) = IPPROTO_FRAGMENT;
1169 } else if (exthdrs.ip6e_hbh) {
1170 nextproto = *mtod(exthdrs.ip6e_hbh, u_char *);
1171 *mtod(exthdrs.ip6e_hbh, u_char *) = IPPROTO_FRAGMENT;
1172 } else {
1173 nextproto = ip6->ip6_nxt;
1174 ip6->ip6_nxt = IPPROTO_FRAGMENT;
1175 }
1176
1177 /*
1178 * Loop through length of segment after first fragment,
1179 * make new header and copy data of each part and link onto
1180 * chain.
1181 */
1182 m0 = m;
1183 for (off = hlen; off < tlen; off += len) {
1184 MGETHDR(m, M_DONTWAIT, MT_HEADER); /* MAC-OK */
1185 if (!m) {
1186 error = ENOBUFS;
1187 ip6stat.ip6s_odropped++;
1188 goto sendorfree;
1189 }
1190 m->m_pkthdr.rcvif = NULL;
1191 m->m_flags = m0->m_flags & M_COPYFLAGS;
1192 *mnext = m;
1193 mnext = &m->m_nextpkt;
1194 m->m_data += max_linkhdr;
1195 mhip6 = mtod(m, struct ip6_hdr *);
1196 *mhip6 = *ip6;
1197 m->m_len = sizeof(*mhip6);
1198 error = ip6_insertfraghdr(m0, m, hlen, &ip6f);
1199 if (error) {
1200 ip6stat.ip6s_odropped++;
1201 goto sendorfree;
1202 }
1203 ip6f->ip6f_offlg = htons((u_short)((off - hlen) & ~7));
1204 if (off + len >= tlen)
1205 len = tlen - off;
1206 else
1207 ip6f->ip6f_offlg |= IP6F_MORE_FRAG;
1208 mhip6->ip6_plen = htons((u_short)(len + hlen +
1209 sizeof(*ip6f) -
1210 sizeof(struct ip6_hdr)));
1211 if ((m_frgpart = m_copy(m0, off, len)) == 0) {
1212 error = ENOBUFS;
1213 ip6stat.ip6s_odropped++;
1214 goto sendorfree;
1215 }
1216 m_cat(m, m_frgpart);
1217 m->m_pkthdr.len = len + hlen + sizeof(*ip6f);
1218 m->m_pkthdr.rcvif = 0;
1219 m->m_pkthdr.socket_id = m0->m_pkthdr.socket_id;
1220 #ifdef __darwin8_notyet
1221 #if CONFIG_MACF_NET
1222 mac_create_fragment(m0, m);
1223 #endif
1224 #endif
1225 ip6f->ip6f_reserved = 0;
1226 ip6f->ip6f_ident = id;
1227 ip6f->ip6f_nxt = nextproto;
1228 ip6stat.ip6s_ofragments++;
1229 in6_ifstat_inc(ifp, ifs6_out_fragcreat);
1230 }
1231
1232 in6_ifstat_inc(ifp, ifs6_out_fragok);
1233 }
1234
1235 /*
1236 * Remove leading garbages.
1237 */
1238 sendorfree:
1239 m = m0->m_nextpkt;
1240 m0->m_nextpkt = 0;
1241 m_freem(m0);
1242 for (m0 = m; m; m = m0) {
1243 m0 = m->m_nextpkt;
1244 m->m_nextpkt = 0;
1245 if (error == 0) {
1246 /* Record statistics for this interface address. */
1247 if (ia) {
1248 #ifndef __APPLE__
1249 ia->ia_ifa.if_opackets++;
1250 ia->ia_ifa.if_obytes += m->m_pkthdr.len;
1251 #endif
1252 }
1253 #if IPSEC
1254 /* clean ipsec history once it goes out of the node */
1255 ipsec_delaux(m);
1256 #endif
1257 error = nd6_output(ifp, origifp, m, dst, ro->ro_rt, 1);
1258
1259 } else
1260 m_freem(m);
1261 }
1262
1263 if (error == 0)
1264 ip6stat.ip6s_fragmented++;
1265
1266 done:
1267 if (!locked)
1268 lck_mtx_unlock(ip6_mutex);
1269 if (ro == &ip6route && ro->ro_rt) { /* brace necessary for rtfree */
1270 rtfree(ro->ro_rt);
1271 } else if (ro_pmtu == &ip6route && ro_pmtu->ro_rt) {
1272 rtfree(ro_pmtu->ro_rt);
1273 }
1274
1275 #if IPSEC
1276 if (sp != NULL)
1277 key_freesp(sp, KEY_SADB_UNLOCKED);
1278 #endif /* IPSEC */
1279
1280 if (ia != NULL)
1281 ifafree(&ia->ia_ifa);
1282 return(error);
1283
1284 freehdrs:
1285 m_freem(exthdrs.ip6e_hbh); /* m_freem will check if mbuf is 0 */
1286 m_freem(exthdrs.ip6e_dest1);
1287 m_freem(exthdrs.ip6e_rthdr);
1288 m_freem(exthdrs.ip6e_dest2);
1289 /* fall through */
1290 bad:
1291 m_freem(m);
1292 goto done;
1293 }
1294
1295 static int
1296 ip6_copyexthdr(mp, hdr, hlen)
1297 struct mbuf **mp;
1298 caddr_t hdr;
1299 int hlen;
1300 {
1301 struct mbuf *m;
1302
1303 if (hlen > MCLBYTES)
1304 return(ENOBUFS); /* XXX */
1305
1306 MGET(m, M_DONTWAIT, MT_DATA);
1307 if (!m)
1308 return(ENOBUFS);
1309
1310 if (hlen > MLEN) {
1311 MCLGET(m, M_DONTWAIT);
1312 if ((m->m_flags & M_EXT) == 0) {
1313 m_free(m);
1314 return(ENOBUFS);
1315 }
1316 }
1317 m->m_len = hlen;
1318 if (hdr)
1319 bcopy(hdr, mtod(m, caddr_t), hlen);
1320
1321 *mp = m;
1322 return(0);
1323 }
1324
1325 /*
1326 * Insert jumbo payload option.
1327 */
1328 static int
1329 ip6_insert_jumboopt(exthdrs, plen)
1330 struct ip6_exthdrs *exthdrs;
1331 u_int32_t plen;
1332 {
1333 struct mbuf *mopt;
1334 u_char *optbuf;
1335 u_int32_t v;
1336
1337 #define JUMBOOPTLEN 8 /* length of jumbo payload option and padding */
1338
1339 /*
1340 * If there is no hop-by-hop options header, allocate new one.
1341 * If there is one but it doesn't have enough space to store the
1342 * jumbo payload option, allocate a cluster to store the whole options.
1343 * Otherwise, use it to store the options.
1344 */
1345 if (exthdrs->ip6e_hbh == 0) {
1346 MGET(mopt, M_DONTWAIT, MT_DATA);
1347 if (mopt == 0)
1348 return(ENOBUFS);
1349 mopt->m_len = JUMBOOPTLEN;
1350 optbuf = mtod(mopt, u_char *);
1351 optbuf[1] = 0; /* = ((JUMBOOPTLEN) >> 3) - 1 */
1352 exthdrs->ip6e_hbh = mopt;
1353 } else {
1354 struct ip6_hbh *hbh;
1355
1356 mopt = exthdrs->ip6e_hbh;
1357 if (M_TRAILINGSPACE(mopt) < JUMBOOPTLEN) {
1358 /*
1359 * XXX assumption:
1360 * - exthdrs->ip6e_hbh is not referenced from places
1361 * other than exthdrs.
1362 * - exthdrs->ip6e_hbh is not an mbuf chain.
1363 */
1364 int oldoptlen = mopt->m_len;
1365 struct mbuf *n;
1366
1367 /*
1368 * XXX: give up if the whole (new) hbh header does
1369 * not fit even in an mbuf cluster.
1370 */
1371 if (oldoptlen + JUMBOOPTLEN > MCLBYTES)
1372 return(ENOBUFS);
1373
1374 /*
1375 * As a consequence, we must always prepare a cluster
1376 * at this point.
1377 */
1378 MGET(n, M_DONTWAIT, MT_DATA);
1379 if (n) {
1380 MCLGET(n, M_DONTWAIT);
1381 if ((n->m_flags & M_EXT) == 0) {
1382 m_freem(n);
1383 n = NULL;
1384 }
1385 }
1386 if (!n)
1387 return(ENOBUFS);
1388 n->m_len = oldoptlen + JUMBOOPTLEN;
1389 bcopy(mtod(mopt, caddr_t), mtod(n, caddr_t),
1390 oldoptlen);
1391 optbuf = (u_char *) (mtod(n, caddr_t) + oldoptlen);
1392 m_freem(mopt);
1393 mopt = exthdrs->ip6e_hbh = n;
1394 } else {
1395 optbuf = mtod(mopt, u_char *) + mopt->m_len;
1396 mopt->m_len += JUMBOOPTLEN;
1397 }
1398 optbuf[0] = IP6OPT_PADN;
1399 optbuf[1] = 1;
1400
1401 /*
1402 * Adjust the header length according to the pad and
1403 * the jumbo payload option.
1404 */
1405 hbh = mtod(mopt, struct ip6_hbh *);
1406 hbh->ip6h_len += (JUMBOOPTLEN >> 3);
1407 }
1408
1409 /* fill in the option. */
1410 optbuf[2] = IP6OPT_JUMBO;
1411 optbuf[3] = 4;
1412 v = (u_int32_t)htonl(plen + JUMBOOPTLEN);
1413 bcopy(&v, &optbuf[4], sizeof(u_int32_t));
1414
1415 /* finally, adjust the packet header length */
1416 exthdrs->ip6e_ip6->m_pkthdr.len += JUMBOOPTLEN;
1417
1418 return(0);
1419 #undef JUMBOOPTLEN
1420 }
1421
1422 /*
1423 * Insert fragment header and copy unfragmentable header portions.
1424 */
1425 static int
1426 ip6_insertfraghdr(m0, m, hlen, frghdrp)
1427 struct mbuf *m0, *m;
1428 int hlen;
1429 struct ip6_frag **frghdrp;
1430 {
1431 struct mbuf *n, *mlast;
1432
1433 if (hlen > sizeof(struct ip6_hdr)) {
1434 n = m_copym(m0, sizeof(struct ip6_hdr),
1435 hlen - sizeof(struct ip6_hdr), M_DONTWAIT);
1436 if (n == 0)
1437 return(ENOBUFS);
1438 m->m_next = n;
1439 } else
1440 n = m;
1441
1442 /* Search for the last mbuf of unfragmentable part. */
1443 for (mlast = n; mlast->m_next; mlast = mlast->m_next)
1444 ;
1445
1446 if ((mlast->m_flags & M_EXT) == 0 &&
1447 M_TRAILINGSPACE(mlast) >= sizeof(struct ip6_frag)) {
1448 /* use the trailing space of the last mbuf for the fragment hdr */
1449 *frghdrp =
1450 (struct ip6_frag *)(mtod(mlast, caddr_t) + mlast->m_len);
1451 mlast->m_len += sizeof(struct ip6_frag);
1452 m->m_pkthdr.len += sizeof(struct ip6_frag);
1453 } else {
1454 /* allocate a new mbuf for the fragment header */
1455 struct mbuf *mfrg;
1456
1457 MGET(mfrg, M_DONTWAIT, MT_DATA);
1458 if (mfrg == 0)
1459 return(ENOBUFS);
1460 mfrg->m_len = sizeof(struct ip6_frag);
1461 *frghdrp = mtod(mfrg, struct ip6_frag *);
1462 mlast->m_next = mfrg;
1463 }
1464
1465 return(0);
1466 }
1467
1468 extern int load_ipfw(void);
1469
1470 /*
1471 * IP6 socket option processing.
1472 */
1473 int
1474 ip6_ctloutput(so, sopt)
1475 struct socket *so;
1476 struct sockopt *sopt;
1477 {
1478 int privileged;
1479 struct inpcb *in6p = sotoinpcb(so);
1480 int error = 0, optval = 0;
1481 int level, op = -1, optname = 0;
1482 int optlen = 0;
1483 struct proc *p;
1484
1485 if (sopt == NULL) {
1486 panic("ip6_ctloutput: arg soopt is NULL");
1487 /* NOTREACHED */
1488 }
1489 level = sopt->sopt_level;
1490 op = sopt->sopt_dir;
1491 optname = sopt->sopt_name;
1492 optlen = sopt->sopt_valsize;
1493 p = sopt->sopt_p;
1494
1495 privileged = (proc_suser(p) == 0);
1496
1497 if (level == IPPROTO_IPV6) {
1498 switch (op) {
1499
1500 case SOPT_SET:
1501 switch (optname) {
1502 case IPV6_PKTOPTIONS:
1503 {
1504 struct mbuf *m;
1505
1506 if (sopt->sopt_valsize > MCLBYTES) {
1507 error = EMSGSIZE;
1508 break;
1509 }
1510 error = soopt_getm(sopt, &m); /* XXX */
1511 if (error != 0)
1512 break;
1513 error = soopt_mcopyin(sopt, m); /* XXX */
1514 if (error != 0)
1515 break;
1516 error = ip6_pcbopts(&in6p->in6p_outputopts,
1517 m, so, sopt);
1518 m_freem(m); /* XXX */
1519 break;
1520 }
1521
1522 /*
1523 * Use of some Hop-by-Hop options or some
1524 * Destination options, might require special
1525 * privilege. That is, normal applications
1526 * (without special privilege) might be forbidden
1527 * from setting certain options in outgoing packets,
1528 * and might never see certain options in received
1529 * packets. [RFC 2292 Section 6]
1530 * KAME specific note:
1531 * KAME prevents non-privileged users from sending or
1532 * receiving ANY hbh/dst options in order to avoid
1533 * overhead of parsing options in the kernel.
1534 */
1535 case IPV6_UNICAST_HOPS:
1536 case IPV6_CHECKSUM:
1537 case IPV6_FAITH:
1538
1539 case IPV6_RECVTCLASS:
1540 case IPV6_V6ONLY:
1541 if (optlen != sizeof(int)) {
1542 error = EINVAL;
1543 break;
1544 }
1545 error = sooptcopyin(sopt, &optval,
1546 sizeof optval, sizeof optval);
1547 if (error)
1548 break;
1549 switch (optname) {
1550
1551 case IPV6_UNICAST_HOPS:
1552 if (optval < -1 || optval >= 256)
1553 error = EINVAL;
1554 else {
1555 /* -1 = kernel default */
1556 in6p->in6p_hops = optval;
1557
1558 if ((in6p->in6p_vflag &
1559 INP_IPV4) != 0)
1560 in6p->inp_ip_ttl = optval;
1561 }
1562 break;
1563 #define OPTSET(bit) \
1564 do { \
1565 if (optval) \
1566 in6p->in6p_flags |= (bit); \
1567 else \
1568 in6p->in6p_flags &= ~(bit); \
1569 } while (0)
1570 #define OPTBIT(bit) (in6p->in6p_flags & (bit) ? 1 : 0)
1571
1572 case IPV6_CHECKSUM:
1573 in6p->in6p_cksum = optval;
1574 break;
1575
1576 case IPV6_FAITH:
1577 OPTSET(IN6P_FAITH);
1578 break;
1579
1580 case IPV6_V6ONLY:
1581 /*
1582 * make setsockopt(IPV6_V6ONLY)
1583 * available only prior to bind(2).
1584 * see ipng mailing list, Jun 22 2001.
1585 */
1586 if (in6p->in6p_lport ||
1587 !IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr))
1588 {
1589 error = EINVAL;
1590 break;
1591 }
1592 OPTSET(IN6P_IPV6_V6ONLY);
1593 if (optval)
1594 in6p->in6p_vflag &= ~INP_IPV4;
1595 else
1596 in6p->in6p_vflag |= INP_IPV4;
1597 break;
1598 case IPV6_RECVTCLASS:
1599 /* cannot mix with RFC2292 XXX */
1600 OPTSET(IN6P_TCLASS);
1601 break;
1602 }
1603 break;
1604
1605 case IPV6_PKTINFO:
1606 case IPV6_HOPLIMIT:
1607 case IPV6_HOPOPTS:
1608 case IPV6_DSTOPTS:
1609 case IPV6_RTHDR:
1610 /* RFC 2292 */
1611 if (optlen != sizeof(int)) {
1612 error = EINVAL;
1613 break;
1614 }
1615 error = sooptcopyin(sopt, &optval,
1616 sizeof optval, sizeof optval);
1617 if (error)
1618 break;
1619 switch (optname) {
1620 case IPV6_PKTINFO:
1621 OPTSET(IN6P_PKTINFO);
1622 break;
1623 case IPV6_HOPLIMIT:
1624 OPTSET(IN6P_HOPLIMIT);
1625 break;
1626 case IPV6_HOPOPTS:
1627 /*
1628 * Check super-user privilege.
1629 * See comments for IPV6_RECVHOPOPTS.
1630 */
1631 if (!privileged)
1632 return(EPERM);
1633 OPTSET(IN6P_HOPOPTS);
1634 break;
1635 case IPV6_DSTOPTS:
1636 if (!privileged)
1637 return(EPERM);
1638 OPTSET(IN6P_DSTOPTS|IN6P_RTHDRDSTOPTS); /* XXX */
1639 break;
1640 case IPV6_RTHDR:
1641 OPTSET(IN6P_RTHDR);
1642 break;
1643 }
1644 break;
1645 #undef OPTSET
1646
1647 case IPV6_TCLASS:
1648 if (optlen != sizeof(optval)) {
1649 error = EINVAL;
1650 break;
1651 }
1652 error = sooptcopyin(sopt, &optval, sizeof optval, sizeof optval);
1653 if (error)
1654 break;
1655 error = ip6_pcbopt(optname, (u_char *)&optval, sizeof(optval), &in6p->in6p_outputopts);
1656 break;
1657
1658 case IPV6_MULTICAST_IF:
1659 case IPV6_MULTICAST_HOPS:
1660 case IPV6_MULTICAST_LOOP:
1661 case IPV6_JOIN_GROUP:
1662 case IPV6_LEAVE_GROUP:
1663 {
1664 struct mbuf *m;
1665 if (sopt->sopt_valsize > MLEN) {
1666 error = EMSGSIZE;
1667 break;
1668 }
1669 /* XXX */
1670 MGET(m, sopt->sopt_p != kernproc ?
1671 M_WAIT : M_DONTWAIT, MT_HEADER);
1672 if (m == 0) {
1673 error = ENOBUFS;
1674 break;
1675 }
1676 m->m_len = sopt->sopt_valsize;
1677 error = sooptcopyin(sopt, mtod(m, char *),
1678 m->m_len, m->m_len);
1679 error = ip6_setmoptions(sopt->sopt_name, in6p, m);
1680 (void)m_free(m);
1681 }
1682 break;
1683
1684 case IPV6_PORTRANGE:
1685 error = sooptcopyin(sopt, &optval,
1686 sizeof optval, sizeof optval);
1687 if (error)
1688 break;
1689
1690 switch (optval) {
1691 case IPV6_PORTRANGE_DEFAULT:
1692 in6p->in6p_flags &= ~(IN6P_LOWPORT);
1693 in6p->in6p_flags &= ~(IN6P_HIGHPORT);
1694 break;
1695
1696 case IPV6_PORTRANGE_HIGH:
1697 in6p->in6p_flags &= ~(IN6P_LOWPORT);
1698 in6p->in6p_flags |= IN6P_HIGHPORT;
1699 break;
1700
1701 case IPV6_PORTRANGE_LOW:
1702 in6p->in6p_flags &= ~(IN6P_HIGHPORT);
1703 in6p->in6p_flags |= IN6P_LOWPORT;
1704 break;
1705
1706 default:
1707 error = EINVAL;
1708 break;
1709 }
1710 break;
1711
1712 #if IPSEC
1713 case IPV6_IPSEC_POLICY:
1714 {
1715 caddr_t req = NULL;
1716 size_t len = 0;
1717 struct mbuf *m;
1718
1719 if (sopt->sopt_valsize > MCLBYTES) {
1720 error = EMSGSIZE;
1721 break;
1722 }
1723 if ((error = soopt_getm(sopt, &m)) != 0) /* XXX */
1724 break;
1725 if ((error = soopt_mcopyin(sopt, m)) != 0) /* XXX */
1726 break;
1727 if (m) {
1728 req = mtod(m, caddr_t);
1729 len = m->m_len;
1730 }
1731 error = ipsec6_set_policy(in6p, optname, req,
1732 len, privileged);
1733 m_freem(m);
1734 }
1735 break;
1736 #endif /* KAME IPSEC */
1737
1738 #if IPFIREWALL
1739 case IPV6_FW_ADD:
1740 case IPV6_FW_DEL:
1741 case IPV6_FW_FLUSH:
1742 case IPV6_FW_ZERO:
1743 {
1744 if (ip6_fw_ctl_ptr == NULL && load_ipfw() != 0)
1745 return EINVAL;
1746
1747 error = (*ip6_fw_ctl_ptr)(sopt);
1748 }
1749 break;
1750 #endif /* IPFIREWALL */
1751
1752 default:
1753 error = ENOPROTOOPT;
1754 break;
1755 }
1756 break;
1757
1758 case SOPT_GET:
1759 switch (optname) {
1760
1761 case IPV6_PKTOPTIONS:
1762 if (in6p->in6p_options) {
1763 struct mbuf *m;
1764 m = m_copym(in6p->in6p_options,
1765 0, M_COPYALL, M_WAIT);
1766 if (m == NULL) {
1767 error = ENOBUFS;
1768 break;
1769 }
1770 error = soopt_mcopyout(sopt, m);
1771 if (error == 0)
1772 m_freem(m);
1773 } else
1774 sopt->sopt_valsize = 0;
1775 break;
1776
1777 case IPV6_UNICAST_HOPS:
1778 case IPV6_CHECKSUM:
1779
1780 case IPV6_FAITH:
1781 case IPV6_V6ONLY:
1782 case IPV6_PORTRANGE:
1783 case IPV6_RECVTCLASS:
1784 switch (optname) {
1785
1786 case IPV6_UNICAST_HOPS:
1787 optval = in6p->in6p_hops;
1788 break;
1789
1790 case IPV6_CHECKSUM:
1791 optval = in6p->in6p_cksum;
1792 break;
1793
1794 case IPV6_FAITH:
1795 optval = OPTBIT(IN6P_FAITH);
1796 break;
1797
1798 case IPV6_V6ONLY:
1799 optval = OPTBIT(IN6P_IPV6_V6ONLY);
1800 break;
1801
1802 case IPV6_PORTRANGE:
1803 {
1804 int flags;
1805 flags = in6p->in6p_flags;
1806 if (flags & IN6P_HIGHPORT)
1807 optval = IPV6_PORTRANGE_HIGH;
1808 else if (flags & IN6P_LOWPORT)
1809 optval = IPV6_PORTRANGE_LOW;
1810 else
1811 optval = 0;
1812 break;
1813 }
1814 case IPV6_RECVTCLASS:
1815 optval = OPTBIT(IN6P_TCLASS);
1816 break;
1817
1818 }
1819 error = sooptcopyout(sopt, &optval,
1820 sizeof optval);
1821 break;
1822
1823 case IPV6_PKTINFO:
1824 case IPV6_HOPLIMIT:
1825 case IPV6_HOPOPTS:
1826 case IPV6_RTHDR:
1827 case IPV6_DSTOPTS:
1828 if ((optname == IPV6_HOPOPTS ||
1829 optname == IPV6_DSTOPTS) &&
1830 !privileged)
1831 return(EPERM);
1832 switch (optname) {
1833 case IPV6_PKTINFO:
1834 optval = OPTBIT(IN6P_PKTINFO);
1835 break;
1836 case IPV6_HOPLIMIT:
1837 optval = OPTBIT(IN6P_HOPLIMIT);
1838 break;
1839 case IPV6_HOPOPTS:
1840 if (!privileged)
1841 return(EPERM);
1842 optval = OPTBIT(IN6P_HOPOPTS);
1843 break;
1844 case IPV6_RTHDR:
1845 optval = OPTBIT(IN6P_RTHDR);
1846 break;
1847 case IPV6_DSTOPTS:
1848 if (!privileged)
1849 return(EPERM);
1850 optval = OPTBIT(IN6P_DSTOPTS|IN6P_RTHDRDSTOPTS);
1851 break;
1852 }
1853 error = sooptcopyout(sopt, &optval,
1854 sizeof optval);
1855 break;
1856
1857 case IPV6_TCLASS:
1858 error = ip6_getpcbopt(in6p->in6p_outputopts, optname, sopt);
1859 break;
1860
1861 case IPV6_MULTICAST_IF:
1862 case IPV6_MULTICAST_HOPS:
1863 case IPV6_MULTICAST_LOOP:
1864 case IPV6_JOIN_GROUP:
1865 case IPV6_LEAVE_GROUP:
1866 {
1867 struct mbuf *m;
1868 error = ip6_getmoptions(sopt->sopt_name,
1869 in6p->in6p_moptions, &m);
1870 if (error == 0)
1871 error = sooptcopyout(sopt,
1872 mtod(m, char *), m->m_len);
1873 if (m != NULL)
1874 m_freem(m);
1875 }
1876 break;
1877
1878 #if IPSEC
1879 case IPV6_IPSEC_POLICY:
1880 {
1881 caddr_t req = NULL;
1882 size_t len = 0;
1883 struct mbuf *m = NULL;
1884 struct mbuf **mp = &m;
1885
1886 if (sopt->sopt_valsize > MCLBYTES) {
1887 error = EMSGSIZE;
1888 break;
1889 }
1890 error = soopt_getm(sopt, &m); /* XXX */
1891 if (error != 0)
1892 break;
1893 error = soopt_mcopyin(sopt, m); /* XXX */
1894 if (error != 0)
1895 break;
1896 if (m) {
1897 req = mtod(m, caddr_t);
1898 len = m->m_len;
1899 }
1900 error = ipsec6_get_policy(in6p, req, len, mp);
1901 if (error == 0)
1902 error = soopt_mcopyout(sopt, m); /*XXX*/
1903 if (error == 0 && m)
1904 m_freem(m);
1905 break;
1906 }
1907 #endif /* KAME IPSEC */
1908
1909 #if IPFIREWALL
1910 case IPV6_FW_GET:
1911 {
1912 if (ip6_fw_ctl_ptr == NULL && load_ipfw() != 0)
1913 return EINVAL;
1914
1915 error = (*ip6_fw_ctl_ptr)(sopt);
1916 }
1917 break;
1918 #endif /* IPFIREWALL */
1919
1920 default:
1921 error = ENOPROTOOPT;
1922 break;
1923 }
1924 break;
1925 }
1926 } else {
1927 error = EINVAL;
1928 }
1929 return(error);
1930 }
1931
1932 /*
1933 * Set up IP6 options in pcb for insertion in output packets or
1934 * specifying behavior of outgoing packets.
1935 */
1936 static int
1937 ip6_pcbopts(
1938 struct ip6_pktopts **pktopt,
1939 struct mbuf *m,
1940 __unused struct socket *so,
1941 struct sockopt *sopt)
1942 {
1943 struct ip6_pktopts *opt = *pktopt;
1944 int error = 0, priv;
1945 struct proc *p = sopt->sopt_p;
1946
1947 /* turn off any old options. */
1948 if (opt) {
1949 #if DIAGNOSTIC
1950 if (opt->ip6po_pktinfo || opt->ip6po_nexthop ||
1951 opt->ip6po_hbh || opt->ip6po_dest1 || opt->ip6po_dest2 ||
1952 opt->ip6po_rhinfo.ip6po_rhi_rthdr)
1953 printf("ip6_pcbopts: all specified options are cleared.\n");
1954 #endif
1955 ip6_clearpktopts(opt, 1, -1);
1956 } else {
1957 opt = _MALLOC(sizeof(*opt), M_IP6OPT, M_WAITOK);
1958 if (opt == NULL)
1959 return ENOBUFS;
1960 }
1961 *pktopt = NULL;
1962
1963 if (!m || m->m_len == 0) {
1964 /*
1965 * Only turning off any previous options, regardless of
1966 * whether the opt is just created or given.
1967 */
1968 if (opt)
1969 FREE(opt, M_IP6OPT);
1970 return(0);
1971 }
1972
1973 priv = (proc_suser(p) == 0);
1974
1975 /* set options specified by user. */
1976 if ((error = ip6_setpktoptions(m, opt, priv, 1)) != 0) {
1977 ip6_clearpktopts(opt, 1, -1); /* XXX: discard all options */
1978 FREE(opt, M_IP6OPT);
1979 return(error);
1980 }
1981 *pktopt = opt;
1982 return(0);
1983 }
1984
1985 static int
1986 ip6_pcbopt(int optname, u_char *buf, int len, struct ip6_pktopts **pktopt)
1987 {
1988 struct ip6_pktopts *opt;
1989
1990 opt = *pktopt;
1991 if (opt == NULL) {
1992 opt = _MALLOC(sizeof(*opt), M_IP6OPT, M_WAITOK);
1993 ip6_initpktopts(opt);
1994 *pktopt = opt;
1995 }
1996
1997 return (ip6_setpktopt(optname, buf, len, opt));
1998 }
1999
2000 static int
2001 ip6_getpcbopt(struct ip6_pktopts *pktopt, int optname, struct sockopt *sopt)
2002 {
2003 void *optdata = NULL;
2004 int optdatalen = 0;
2005 int deftclass = 0;
2006 int error = 0;
2007
2008 switch (optname) {
2009 case IPV6_TCLASS:
2010 if (pktopt && pktopt->ip6po_tclass >= 0)
2011 optdata = &pktopt->ip6po_tclass;
2012 else
2013 optdata = &deftclass;
2014 optdatalen = sizeof(int);
2015 break;
2016 default: /* should not happen */
2017 #ifdef DIAGNOSTIC
2018 panic("ip6_getpcbopt: unexpected option\n");
2019 #endif
2020 return (ENOPROTOOPT);
2021 }
2022
2023 error = sooptcopyout(sopt, optdata, optdatalen);
2024 return (error);
2025 }
2026
2027 static int
2028 ip6_setpktopt(int optname, u_char *buf, int len, struct ip6_pktopts *opt)
2029 {
2030 switch (optname) {
2031 case IPV6_TCLASS:
2032 {
2033 int tclass;
2034
2035 if (len != sizeof(int))
2036 return (EINVAL);
2037 tclass = *(int *)buf;
2038 if (tclass < -1 || tclass > 255)
2039 return (EINVAL);
2040
2041 opt->ip6po_tclass = tclass;
2042 break;
2043 }
2044
2045 default:
2046 return (ENOPROTOOPT);
2047 } /* end of switch */
2048
2049 return (0);
2050 }
2051
2052 /*
2053 * initialize ip6_pktopts. beware that there are non-zero default values in
2054 * the struct.
2055 */
2056 void
2057 ip6_initpktopts(opt)
2058 struct ip6_pktopts *opt;
2059 {
2060 bzero(opt, sizeof(*opt));
2061 opt->ip6po_hlim = -1; /* -1 means default hop limit */
2062 opt->ip6po_tclass = -1; /* -1 means default traffic class */
2063 }
2064
2065 void
2066 ip6_clearpktopts(pktopt, needfree, optname)
2067 struct ip6_pktopts *pktopt;
2068 int needfree, optname;
2069 {
2070 if (pktopt == NULL)
2071 return;
2072
2073 if (optname == -1) {
2074 if (needfree && pktopt->ip6po_pktinfo)
2075 FREE(pktopt->ip6po_pktinfo, M_IP6OPT);
2076 pktopt->ip6po_pktinfo = NULL;
2077 }
2078 if (optname == -1)
2079 pktopt->ip6po_hlim = -1;
2080 if (optname == -1)
2081 pktopt->ip6po_tclass = -1;
2082 if (optname == -1) {
2083 if (needfree && pktopt->ip6po_nexthop)
2084 FREE(pktopt->ip6po_nexthop, M_IP6OPT);
2085 pktopt->ip6po_nexthop = NULL;
2086 }
2087 if (optname == -1) {
2088 if (needfree && pktopt->ip6po_hbh)
2089 FREE(pktopt->ip6po_hbh, M_IP6OPT);
2090 pktopt->ip6po_hbh = NULL;
2091 }
2092 if (optname == -1) {
2093 if (needfree && pktopt->ip6po_dest1)
2094 FREE(pktopt->ip6po_dest1, M_IP6OPT);
2095 pktopt->ip6po_dest1 = NULL;
2096 }
2097 if (optname == -1) {
2098 if (needfree && pktopt->ip6po_rhinfo.ip6po_rhi_rthdr)
2099 FREE(pktopt->ip6po_rhinfo.ip6po_rhi_rthdr, M_IP6OPT);
2100 pktopt->ip6po_rhinfo.ip6po_rhi_rthdr = NULL;
2101 if (pktopt->ip6po_route.ro_rt) {
2102 rtfree(pktopt->ip6po_route.ro_rt);
2103 pktopt->ip6po_route.ro_rt = NULL;
2104 }
2105 }
2106 if (optname == -1) {
2107 if (needfree && pktopt->ip6po_dest2)
2108 FREE(pktopt->ip6po_dest2, M_IP6OPT);
2109 pktopt->ip6po_dest2 = NULL;
2110 }
2111 }
2112
2113 #define PKTOPT_EXTHDRCPY(type) \
2114 do {\
2115 if (src->type) {\
2116 int hlen =\
2117 (((struct ip6_ext *)src->type)->ip6e_len + 1) << 3;\
2118 dst->type = _MALLOC(hlen, M_IP6OPT, canwait);\
2119 if (dst->type == NULL && canwait == M_NOWAIT)\
2120 goto bad;\
2121 bcopy(src->type, dst->type, hlen);\
2122 }\
2123 } while (0)
2124
2125 struct ip6_pktopts *
2126 ip6_copypktopts(src, canwait)
2127 struct ip6_pktopts *src;
2128 int canwait;
2129 {
2130 struct ip6_pktopts *dst;
2131
2132 if (src == NULL) {
2133 printf("ip6_clearpktopts: invalid argument\n");
2134 return(NULL);
2135 }
2136
2137 dst = _MALLOC(sizeof(*dst), M_IP6OPT, canwait);
2138 if (dst == NULL && canwait == M_NOWAIT)
2139 return (NULL);
2140 bzero(dst, sizeof(*dst));
2141
2142 dst->ip6po_hlim = src->ip6po_hlim;
2143 dst->ip6po_tclass = src->ip6po_tclass;
2144 if (src->ip6po_pktinfo) {
2145 dst->ip6po_pktinfo = _MALLOC(sizeof(*dst->ip6po_pktinfo),
2146 M_IP6OPT, canwait);
2147 if (dst->ip6po_pktinfo == NULL && canwait == M_NOWAIT)
2148 goto bad;
2149 *dst->ip6po_pktinfo = *src->ip6po_pktinfo;
2150 }
2151 if (src->ip6po_nexthop) {
2152 dst->ip6po_nexthop = _MALLOC(src->ip6po_nexthop->sa_len,
2153 M_IP6OPT, canwait);
2154 if (dst->ip6po_nexthop == NULL && canwait == M_NOWAIT)
2155 goto bad;
2156 bcopy(src->ip6po_nexthop, dst->ip6po_nexthop,
2157 src->ip6po_nexthop->sa_len);
2158 }
2159 PKTOPT_EXTHDRCPY(ip6po_hbh);
2160 PKTOPT_EXTHDRCPY(ip6po_dest1);
2161 PKTOPT_EXTHDRCPY(ip6po_dest2);
2162 PKTOPT_EXTHDRCPY(ip6po_rthdr); /* not copy the cached route */
2163 return(dst);
2164
2165 bad:
2166 if (dst->ip6po_pktinfo) FREE(dst->ip6po_pktinfo, M_IP6OPT);
2167 if (dst->ip6po_nexthop) FREE(dst->ip6po_nexthop, M_IP6OPT);
2168 if (dst->ip6po_hbh) FREE(dst->ip6po_hbh, M_IP6OPT);
2169 if (dst->ip6po_dest1) FREE(dst->ip6po_dest1, M_IP6OPT);
2170 if (dst->ip6po_dest2) FREE(dst->ip6po_dest2, M_IP6OPT);
2171 if (dst->ip6po_rthdr) FREE(dst->ip6po_rthdr, M_IP6OPT);
2172 FREE(dst, M_IP6OPT);
2173 return(NULL);
2174 }
2175 #undef PKTOPT_EXTHDRCPY
2176
2177 void
2178 ip6_freepcbopts(pktopt)
2179 struct ip6_pktopts *pktopt;
2180 {
2181 if (pktopt == NULL)
2182 return;
2183
2184 ip6_clearpktopts(pktopt, 1, -1);
2185
2186 FREE(pktopt, M_IP6OPT);
2187 }
2188
2189 /*
2190 * Set the IP6 multicast options in response to user setsockopt().
2191 */
2192 static int
2193 ip6_setmoptions(
2194 int optname,
2195 struct inpcb* in6p,
2196 struct mbuf *m)
2197 {
2198 int error = 0;
2199 u_int loop, ifindex;
2200 struct ipv6_mreq *mreq;
2201 struct ifnet *ifp;
2202 struct ip6_moptions **im6op = &in6p->in6p_moptions;
2203 struct ip6_moptions *im6o = *im6op;
2204 struct ip_moptions *imo;
2205 struct route_in6 ro;
2206 struct sockaddr_in6 *dst;
2207 struct in6_multi_mship *imm;
2208
2209 if (im6o == NULL) {
2210 /*
2211 * No multicast option buffer attached to the pcb;
2212 * allocate one and initialize to default values.
2213 */
2214 im6o = (struct ip6_moptions *)
2215 _MALLOC(sizeof(*im6o), M_IPMOPTS, M_WAITOK);
2216
2217 if (im6o == NULL)
2218 return(ENOBUFS);
2219 *im6op = im6o;
2220 im6o->im6o_multicast_ifp = NULL;
2221 im6o->im6o_multicast_hlim = ip6_defmcasthlim;
2222 im6o->im6o_multicast_loop = IPV6_DEFAULT_MULTICAST_LOOP;
2223 LIST_INIT(&im6o->im6o_memberships);
2224 }
2225
2226 if (in6p->inp_moptions == NULL) {
2227 /*
2228 * No IPv4 multicast option buffer attached to the pcb;
2229 * call ip_createmoptions to allocate one and initialize
2230 * to default values.
2231 */
2232 error = ip_createmoptions(&in6p->inp_moptions);
2233 if (error != 0)
2234 return error;
2235 }
2236 imo = in6p->inp_moptions;
2237
2238 switch (optname) {
2239
2240 case IPV6_MULTICAST_IF:
2241 /*
2242 * Select the interface for outgoing multicast packets.
2243 */
2244 if (m == NULL || m->m_len != sizeof(u_int)) {
2245 error = EINVAL;
2246 break;
2247 }
2248 bcopy(mtod(m, u_int *), &ifindex, sizeof(ifindex));
2249
2250 ifnet_head_lock_shared();
2251 /* Don't need to check is ifindex is < 0 since it's unsigned */
2252 if (if_index < ifindex) {
2253 error = ENXIO; /* XXX EINVAL? */
2254 ifnet_head_done();
2255 break;
2256 }
2257 ifp = ifindex2ifnet[ifindex];
2258 ifnet_head_done();
2259 if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {
2260 error = EADDRNOTAVAIL;
2261 break;
2262 }
2263 im6o->im6o_multicast_ifp = ifp;
2264 imo->imo_multicast_ifp = ifp;
2265 break;
2266
2267 case IPV6_MULTICAST_HOPS:
2268 {
2269 /*
2270 * Set the IP6 hoplimit for outgoing multicast packets.
2271 */
2272 int optval;
2273 if (m == NULL || m->m_len != sizeof(int)) {
2274 error = EINVAL;
2275 break;
2276 }
2277 bcopy(mtod(m, u_int *), &optval, sizeof(optval));
2278 if (optval < -1 || optval >= 256)
2279 error = EINVAL;
2280 else if (optval == -1) {
2281 im6o->im6o_multicast_hlim = ip6_defmcasthlim;
2282 imo->imo_multicast_ttl = IP_DEFAULT_MULTICAST_TTL;
2283 } else {
2284 im6o->im6o_multicast_hlim = optval;
2285 imo->imo_multicast_ttl = optval;
2286 }
2287 break;
2288 }
2289
2290 case IPV6_MULTICAST_LOOP:
2291 /*
2292 * Set the loopback flag for outgoing multicast packets.
2293 * Must be zero or one.
2294 */
2295 if (m == NULL || m->m_len != sizeof(u_int)) {
2296 error = EINVAL;
2297 break;
2298 }
2299 bcopy(mtod(m, u_int *), &loop, sizeof(loop));
2300 if (loop > 1) {
2301 error = EINVAL;
2302 break;
2303 }
2304 im6o->im6o_multicast_loop = loop;
2305 imo->imo_multicast_loop = loop;
2306 break;
2307
2308 case IPV6_JOIN_GROUP:
2309 /*
2310 * Add a multicast group membership.
2311 * Group must be a valid IP6 multicast address.
2312 */
2313 if (m == NULL || m->m_len != sizeof(struct ipv6_mreq)) {
2314 error = EINVAL;
2315 break;
2316 }
2317 mreq = mtod(m, struct ipv6_mreq *);
2318 /*
2319 * If the interface is specified, validate it.
2320 *
2321 * Don't need to check if it's < 0, since it's unsigned
2322 */
2323 ifnet_head_lock_shared();
2324 if (if_index < mreq->ipv6mr_interface) {
2325 ifnet_head_done();
2326 error = ENXIO; /* XXX EINVAL? */
2327 break;
2328 }
2329 ifp = ifindex2ifnet[mreq->ipv6mr_interface];
2330 ifnet_head_done();
2331
2332 if (IN6_IS_ADDR_UNSPECIFIED(&mreq->ipv6mr_multiaddr)) {
2333 /*
2334 * We use the unspecified address to specify to accept
2335 * all multicast addresses. Only super user is allowed
2336 * to do this.
2337 */
2338 if (suser(kauth_cred_get(), 0))
2339 {
2340 error = EACCES;
2341 break;
2342 }
2343 } else if (IN6_IS_ADDR_V4MAPPED(&mreq->ipv6mr_multiaddr)) {
2344 struct ip_mreq v4req;
2345
2346 v4req.imr_multiaddr.s_addr = mreq->ipv6mr_multiaddr.s6_addr32[3];
2347 v4req.imr_interface.s_addr = INADDR_ANY;
2348
2349 /* Find an IPv4 address on the specified interface. */
2350 if (mreq->ipv6mr_interface != 0) {
2351 struct in_ifaddr *ifa;
2352
2353 lck_rw_lock_shared(in_ifaddr_rwlock);
2354 TAILQ_FOREACH(ifa, &in_ifaddrhead, ia_link) {
2355 if (ifa->ia_ifp == ifp) {
2356 v4req.imr_interface = IA_SIN(ifa)->sin_addr;
2357 break;
2358 }
2359 }
2360 lck_rw_done(in_ifaddr_rwlock);
2361
2362 if (v4req.imr_multiaddr.s_addr == 0) {
2363 /* Interface has no IPv4 address. */
2364 error = EINVAL;
2365 break;
2366 }
2367 }
2368
2369 error = ip_addmembership(imo, &v4req);
2370 break;
2371 } else if (!IN6_IS_ADDR_MULTICAST(&mreq->ipv6mr_multiaddr)) {
2372 error = EINVAL;
2373 break;
2374 }
2375 /*
2376 * If no interface was explicitly specified, choose an
2377 * appropriate one according to the given multicast address.
2378 */
2379 if (mreq->ipv6mr_interface == 0) {
2380 /*
2381 * If the multicast address is in node-local scope,
2382 * the interface should be a loopback interface.
2383 * Otherwise, look up the routing table for the
2384 * address, and choose the outgoing interface.
2385 * XXX: is it a good approach?
2386 */
2387 if (IN6_IS_ADDR_MC_NODELOCAL(&mreq->ipv6mr_multiaddr)) {
2388 ifp = lo_ifp;
2389 } else {
2390 ro.ro_rt = NULL;
2391 dst = (struct sockaddr_in6 *)&ro.ro_dst;
2392 bzero(dst, sizeof(*dst));
2393 dst->sin6_len = sizeof(struct sockaddr_in6);
2394 dst->sin6_family = AF_INET6;
2395 dst->sin6_addr = mreq->ipv6mr_multiaddr;
2396 rtalloc((struct route *)&ro);
2397 if (ro.ro_rt == NULL) {
2398 error = EADDRNOTAVAIL;
2399 break;
2400 }
2401 ifp = ro.ro_rt->rt_ifp;
2402 rtfree(ro.ro_rt);
2403 ro.ro_rt = NULL;
2404 }
2405 }
2406
2407 /*
2408 * See if we found an interface, and confirm that it
2409 * supports multicast
2410 */
2411 if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {
2412 error = EADDRNOTAVAIL;
2413 break;
2414 }
2415 /*
2416 * Put interface index into the multicast address,
2417 * if the address has link-local scope.
2418 */
2419 if (IN6_IS_ADDR_MC_LINKLOCAL(&mreq->ipv6mr_multiaddr)) {
2420 mreq->ipv6mr_multiaddr.s6_addr16[1]
2421 = htons(mreq->ipv6mr_interface);
2422 }
2423 /*
2424 * See if the membership already exists.
2425 */
2426 lck_mtx_lock(nd6_mutex);
2427 for (imm = im6o->im6o_memberships.lh_first;
2428 imm != NULL; imm = imm->i6mm_chain.le_next)
2429 if (imm->i6mm_maddr->in6m_ifp == ifp &&
2430 IN6_ARE_ADDR_EQUAL(&imm->i6mm_maddr->in6m_addr,
2431 &mreq->ipv6mr_multiaddr))
2432 break;
2433 if (imm != NULL) {
2434 error = EADDRINUSE;
2435 lck_mtx_unlock(nd6_mutex);
2436 break;
2437 }
2438 /*
2439 * Everything looks good; add a new record to the multicast
2440 * address list for the given interface.
2441 */
2442 imm = _MALLOC(sizeof(*imm), M_IPMADDR, M_WAITOK);
2443 if (imm == NULL) {
2444 error = ENOBUFS;
2445 lck_mtx_unlock(nd6_mutex);
2446 break;
2447 }
2448 if ((imm->i6mm_maddr =
2449 in6_addmulti(&mreq->ipv6mr_multiaddr, ifp, &error, 1)) == NULL) {
2450 FREE(imm, M_IPMADDR);
2451 lck_mtx_unlock(nd6_mutex);
2452 break;
2453 }
2454 LIST_INSERT_HEAD(&im6o->im6o_memberships, imm, i6mm_chain);
2455 lck_mtx_unlock(nd6_mutex);
2456 break;
2457
2458 case IPV6_LEAVE_GROUP:
2459 /*
2460 * Drop a multicast group membership.
2461 * Group must be a valid IP6 multicast address.
2462 */
2463 if (m == NULL || m->m_len != sizeof(struct ipv6_mreq)) {
2464 error = EINVAL;
2465 break;
2466 }
2467 mreq = mtod(m, struct ipv6_mreq *);
2468 /*
2469 * If an interface address was specified, get a pointer
2470 * to its ifnet structure.
2471 *
2472 * Don't need to check if it's < 0, since it's unsigned.
2473 */
2474 ifnet_head_lock_shared();
2475 if (if_index < mreq->ipv6mr_interface) {
2476 ifnet_head_done();
2477 error = ENXIO; /* XXX EINVAL? */
2478 break;
2479 }
2480 ifp = ifindex2ifnet[mreq->ipv6mr_interface];
2481 ifnet_head_done();
2482
2483 if (IN6_IS_ADDR_UNSPECIFIED(&mreq->ipv6mr_multiaddr)) {
2484 if (suser(kauth_cred_get(), 0)) {
2485 error = EACCES;
2486 break;
2487 }
2488 } else if (IN6_IS_ADDR_V4MAPPED(&mreq->ipv6mr_multiaddr)) {
2489 struct ip_mreq v4req;
2490
2491 v4req.imr_multiaddr.s_addr = mreq->ipv6mr_multiaddr.s6_addr32[3];
2492 v4req.imr_interface.s_addr = INADDR_ANY;
2493
2494 if (ifp != NULL) {
2495 struct in_ifaddr *ifa;
2496
2497 lck_rw_lock_shared(in_ifaddr_rwlock);
2498 TAILQ_FOREACH(ifa, &in_ifaddrhead, ia_link) {
2499 if (ifa->ia_ifp == ifp) {
2500 v4req.imr_interface = IA_SIN(ifa)->sin_addr;
2501 break;
2502 }
2503 }
2504 lck_rw_done(in_ifaddr_rwlock);
2505 }
2506
2507 error = ip_dropmembership(imo, &v4req);
2508 break;
2509 } else if (!IN6_IS_ADDR_MULTICAST(&mreq->ipv6mr_multiaddr)) {
2510 error = EINVAL;
2511 break;
2512 }
2513 /*
2514 * Put interface index into the multicast address,
2515 * if the address has link-local scope.
2516 */
2517 if (IN6_IS_ADDR_MC_LINKLOCAL(&mreq->ipv6mr_multiaddr)) {
2518 mreq->ipv6mr_multiaddr.s6_addr16[1]
2519 = htons(mreq->ipv6mr_interface);
2520 }
2521 /*
2522 * Find the membership in the membership list.
2523 */
2524 lck_mtx_lock(nd6_mutex);
2525 for (imm = im6o->im6o_memberships.lh_first;
2526 imm != NULL; imm = imm->i6mm_chain.le_next) {
2527 if ((ifp == NULL ||
2528 imm->i6mm_maddr->in6m_ifp == ifp) &&
2529 IN6_ARE_ADDR_EQUAL(&imm->i6mm_maddr->in6m_addr,
2530 &mreq->ipv6mr_multiaddr))
2531 break;
2532 }
2533 if (imm == NULL) {
2534 /* Unable to resolve interface */
2535 error = EADDRNOTAVAIL;
2536 lck_mtx_unlock(nd6_mutex);
2537 break;
2538 }
2539 /*
2540 * Give up the multicast address record to which the
2541 * membership points.
2542 */
2543 LIST_REMOVE(imm, i6mm_chain);
2544 in6_delmulti(imm->i6mm_maddr, 1);
2545 lck_mtx_unlock(nd6_mutex);
2546 FREE(imm, M_IPMADDR);
2547 break;
2548
2549 default:
2550 error = EOPNOTSUPP;
2551 break;
2552 }
2553
2554 /*
2555 * If all options have default values, no need to keep the mbuf.
2556 */
2557 lck_mtx_lock(nd6_mutex);
2558 if (im6o->im6o_multicast_ifp == NULL &&
2559 im6o->im6o_multicast_hlim == ip6_defmcasthlim &&
2560 im6o->im6o_multicast_loop == IPV6_DEFAULT_MULTICAST_LOOP &&
2561 im6o->im6o_memberships.lh_first == NULL) {
2562 FREE(*im6op, M_IPMOPTS);
2563 *im6op = NULL;
2564 }
2565 if (imo->imo_multicast_ifp == NULL &&
2566 imo->imo_multicast_vif == -1 &&
2567 imo->imo_multicast_ttl == IP_DEFAULT_MULTICAST_TTL &&
2568 imo->imo_multicast_loop == IP_DEFAULT_MULTICAST_LOOP &&
2569 imo->imo_num_memberships == 0) {
2570 ip_freemoptions(imo);
2571 in6p->inp_moptions = 0;
2572 }
2573 lck_mtx_unlock(nd6_mutex);
2574
2575 return(error);
2576 }
2577
2578 /*
2579 * Return the IP6 multicast options in response to user getsockopt().
2580 */
2581 static int
2582 ip6_getmoptions(optname, im6o, mp)
2583 int optname;
2584 struct ip6_moptions *im6o;
2585 struct mbuf **mp;
2586 {
2587 u_int *hlim, *loop, *ifindex;
2588
2589 *mp = m_get(M_WAIT, MT_HEADER); /*XXX*/
2590 if (*mp == NULL)
2591 return ENOBUFS;
2592
2593 switch (optname) {
2594
2595 case IPV6_MULTICAST_IF:
2596 ifindex = mtod(*mp, u_int *);
2597 (*mp)->m_len = sizeof(u_int);
2598 if (im6o == NULL || im6o->im6o_multicast_ifp == NULL)
2599 *ifindex = 0;
2600 else
2601 *ifindex = im6o->im6o_multicast_ifp->if_index;
2602 return(0);
2603
2604 case IPV6_MULTICAST_HOPS:
2605 hlim = mtod(*mp, u_int *);
2606 (*mp)->m_len = sizeof(u_int);
2607 if (im6o == NULL)
2608 *hlim = ip6_defmcasthlim;
2609 else
2610 *hlim = im6o->im6o_multicast_hlim;
2611 return(0);
2612
2613 case IPV6_MULTICAST_LOOP:
2614 loop = mtod(*mp, u_int *);
2615 (*mp)->m_len = sizeof(u_int);
2616 if (im6o == NULL)
2617 *loop = ip6_defmcasthlim;
2618 else
2619 *loop = im6o->im6o_multicast_loop;
2620 return(0);
2621
2622 default:
2623 return(EOPNOTSUPP);
2624 }
2625 }
2626
2627 /*
2628 * Discard the IP6 multicast options.
2629 */
2630 void
2631 ip6_freemoptions(im6o)
2632 struct ip6_moptions *im6o;
2633 {
2634 struct in6_multi_mship *imm;
2635
2636 if (im6o == NULL)
2637 return;
2638
2639 lck_mtx_lock(nd6_mutex);
2640 while ((imm = im6o->im6o_memberships.lh_first) != NULL) {
2641 LIST_REMOVE(imm, i6mm_chain);
2642 if (imm->i6mm_maddr)
2643 in6_delmulti(imm->i6mm_maddr, 1);
2644 FREE(imm, M_IPMADDR);
2645 }
2646 lck_mtx_unlock(nd6_mutex);
2647 FREE(im6o, M_IPMOPTS);
2648 }
2649
2650 /*
2651 * Set IPv6 outgoing packet options based on advanced API.
2652 */
2653 int
2654 ip6_setpktoptions(control, opt, priv, needcopy)
2655 struct mbuf *control;
2656 struct ip6_pktopts *opt;
2657 int priv, needcopy;
2658 {
2659 struct cmsghdr *cm = 0;
2660
2661 if (control == 0 || opt == 0)
2662 return(EINVAL);
2663
2664 ip6_initpktopts(opt);
2665
2666 /*
2667 * XXX: Currently, we assume all the optional information is stored
2668 * in a single mbuf.
2669 */
2670 if (control->m_next)
2671 return(EINVAL);
2672
2673 for (; control->m_len; control->m_data += CMSG_ALIGN(cm->cmsg_len),
2674 control->m_len -= CMSG_ALIGN(cm->cmsg_len)) {
2675 cm = mtod(control, struct cmsghdr *);
2676 if (cm->cmsg_len == 0 || cm->cmsg_len > control->m_len)
2677 return(EINVAL);
2678 if (cm->cmsg_level != IPPROTO_IPV6)
2679 continue;
2680
2681 /*
2682 * XXX should check if RFC2292 API is mixed with 2292bis API
2683 */
2684 switch (cm->cmsg_type) {
2685 case IPV6_PKTINFO:
2686 if (cm->cmsg_len != CMSG_LEN(sizeof(struct in6_pktinfo)))
2687 return(EINVAL);
2688 if (needcopy) {
2689 /* XXX: Is it really WAITOK? */
2690 opt->ip6po_pktinfo =
2691 _MALLOC(sizeof(struct in6_pktinfo),
2692 M_IP6OPT, M_WAITOK);
2693 if (opt->ip6po_pktinfo == NULL)
2694 return ENOBUFS;
2695 bcopy(CMSG_DATA(cm), opt->ip6po_pktinfo,
2696 sizeof(struct in6_pktinfo));
2697 } else
2698 opt->ip6po_pktinfo =
2699 (struct in6_pktinfo *)CMSG_DATA(cm);
2700 if (opt->ip6po_pktinfo->ipi6_ifindex &&
2701 IN6_IS_ADDR_LINKLOCAL(&opt->ip6po_pktinfo->ipi6_addr))
2702 opt->ip6po_pktinfo->ipi6_addr.s6_addr16[1] =
2703 htons(opt->ip6po_pktinfo->ipi6_ifindex);
2704
2705 if (opt->ip6po_pktinfo->ipi6_ifindex > if_index) {
2706 return(ENXIO);
2707 }
2708
2709 /*
2710 * Check if the requested source address is indeed a
2711 * unicast address assigned to the node, and can be
2712 * used as the packet's source address.
2713 */
2714 if (!IN6_IS_ADDR_UNSPECIFIED(&opt->ip6po_pktinfo->ipi6_addr)) {
2715 struct in6_ifaddr *ia6;
2716 struct sockaddr_in6 sin6;
2717
2718 bzero(&sin6, sizeof(sin6));
2719 sin6.sin6_len = sizeof(sin6);
2720 sin6.sin6_family = AF_INET6;
2721 sin6.sin6_addr =
2722 opt->ip6po_pktinfo->ipi6_addr;
2723 ia6 = (struct in6_ifaddr *)ifa_ifwithaddr(sin6tosa(&sin6));
2724 if (ia6 == NULL ||
2725 (ia6->ia6_flags & (IN6_IFF_ANYCAST |
2726 IN6_IFF_NOTREADY)) != 0) {
2727 if (ia6) ifafree(&ia6->ia_ifa);
2728 return(EADDRNOTAVAIL);
2729 }
2730 ifafree(&ia6->ia_ifa);
2731 ia6 = NULL;
2732 }
2733 break;
2734
2735 case IPV6_HOPLIMIT:
2736 if (cm->cmsg_len != CMSG_LEN(sizeof(int)))
2737 return(EINVAL);
2738
2739 opt->ip6po_hlim = *(int *)CMSG_DATA(cm);
2740 if (opt->ip6po_hlim < -1 || opt->ip6po_hlim > 255)
2741 return(EINVAL);
2742 break;
2743
2744 case IPV6_TCLASS:
2745 if (cm->cmsg_len != CMSG_LEN(sizeof(int)))
2746 return(EINVAL);
2747
2748 opt->ip6po_tclass = *(int *)CMSG_DATA(cm);
2749 if (opt->ip6po_tclass < -1 || opt->ip6po_tclass > 255)
2750 return (EINVAL);
2751 break;
2752
2753 case IPV6_NEXTHOP:
2754 if (!priv)
2755 return(EPERM);
2756
2757 if (cm->cmsg_len < sizeof(u_char) ||
2758 /* check if cmsg_len is large enough for sa_len */
2759 cm->cmsg_len < CMSG_LEN(*CMSG_DATA(cm)))
2760 return(EINVAL);
2761
2762 if (needcopy) {
2763 opt->ip6po_nexthop =
2764 _MALLOC(*CMSG_DATA(cm),
2765 M_IP6OPT, M_WAITOK);
2766 if (opt->ip6po_nexthop == NULL)
2767 return ENOBUFS;
2768 bcopy(CMSG_DATA(cm),
2769 opt->ip6po_nexthop,
2770 *CMSG_DATA(cm));
2771 } else
2772 opt->ip6po_nexthop =
2773 (struct sockaddr *)CMSG_DATA(cm);
2774 break;
2775
2776 case IPV6_HOPOPTS:
2777 {
2778 struct ip6_hbh *hbh;
2779 int hbhlen;
2780
2781 if (cm->cmsg_len < CMSG_LEN(sizeof(struct ip6_hbh)))
2782 return(EINVAL);
2783 hbh = (struct ip6_hbh *)CMSG_DATA(cm);
2784 hbhlen = (hbh->ip6h_len + 1) << 3;
2785 if (cm->cmsg_len != CMSG_LEN(hbhlen))
2786 return(EINVAL);
2787
2788 if (needcopy) {
2789 opt->ip6po_hbh =
2790 _MALLOC(hbhlen, M_IP6OPT, M_WAITOK);
2791 if (opt->ip6po_hbh == NULL)
2792 return ENOBUFS;
2793 bcopy(hbh, opt->ip6po_hbh, hbhlen);
2794 } else
2795 opt->ip6po_hbh = hbh;
2796 break;
2797 }
2798
2799 case IPV6_DSTOPTS:
2800 {
2801 struct ip6_dest *dest, **newdest;
2802 int destlen;
2803
2804 if (cm->cmsg_len < CMSG_LEN(sizeof(struct ip6_dest)))
2805 return(EINVAL);
2806 dest = (struct ip6_dest *)CMSG_DATA(cm);
2807 destlen = (dest->ip6d_len + 1) << 3;
2808 if (cm->cmsg_len != CMSG_LEN(destlen))
2809 return(EINVAL);
2810
2811 /*
2812 * The old advacned API is ambiguous on this
2813 * point. Our approach is to determine the
2814 * position based according to the existence
2815 * of a routing header. Note, however, that
2816 * this depends on the order of the extension
2817 * headers in the ancillary data; the 1st part
2818 * of the destination options header must
2819 * appear before the routing header in the
2820 * ancillary data, too.
2821 * RFC2292bis solved the ambiguity by
2822 * introducing separate cmsg types.
2823 */
2824 if (opt->ip6po_rthdr == NULL)
2825 newdest = &opt->ip6po_dest1;
2826 else
2827 newdest = &opt->ip6po_dest2;
2828
2829 if (needcopy) {
2830 *newdest = _MALLOC(destlen, M_IP6OPT, M_WAITOK);
2831 if (*newdest == NULL)
2832 return ENOBUFS;
2833 bcopy(dest, *newdest, destlen);
2834 } else
2835 *newdest = dest;
2836
2837 break;
2838 }
2839
2840 case IPV6_RTHDR:
2841 {
2842 struct ip6_rthdr *rth;
2843 int rthlen;
2844
2845 if (cm->cmsg_len < CMSG_LEN(sizeof(struct ip6_rthdr)))
2846 return(EINVAL);
2847 rth = (struct ip6_rthdr *)CMSG_DATA(cm);
2848 rthlen = (rth->ip6r_len + 1) << 3;
2849 if (cm->cmsg_len != CMSG_LEN(rthlen))
2850 return(EINVAL);
2851
2852 switch (rth->ip6r_type) {
2853 case IPV6_RTHDR_TYPE_0:
2854 /* must contain one addr */
2855 if (rth->ip6r_len == 0)
2856 return(EINVAL);
2857 /* length must be even */
2858 if (rth->ip6r_len % 2)
2859 return(EINVAL);
2860 if (rth->ip6r_len / 2 != rth->ip6r_segleft)
2861 return(EINVAL);
2862 break;
2863 default:
2864 return(EINVAL); /* not supported */
2865 }
2866
2867 if (needcopy) {
2868 opt->ip6po_rthdr = _MALLOC(rthlen, M_IP6OPT,
2869 M_WAITOK);
2870 if (opt->ip6po_rthdr == NULL)
2871 return ENOBUFS;
2872 bcopy(rth, opt->ip6po_rthdr, rthlen);
2873 } else
2874 opt->ip6po_rthdr = rth;
2875
2876 break;
2877 }
2878
2879 default:
2880 return(ENOPROTOOPT);
2881 }
2882 }
2883
2884 return(0);
2885 }
2886
2887 /*
2888 * Routine called from ip6_output() to loop back a copy of an IP6 multicast
2889 * packet to the input queue of a specified interface. Note that this
2890 * calls the output routine of the loopback "driver", but with an interface
2891 * pointer that might NOT be &loif -- easier than replicating that code here.
2892 */
2893 void
2894 ip6_mloopback(
2895 struct ifnet *ifp,
2896 struct mbuf *m,
2897 struct sockaddr_in6 *dst)
2898 {
2899 struct mbuf *copym;
2900 struct ip6_hdr *ip6;
2901
2902 copym = m_copy(m, 0, M_COPYALL);
2903 if (copym == NULL)
2904 return;
2905
2906 /*
2907 * Make sure to deep-copy IPv6 header portion in case the data
2908 * is in an mbuf cluster, so that we can safely override the IPv6
2909 * header portion later.
2910 */
2911 if ((copym->m_flags & M_EXT) != 0 ||
2912 copym->m_len < sizeof(struct ip6_hdr)) {
2913 copym = m_pullup(copym, sizeof(struct ip6_hdr));
2914 if (copym == NULL)
2915 return;
2916 }
2917
2918 #if DIAGNOSTIC
2919 if (copym->m_len < sizeof(*ip6)) {
2920 m_freem(copym);
2921 return;
2922 }
2923 #endif
2924
2925 ip6 = mtod(copym, struct ip6_hdr *);
2926 #ifndef SCOPEDROUTING
2927 /*
2928 * clear embedded scope identifiers if necessary.
2929 * in6_clearscope will touch the addresses only when necessary.
2930 */
2931 in6_clearscope(&ip6->ip6_src);
2932 in6_clearscope(&ip6->ip6_dst);
2933 #endif
2934
2935 #ifdef __APPLE__
2936
2937 /* Makes sure the HW checksum flags are cleaned before sending the packet */
2938
2939 copym->m_pkthdr.rcvif = 0;
2940 copym->m_pkthdr.csum_data = 0;
2941 copym->m_pkthdr.csum_flags = 0;
2942
2943 if (lo_ifp) {
2944 copym->m_pkthdr.rcvif = ifp;
2945 lck_mtx_unlock(ip6_mutex);
2946 dlil_output(lo_ifp, PF_INET6, copym, 0, (struct sockaddr *)dst, 0);
2947 lck_mtx_lock(ip6_mutex);
2948 } else
2949 m_free(copym);
2950 #else
2951 (void)if_simloop(ifp, copym, dst->sin6_family, NULL);
2952 #endif
2953 }
2954
2955 /*
2956 * Chop IPv6 header off from the payload.
2957 */
2958 static int
2959 ip6_splithdr(m, exthdrs)
2960 struct mbuf *m;
2961 struct ip6_exthdrs *exthdrs;
2962 {
2963 struct mbuf *mh;
2964 struct ip6_hdr *ip6;
2965
2966 ip6 = mtod(m, struct ip6_hdr *);
2967 if (m->m_len > sizeof(*ip6)) {
2968 MGETHDR(mh, M_DONTWAIT, MT_HEADER); /* MAC-OK */
2969 if (mh == 0) {
2970 m_freem(m);
2971 return ENOBUFS;
2972 }
2973 M_COPY_PKTHDR(mh, m);
2974 MH_ALIGN(mh, sizeof(*ip6));
2975 m->m_flags &= ~M_PKTHDR;
2976 m->m_len -= sizeof(*ip6);
2977 m->m_data += sizeof(*ip6);
2978 mh->m_next = m;
2979 m = mh;
2980 m->m_len = sizeof(*ip6);
2981 bcopy((caddr_t)ip6, mtod(m, caddr_t), sizeof(*ip6));
2982 }
2983 exthdrs->ip6e_ip6 = m;
2984 return 0;
2985 }
2986
2987 /*
2988 * Compute IPv6 extension header length.
2989 */
2990 int
2991 ip6_optlen(in6p)
2992 struct in6pcb *in6p;
2993 {
2994 int len;
2995
2996 if (!in6p->in6p_outputopts)
2997 return 0;
2998
2999 len = 0;
3000 #define elen(x) \
3001 (((struct ip6_ext *)(x)) ? (((struct ip6_ext *)(x))->ip6e_len + 1) << 3 : 0)
3002
3003 len += elen(in6p->in6p_outputopts->ip6po_hbh);
3004 if (in6p->in6p_outputopts->ip6po_rthdr)
3005 /* dest1 is valid with rthdr only */
3006 len += elen(in6p->in6p_outputopts->ip6po_dest1);
3007 len += elen(in6p->in6p_outputopts->ip6po_rthdr);
3008 len += elen(in6p->in6p_outputopts->ip6po_dest2);
3009 return len;
3010 #undef elen
3011 }
3012