]> git.saurik.com Git - apple/xnu.git/blob - bsd/netinet6/ip6_output.c
309686f7fd4b15a481eae16bbf1f5ce9b828cd8e
[apple/xnu.git] / bsd / netinet6 / ip6_output.c
1 /*
2 * Copyright (c) 2008-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 /* $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)
1745 load_ip6fw();
1746 if (ip6_fw_ctl_ptr != NULL)
1747 error = (*ip6_fw_ctl_ptr)(sopt);
1748 else
1749 return ENOPROTOOPT;
1750 }
1751 break;
1752 #endif /* IPFIREWALL */
1753
1754 default:
1755 error = ENOPROTOOPT;
1756 break;
1757 }
1758 break;
1759
1760 case SOPT_GET:
1761 switch (optname) {
1762
1763 case IPV6_PKTOPTIONS:
1764 if (in6p->in6p_options) {
1765 struct mbuf *m;
1766 m = m_copym(in6p->in6p_options,
1767 0, M_COPYALL, M_WAIT);
1768 if (m == NULL) {
1769 error = ENOBUFS;
1770 break;
1771 }
1772 error = soopt_mcopyout(sopt, m);
1773 if (error == 0)
1774 m_freem(m);
1775 } else
1776 sopt->sopt_valsize = 0;
1777 break;
1778
1779 case IPV6_UNICAST_HOPS:
1780 case IPV6_CHECKSUM:
1781
1782 case IPV6_FAITH:
1783 case IPV6_V6ONLY:
1784 case IPV6_PORTRANGE:
1785 case IPV6_RECVTCLASS:
1786 switch (optname) {
1787
1788 case IPV6_UNICAST_HOPS:
1789 optval = in6p->in6p_hops;
1790 break;
1791
1792 case IPV6_CHECKSUM:
1793 optval = in6p->in6p_cksum;
1794 break;
1795
1796 case IPV6_FAITH:
1797 optval = OPTBIT(IN6P_FAITH);
1798 break;
1799
1800 case IPV6_V6ONLY:
1801 optval = OPTBIT(IN6P_IPV6_V6ONLY);
1802 break;
1803
1804 case IPV6_PORTRANGE:
1805 {
1806 int flags;
1807 flags = in6p->in6p_flags;
1808 if (flags & IN6P_HIGHPORT)
1809 optval = IPV6_PORTRANGE_HIGH;
1810 else if (flags & IN6P_LOWPORT)
1811 optval = IPV6_PORTRANGE_LOW;
1812 else
1813 optval = 0;
1814 break;
1815 }
1816 case IPV6_RECVTCLASS:
1817 optval = OPTBIT(IN6P_TCLASS);
1818 break;
1819
1820 }
1821 error = sooptcopyout(sopt, &optval,
1822 sizeof optval);
1823 break;
1824
1825 case IPV6_PKTINFO:
1826 case IPV6_HOPLIMIT:
1827 case IPV6_HOPOPTS:
1828 case IPV6_RTHDR:
1829 case IPV6_DSTOPTS:
1830 if ((optname == IPV6_HOPOPTS ||
1831 optname == IPV6_DSTOPTS) &&
1832 !privileged)
1833 return(EPERM);
1834 switch (optname) {
1835 case IPV6_PKTINFO:
1836 optval = OPTBIT(IN6P_PKTINFO);
1837 break;
1838 case IPV6_HOPLIMIT:
1839 optval = OPTBIT(IN6P_HOPLIMIT);
1840 break;
1841 case IPV6_HOPOPTS:
1842 if (!privileged)
1843 return(EPERM);
1844 optval = OPTBIT(IN6P_HOPOPTS);
1845 break;
1846 case IPV6_RTHDR:
1847 optval = OPTBIT(IN6P_RTHDR);
1848 break;
1849 case IPV6_DSTOPTS:
1850 if (!privileged)
1851 return(EPERM);
1852 optval = OPTBIT(IN6P_DSTOPTS|IN6P_RTHDRDSTOPTS);
1853 break;
1854 }
1855 error = sooptcopyout(sopt, &optval,
1856 sizeof optval);
1857 break;
1858
1859 case IPV6_TCLASS:
1860 error = ip6_getpcbopt(in6p->in6p_outputopts, optname, sopt);
1861 break;
1862
1863 case IPV6_MULTICAST_IF:
1864 case IPV6_MULTICAST_HOPS:
1865 case IPV6_MULTICAST_LOOP:
1866 case IPV6_JOIN_GROUP:
1867 case IPV6_LEAVE_GROUP:
1868 {
1869 struct mbuf *m;
1870 error = ip6_getmoptions(sopt->sopt_name,
1871 in6p->in6p_moptions, &m);
1872 if (error == 0)
1873 error = sooptcopyout(sopt,
1874 mtod(m, char *), m->m_len);
1875 if (m != NULL)
1876 m_freem(m);
1877 }
1878 break;
1879
1880 #if IPSEC
1881 case IPV6_IPSEC_POLICY:
1882 {
1883 caddr_t req = NULL;
1884 size_t len = 0;
1885 struct mbuf *m = NULL;
1886 struct mbuf **mp = &m;
1887
1888 if (sopt->sopt_valsize > MCLBYTES) {
1889 error = EMSGSIZE;
1890 break;
1891 }
1892 error = soopt_getm(sopt, &m); /* XXX */
1893 if (error != 0)
1894 break;
1895 error = soopt_mcopyin(sopt, m); /* XXX */
1896 if (error != 0)
1897 break;
1898 if (m) {
1899 req = mtod(m, caddr_t);
1900 len = m->m_len;
1901 }
1902 error = ipsec6_get_policy(in6p, req, len, mp);
1903 if (error == 0)
1904 error = soopt_mcopyout(sopt, m); /*XXX*/
1905 if (error == 0 && m)
1906 m_freem(m);
1907 break;
1908 }
1909 #endif /* KAME IPSEC */
1910
1911 #if IPFIREWALL
1912 case IPV6_FW_GET:
1913 {
1914 if (ip6_fw_ctl_ptr == NULL)
1915 load_ip6fw();
1916 if (ip6_fw_ctl_ptr != NULL)
1917 error = (*ip6_fw_ctl_ptr)(sopt);
1918 else
1919 return ENOPROTOOPT;
1920 }
1921 break;
1922 #endif /* IPFIREWALL */
1923
1924 default:
1925 error = ENOPROTOOPT;
1926 break;
1927 }
1928 break;
1929 }
1930 } else {
1931 error = EINVAL;
1932 }
1933 return(error);
1934 }
1935
1936 /*
1937 * Set up IP6 options in pcb for insertion in output packets or
1938 * specifying behavior of outgoing packets.
1939 */
1940 static int
1941 ip6_pcbopts(
1942 struct ip6_pktopts **pktopt,
1943 struct mbuf *m,
1944 __unused struct socket *so,
1945 struct sockopt *sopt)
1946 {
1947 struct ip6_pktopts *opt = *pktopt;
1948 int error = 0, priv;
1949 struct proc *p = sopt->sopt_p;
1950
1951 /* turn off any old options. */
1952 if (opt) {
1953 #if DIAGNOSTIC
1954 if (opt->ip6po_pktinfo || opt->ip6po_nexthop ||
1955 opt->ip6po_hbh || opt->ip6po_dest1 || opt->ip6po_dest2 ||
1956 opt->ip6po_rhinfo.ip6po_rhi_rthdr)
1957 printf("ip6_pcbopts: all specified options are cleared.\n");
1958 #endif
1959 ip6_clearpktopts(opt, 1, -1);
1960 } else {
1961 opt = _MALLOC(sizeof(*opt), M_IP6OPT, M_WAITOK);
1962 if (opt == NULL)
1963 return ENOBUFS;
1964 }
1965 *pktopt = NULL;
1966
1967 if (!m || m->m_len == 0) {
1968 /*
1969 * Only turning off any previous options, regardless of
1970 * whether the opt is just created or given.
1971 */
1972 if (opt)
1973 FREE(opt, M_IP6OPT);
1974 return(0);
1975 }
1976
1977 priv = (proc_suser(p) == 0);
1978
1979 /* set options specified by user. */
1980 if ((error = ip6_setpktoptions(m, opt, priv, 1)) != 0) {
1981 ip6_clearpktopts(opt, 1, -1); /* XXX: discard all options */
1982 FREE(opt, M_IP6OPT);
1983 return(error);
1984 }
1985 *pktopt = opt;
1986 return(0);
1987 }
1988
1989 static int
1990 ip6_pcbopt(int optname, u_char *buf, int len, struct ip6_pktopts **pktopt)
1991 {
1992 struct ip6_pktopts *opt;
1993
1994 opt = *pktopt;
1995 if (opt == NULL) {
1996 opt = _MALLOC(sizeof(*opt), M_IP6OPT, M_WAITOK);
1997 ip6_initpktopts(opt);
1998 *pktopt = opt;
1999 }
2000
2001 return (ip6_setpktopt(optname, buf, len, opt));
2002 }
2003
2004 static int
2005 ip6_getpcbopt(struct ip6_pktopts *pktopt, int optname, struct sockopt *sopt)
2006 {
2007 void *optdata = NULL;
2008 int optdatalen = 0;
2009 int deftclass = 0;
2010 int error = 0;
2011
2012 switch (optname) {
2013 case IPV6_TCLASS:
2014 if (pktopt && pktopt->ip6po_tclass >= 0)
2015 optdata = &pktopt->ip6po_tclass;
2016 else
2017 optdata = &deftclass;
2018 optdatalen = sizeof(int);
2019 break;
2020 default: /* should not happen */
2021 #ifdef DIAGNOSTIC
2022 panic("ip6_getpcbopt: unexpected option\n");
2023 #endif
2024 return (ENOPROTOOPT);
2025 }
2026
2027 error = sooptcopyout(sopt, optdata, optdatalen);
2028 return (error);
2029 }
2030
2031 static int
2032 ip6_setpktopt(int optname, u_char *buf, int len, struct ip6_pktopts *opt)
2033 {
2034 switch (optname) {
2035 case IPV6_TCLASS:
2036 {
2037 int tclass;
2038
2039 if (len != sizeof(int))
2040 return (EINVAL);
2041 tclass = *(int *)buf;
2042 if (tclass < -1 || tclass > 255)
2043 return (EINVAL);
2044
2045 opt->ip6po_tclass = tclass;
2046 break;
2047 }
2048
2049 default:
2050 return (ENOPROTOOPT);
2051 } /* end of switch */
2052
2053 return (0);
2054 }
2055
2056 /*
2057 * initialize ip6_pktopts. beware that there are non-zero default values in
2058 * the struct.
2059 */
2060 void
2061 ip6_initpktopts(opt)
2062 struct ip6_pktopts *opt;
2063 {
2064 bzero(opt, sizeof(*opt));
2065 opt->ip6po_hlim = -1; /* -1 means default hop limit */
2066 opt->ip6po_tclass = -1; /* -1 means default traffic class */
2067 }
2068
2069 void
2070 ip6_clearpktopts(pktopt, needfree, optname)
2071 struct ip6_pktopts *pktopt;
2072 int needfree, optname;
2073 {
2074 if (pktopt == NULL)
2075 return;
2076
2077 if (optname == -1) {
2078 if (needfree && pktopt->ip6po_pktinfo)
2079 FREE(pktopt->ip6po_pktinfo, M_IP6OPT);
2080 pktopt->ip6po_pktinfo = NULL;
2081 }
2082 if (optname == -1)
2083 pktopt->ip6po_hlim = -1;
2084 if (optname == -1)
2085 pktopt->ip6po_tclass = -1;
2086 if (optname == -1) {
2087 if (needfree && pktopt->ip6po_nexthop)
2088 FREE(pktopt->ip6po_nexthop, M_IP6OPT);
2089 pktopt->ip6po_nexthop = NULL;
2090 }
2091 if (optname == -1) {
2092 if (needfree && pktopt->ip6po_hbh)
2093 FREE(pktopt->ip6po_hbh, M_IP6OPT);
2094 pktopt->ip6po_hbh = NULL;
2095 }
2096 if (optname == -1) {
2097 if (needfree && pktopt->ip6po_dest1)
2098 FREE(pktopt->ip6po_dest1, M_IP6OPT);
2099 pktopt->ip6po_dest1 = NULL;
2100 }
2101 if (optname == -1) {
2102 if (needfree && pktopt->ip6po_rhinfo.ip6po_rhi_rthdr)
2103 FREE(pktopt->ip6po_rhinfo.ip6po_rhi_rthdr, M_IP6OPT);
2104 pktopt->ip6po_rhinfo.ip6po_rhi_rthdr = NULL;
2105 if (pktopt->ip6po_route.ro_rt) {
2106 rtfree(pktopt->ip6po_route.ro_rt);
2107 pktopt->ip6po_route.ro_rt = NULL;
2108 }
2109 }
2110 if (optname == -1) {
2111 if (needfree && pktopt->ip6po_dest2)
2112 FREE(pktopt->ip6po_dest2, M_IP6OPT);
2113 pktopt->ip6po_dest2 = NULL;
2114 }
2115 }
2116
2117 #define PKTOPT_EXTHDRCPY(type) \
2118 do {\
2119 if (src->type) {\
2120 int hlen =\
2121 (((struct ip6_ext *)src->type)->ip6e_len + 1) << 3;\
2122 dst->type = _MALLOC(hlen, M_IP6OPT, canwait);\
2123 if (dst->type == NULL && canwait == M_NOWAIT)\
2124 goto bad;\
2125 bcopy(src->type, dst->type, hlen);\
2126 }\
2127 } while (0)
2128
2129 struct ip6_pktopts *
2130 ip6_copypktopts(src, canwait)
2131 struct ip6_pktopts *src;
2132 int canwait;
2133 {
2134 struct ip6_pktopts *dst;
2135
2136 if (src == NULL) {
2137 printf("ip6_clearpktopts: invalid argument\n");
2138 return(NULL);
2139 }
2140
2141 dst = _MALLOC(sizeof(*dst), M_IP6OPT, canwait);
2142 if (dst == NULL && canwait == M_NOWAIT)
2143 return (NULL);
2144 bzero(dst, sizeof(*dst));
2145
2146 dst->ip6po_hlim = src->ip6po_hlim;
2147 dst->ip6po_tclass = src->ip6po_tclass;
2148 if (src->ip6po_pktinfo) {
2149 dst->ip6po_pktinfo = _MALLOC(sizeof(*dst->ip6po_pktinfo),
2150 M_IP6OPT, canwait);
2151 if (dst->ip6po_pktinfo == NULL && canwait == M_NOWAIT)
2152 goto bad;
2153 *dst->ip6po_pktinfo = *src->ip6po_pktinfo;
2154 }
2155 if (src->ip6po_nexthop) {
2156 dst->ip6po_nexthop = _MALLOC(src->ip6po_nexthop->sa_len,
2157 M_IP6OPT, canwait);
2158 if (dst->ip6po_nexthop == NULL && canwait == M_NOWAIT)
2159 goto bad;
2160 bcopy(src->ip6po_nexthop, dst->ip6po_nexthop,
2161 src->ip6po_nexthop->sa_len);
2162 }
2163 PKTOPT_EXTHDRCPY(ip6po_hbh);
2164 PKTOPT_EXTHDRCPY(ip6po_dest1);
2165 PKTOPT_EXTHDRCPY(ip6po_dest2);
2166 PKTOPT_EXTHDRCPY(ip6po_rthdr); /* not copy the cached route */
2167 return(dst);
2168
2169 bad:
2170 if (dst->ip6po_pktinfo) FREE(dst->ip6po_pktinfo, M_IP6OPT);
2171 if (dst->ip6po_nexthop) FREE(dst->ip6po_nexthop, M_IP6OPT);
2172 if (dst->ip6po_hbh) FREE(dst->ip6po_hbh, M_IP6OPT);
2173 if (dst->ip6po_dest1) FREE(dst->ip6po_dest1, M_IP6OPT);
2174 if (dst->ip6po_dest2) FREE(dst->ip6po_dest2, M_IP6OPT);
2175 if (dst->ip6po_rthdr) FREE(dst->ip6po_rthdr, M_IP6OPT);
2176 FREE(dst, M_IP6OPT);
2177 return(NULL);
2178 }
2179 #undef PKTOPT_EXTHDRCPY
2180
2181 void
2182 ip6_freepcbopts(pktopt)
2183 struct ip6_pktopts *pktopt;
2184 {
2185 if (pktopt == NULL)
2186 return;
2187
2188 ip6_clearpktopts(pktopt, 1, -1);
2189
2190 FREE(pktopt, M_IP6OPT);
2191 }
2192
2193 /*
2194 * Set the IP6 multicast options in response to user setsockopt().
2195 */
2196 static int
2197 ip6_setmoptions(
2198 int optname,
2199 struct inpcb* in6p,
2200 struct mbuf *m)
2201 {
2202 int error = 0;
2203 u_int loop, ifindex;
2204 struct ipv6_mreq *mreq;
2205 struct ifnet *ifp;
2206 struct ip6_moptions **im6op = &in6p->in6p_moptions;
2207 struct ip6_moptions *im6o = *im6op;
2208 struct ip_moptions *imo;
2209 struct route_in6 ro;
2210 struct sockaddr_in6 *dst;
2211 struct in6_multi_mship *imm;
2212
2213 if (im6o == NULL) {
2214 /*
2215 * No multicast option buffer attached to the pcb;
2216 * allocate one and initialize to default values.
2217 */
2218 im6o = (struct ip6_moptions *)
2219 _MALLOC(sizeof(*im6o), M_IPMOPTS, M_WAITOK);
2220
2221 if (im6o == NULL)
2222 return(ENOBUFS);
2223 *im6op = im6o;
2224 im6o->im6o_multicast_ifp = NULL;
2225 im6o->im6o_multicast_hlim = ip6_defmcasthlim;
2226 im6o->im6o_multicast_loop = IPV6_DEFAULT_MULTICAST_LOOP;
2227 LIST_INIT(&im6o->im6o_memberships);
2228 }
2229
2230 if (in6p->inp_moptions == NULL) {
2231 /*
2232 * No IPv4 multicast option buffer attached to the pcb;
2233 * call ip_createmoptions to allocate one and initialize
2234 * to default values.
2235 */
2236 error = ip_createmoptions(&in6p->inp_moptions);
2237 if (error != 0)
2238 return error;
2239 }
2240 imo = in6p->inp_moptions;
2241
2242 switch (optname) {
2243
2244 case IPV6_MULTICAST_IF:
2245 /*
2246 * Select the interface for outgoing multicast packets.
2247 */
2248 if (m == NULL || m->m_len != sizeof(u_int)) {
2249 error = EINVAL;
2250 break;
2251 }
2252 bcopy(mtod(m, u_int *), &ifindex, sizeof(ifindex));
2253
2254 ifnet_head_lock_shared();
2255 /* Don't need to check is ifindex is < 0 since it's unsigned */
2256 if (if_index < ifindex) {
2257 error = ENXIO; /* XXX EINVAL? */
2258 ifnet_head_done();
2259 break;
2260 }
2261 ifp = ifindex2ifnet[ifindex];
2262 ifnet_head_done();
2263 if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {
2264 error = EADDRNOTAVAIL;
2265 break;
2266 }
2267 im6o->im6o_multicast_ifp = ifp;
2268 imo->imo_multicast_ifp = ifp;
2269 break;
2270
2271 case IPV6_MULTICAST_HOPS:
2272 {
2273 /*
2274 * Set the IP6 hoplimit for outgoing multicast packets.
2275 */
2276 int optval;
2277 if (m == NULL || m->m_len != sizeof(int)) {
2278 error = EINVAL;
2279 break;
2280 }
2281 bcopy(mtod(m, u_int *), &optval, sizeof(optval));
2282 if (optval < -1 || optval >= 256)
2283 error = EINVAL;
2284 else if (optval == -1) {
2285 im6o->im6o_multicast_hlim = ip6_defmcasthlim;
2286 imo->imo_multicast_ttl = IP_DEFAULT_MULTICAST_TTL;
2287 } else {
2288 im6o->im6o_multicast_hlim = optval;
2289 imo->imo_multicast_ttl = optval;
2290 }
2291 break;
2292 }
2293
2294 case IPV6_MULTICAST_LOOP:
2295 /*
2296 * Set the loopback flag for outgoing multicast packets.
2297 * Must be zero or one.
2298 */
2299 if (m == NULL || m->m_len != sizeof(u_int)) {
2300 error = EINVAL;
2301 break;
2302 }
2303 bcopy(mtod(m, u_int *), &loop, sizeof(loop));
2304 if (loop > 1) {
2305 error = EINVAL;
2306 break;
2307 }
2308 im6o->im6o_multicast_loop = loop;
2309 imo->imo_multicast_loop = loop;
2310 break;
2311
2312 case IPV6_JOIN_GROUP:
2313 /*
2314 * Add a multicast group membership.
2315 * Group must be a valid IP6 multicast address.
2316 */
2317 if (m == NULL || m->m_len != sizeof(struct ipv6_mreq)) {
2318 error = EINVAL;
2319 break;
2320 }
2321 mreq = mtod(m, struct ipv6_mreq *);
2322 /*
2323 * If the interface is specified, validate it.
2324 *
2325 * Don't need to check if it's < 0, since it's unsigned
2326 */
2327 ifnet_head_lock_shared();
2328 if (if_index < mreq->ipv6mr_interface) {
2329 ifnet_head_done();
2330 error = ENXIO; /* XXX EINVAL? */
2331 break;
2332 }
2333 ifp = ifindex2ifnet[mreq->ipv6mr_interface];
2334 ifnet_head_done();
2335
2336 if (IN6_IS_ADDR_UNSPECIFIED(&mreq->ipv6mr_multiaddr)) {
2337 /*
2338 * We use the unspecified address to specify to accept
2339 * all multicast addresses. Only super user is allowed
2340 * to do this.
2341 */
2342 if (suser(kauth_cred_get(), 0))
2343 {
2344 error = EACCES;
2345 break;
2346 }
2347 } else if (IN6_IS_ADDR_V4MAPPED(&mreq->ipv6mr_multiaddr)) {
2348 struct ip_mreq v4req;
2349
2350 v4req.imr_multiaddr.s_addr = mreq->ipv6mr_multiaddr.s6_addr32[3];
2351 v4req.imr_interface.s_addr = INADDR_ANY;
2352
2353 /* Find an IPv4 address on the specified interface. */
2354 if (mreq->ipv6mr_interface != 0) {
2355 struct in_ifaddr *ifa;
2356
2357 lck_rw_lock_shared(in_ifaddr_rwlock);
2358 TAILQ_FOREACH(ifa, &in_ifaddrhead, ia_link) {
2359 if (ifa->ia_ifp == ifp) {
2360 v4req.imr_interface = IA_SIN(ifa)->sin_addr;
2361 break;
2362 }
2363 }
2364 lck_rw_done(in_ifaddr_rwlock);
2365
2366 if (v4req.imr_multiaddr.s_addr == 0) {
2367 /* Interface has no IPv4 address. */
2368 error = EINVAL;
2369 break;
2370 }
2371 }
2372
2373 error = ip_addmembership(imo, &v4req);
2374 break;
2375 } else if (!IN6_IS_ADDR_MULTICAST(&mreq->ipv6mr_multiaddr)) {
2376 error = EINVAL;
2377 break;
2378 }
2379 /*
2380 * If no interface was explicitly specified, choose an
2381 * appropriate one according to the given multicast address.
2382 */
2383 if (mreq->ipv6mr_interface == 0) {
2384 /*
2385 * If the multicast address is in node-local scope,
2386 * the interface should be a loopback interface.
2387 * Otherwise, look up the routing table for the
2388 * address, and choose the outgoing interface.
2389 * XXX: is it a good approach?
2390 */
2391 if (IN6_IS_ADDR_MC_NODELOCAL(&mreq->ipv6mr_multiaddr)) {
2392 ifp = lo_ifp;
2393 } else {
2394 ro.ro_rt = NULL;
2395 dst = (struct sockaddr_in6 *)&ro.ro_dst;
2396 bzero(dst, sizeof(*dst));
2397 dst->sin6_len = sizeof(struct sockaddr_in6);
2398 dst->sin6_family = AF_INET6;
2399 dst->sin6_addr = mreq->ipv6mr_multiaddr;
2400 rtalloc((struct route *)&ro);
2401 if (ro.ro_rt == NULL) {
2402 error = EADDRNOTAVAIL;
2403 break;
2404 }
2405 ifp = ro.ro_rt->rt_ifp;
2406 rtfree(ro.ro_rt);
2407 ro.ro_rt = NULL;
2408 }
2409 }
2410
2411 /*
2412 * See if we found an interface, and confirm that it
2413 * supports multicast
2414 */
2415 if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {
2416 error = EADDRNOTAVAIL;
2417 break;
2418 }
2419 /*
2420 * Put interface index into the multicast address,
2421 * if the address has link-local scope.
2422 */
2423 if (IN6_IS_ADDR_MC_LINKLOCAL(&mreq->ipv6mr_multiaddr)) {
2424 mreq->ipv6mr_multiaddr.s6_addr16[1]
2425 = htons(mreq->ipv6mr_interface);
2426 }
2427 /*
2428 * See if the membership already exists.
2429 */
2430 lck_mtx_lock(nd6_mutex);
2431 for (imm = im6o->im6o_memberships.lh_first;
2432 imm != NULL; imm = imm->i6mm_chain.le_next)
2433 if (imm->i6mm_maddr->in6m_ifp == ifp &&
2434 IN6_ARE_ADDR_EQUAL(&imm->i6mm_maddr->in6m_addr,
2435 &mreq->ipv6mr_multiaddr))
2436 break;
2437 if (imm != NULL) {
2438 error = EADDRINUSE;
2439 lck_mtx_unlock(nd6_mutex);
2440 break;
2441 }
2442 /*
2443 * Everything looks good; add a new record to the multicast
2444 * address list for the given interface.
2445 */
2446 imm = _MALLOC(sizeof(*imm), M_IPMADDR, M_WAITOK);
2447 if (imm == NULL) {
2448 error = ENOBUFS;
2449 lck_mtx_unlock(nd6_mutex);
2450 break;
2451 }
2452 if ((imm->i6mm_maddr =
2453 in6_addmulti(&mreq->ipv6mr_multiaddr, ifp, &error, 1)) == NULL) {
2454 FREE(imm, M_IPMADDR);
2455 lck_mtx_unlock(nd6_mutex);
2456 break;
2457 }
2458 LIST_INSERT_HEAD(&im6o->im6o_memberships, imm, i6mm_chain);
2459 lck_mtx_unlock(nd6_mutex);
2460 break;
2461
2462 case IPV6_LEAVE_GROUP:
2463 /*
2464 * Drop a multicast group membership.
2465 * Group must be a valid IP6 multicast address.
2466 */
2467 if (m == NULL || m->m_len != sizeof(struct ipv6_mreq)) {
2468 error = EINVAL;
2469 break;
2470 }
2471 mreq = mtod(m, struct ipv6_mreq *);
2472 /*
2473 * If an interface address was specified, get a pointer
2474 * to its ifnet structure.
2475 *
2476 * Don't need to check if it's < 0, since it's unsigned.
2477 */
2478 ifnet_head_lock_shared();
2479 if (if_index < mreq->ipv6mr_interface) {
2480 ifnet_head_done();
2481 error = ENXIO; /* XXX EINVAL? */
2482 break;
2483 }
2484 ifp = ifindex2ifnet[mreq->ipv6mr_interface];
2485 ifnet_head_done();
2486
2487 if (IN6_IS_ADDR_UNSPECIFIED(&mreq->ipv6mr_multiaddr)) {
2488 if (suser(kauth_cred_get(), 0)) {
2489 error = EACCES;
2490 break;
2491 }
2492 } else if (IN6_IS_ADDR_V4MAPPED(&mreq->ipv6mr_multiaddr)) {
2493 struct ip_mreq v4req;
2494
2495 v4req.imr_multiaddr.s_addr = mreq->ipv6mr_multiaddr.s6_addr32[3];
2496 v4req.imr_interface.s_addr = INADDR_ANY;
2497
2498 if (ifp != NULL) {
2499 struct in_ifaddr *ifa;
2500
2501 lck_rw_lock_shared(in_ifaddr_rwlock);
2502 TAILQ_FOREACH(ifa, &in_ifaddrhead, ia_link) {
2503 if (ifa->ia_ifp == ifp) {
2504 v4req.imr_interface = IA_SIN(ifa)->sin_addr;
2505 break;
2506 }
2507 }
2508 lck_rw_done(in_ifaddr_rwlock);
2509 }
2510
2511 error = ip_dropmembership(imo, &v4req);
2512 break;
2513 } else if (!IN6_IS_ADDR_MULTICAST(&mreq->ipv6mr_multiaddr)) {
2514 error = EINVAL;
2515 break;
2516 }
2517 /*
2518 * Put interface index into the multicast address,
2519 * if the address has link-local scope.
2520 */
2521 if (IN6_IS_ADDR_MC_LINKLOCAL(&mreq->ipv6mr_multiaddr)) {
2522 mreq->ipv6mr_multiaddr.s6_addr16[1]
2523 = htons(mreq->ipv6mr_interface);
2524 }
2525 /*
2526 * Find the membership in the membership list.
2527 */
2528 lck_mtx_lock(nd6_mutex);
2529 for (imm = im6o->im6o_memberships.lh_first;
2530 imm != NULL; imm = imm->i6mm_chain.le_next) {
2531 if ((ifp == NULL ||
2532 imm->i6mm_maddr->in6m_ifp == ifp) &&
2533 IN6_ARE_ADDR_EQUAL(&imm->i6mm_maddr->in6m_addr,
2534 &mreq->ipv6mr_multiaddr))
2535 break;
2536 }
2537 if (imm == NULL) {
2538 /* Unable to resolve interface */
2539 error = EADDRNOTAVAIL;
2540 lck_mtx_unlock(nd6_mutex);
2541 break;
2542 }
2543 /*
2544 * Give up the multicast address record to which the
2545 * membership points.
2546 */
2547 LIST_REMOVE(imm, i6mm_chain);
2548 in6_delmulti(imm->i6mm_maddr, 1);
2549 lck_mtx_unlock(nd6_mutex);
2550 FREE(imm, M_IPMADDR);
2551 break;
2552
2553 default:
2554 error = EOPNOTSUPP;
2555 break;
2556 }
2557
2558 /*
2559 * If all options have default values, no need to keep the mbuf.
2560 */
2561 lck_mtx_lock(nd6_mutex);
2562 if (im6o->im6o_multicast_ifp == NULL &&
2563 im6o->im6o_multicast_hlim == ip6_defmcasthlim &&
2564 im6o->im6o_multicast_loop == IPV6_DEFAULT_MULTICAST_LOOP &&
2565 im6o->im6o_memberships.lh_first == NULL) {
2566 FREE(*im6op, M_IPMOPTS);
2567 *im6op = NULL;
2568 }
2569 if (imo->imo_multicast_ifp == NULL &&
2570 imo->imo_multicast_vif == -1 &&
2571 imo->imo_multicast_ttl == IP_DEFAULT_MULTICAST_TTL &&
2572 imo->imo_multicast_loop == IP_DEFAULT_MULTICAST_LOOP &&
2573 imo->imo_num_memberships == 0) {
2574 ip_freemoptions(imo);
2575 in6p->inp_moptions = 0;
2576 }
2577 lck_mtx_unlock(nd6_mutex);
2578
2579 return(error);
2580 }
2581
2582 /*
2583 * Return the IP6 multicast options in response to user getsockopt().
2584 */
2585 static int
2586 ip6_getmoptions(optname, im6o, mp)
2587 int optname;
2588 struct ip6_moptions *im6o;
2589 struct mbuf **mp;
2590 {
2591 u_int *hlim, *loop, *ifindex;
2592
2593 *mp = m_get(M_WAIT, MT_HEADER); /*XXX*/
2594 if (*mp == NULL)
2595 return ENOBUFS;
2596
2597 switch (optname) {
2598
2599 case IPV6_MULTICAST_IF:
2600 ifindex = mtod(*mp, u_int *);
2601 (*mp)->m_len = sizeof(u_int);
2602 if (im6o == NULL || im6o->im6o_multicast_ifp == NULL)
2603 *ifindex = 0;
2604 else
2605 *ifindex = im6o->im6o_multicast_ifp->if_index;
2606 return(0);
2607
2608 case IPV6_MULTICAST_HOPS:
2609 hlim = mtod(*mp, u_int *);
2610 (*mp)->m_len = sizeof(u_int);
2611 if (im6o == NULL)
2612 *hlim = ip6_defmcasthlim;
2613 else
2614 *hlim = im6o->im6o_multicast_hlim;
2615 return(0);
2616
2617 case IPV6_MULTICAST_LOOP:
2618 loop = mtod(*mp, u_int *);
2619 (*mp)->m_len = sizeof(u_int);
2620 if (im6o == NULL)
2621 *loop = ip6_defmcasthlim;
2622 else
2623 *loop = im6o->im6o_multicast_loop;
2624 return(0);
2625
2626 default:
2627 return(EOPNOTSUPP);
2628 }
2629 }
2630
2631 /*
2632 * Discard the IP6 multicast options.
2633 */
2634 void
2635 ip6_freemoptions(im6o)
2636 struct ip6_moptions *im6o;
2637 {
2638 struct in6_multi_mship *imm;
2639
2640 if (im6o == NULL)
2641 return;
2642
2643 lck_mtx_lock(nd6_mutex);
2644 while ((imm = im6o->im6o_memberships.lh_first) != NULL) {
2645 LIST_REMOVE(imm, i6mm_chain);
2646 if (imm->i6mm_maddr)
2647 in6_delmulti(imm->i6mm_maddr, 1);
2648 FREE(imm, M_IPMADDR);
2649 }
2650 lck_mtx_unlock(nd6_mutex);
2651 FREE(im6o, M_IPMOPTS);
2652 }
2653
2654 /*
2655 * Set IPv6 outgoing packet options based on advanced API.
2656 */
2657 int
2658 ip6_setpktoptions(control, opt, priv, needcopy)
2659 struct mbuf *control;
2660 struct ip6_pktopts *opt;
2661 int priv, needcopy;
2662 {
2663 struct cmsghdr *cm = 0;
2664
2665 if (control == 0 || opt == 0)
2666 return(EINVAL);
2667
2668 ip6_initpktopts(opt);
2669
2670 /*
2671 * XXX: Currently, we assume all the optional information is stored
2672 * in a single mbuf.
2673 */
2674 if (control->m_next)
2675 return(EINVAL);
2676
2677 for (; control->m_len; control->m_data += CMSG_ALIGN(cm->cmsg_len),
2678 control->m_len -= CMSG_ALIGN(cm->cmsg_len)) {
2679 cm = mtod(control, struct cmsghdr *);
2680 if (cm->cmsg_len == 0 || cm->cmsg_len > control->m_len)
2681 return(EINVAL);
2682 if (cm->cmsg_level != IPPROTO_IPV6)
2683 continue;
2684
2685 /*
2686 * XXX should check if RFC2292 API is mixed with 2292bis API
2687 */
2688 switch (cm->cmsg_type) {
2689 case IPV6_PKTINFO:
2690 if (cm->cmsg_len != CMSG_LEN(sizeof(struct in6_pktinfo)))
2691 return(EINVAL);
2692 if (needcopy) {
2693 /* XXX: Is it really WAITOK? */
2694 opt->ip6po_pktinfo =
2695 _MALLOC(sizeof(struct in6_pktinfo),
2696 M_IP6OPT, M_WAITOK);
2697 if (opt->ip6po_pktinfo == NULL)
2698 return ENOBUFS;
2699 bcopy(CMSG_DATA(cm), opt->ip6po_pktinfo,
2700 sizeof(struct in6_pktinfo));
2701 } else
2702 opt->ip6po_pktinfo =
2703 (struct in6_pktinfo *)CMSG_DATA(cm);
2704 if (opt->ip6po_pktinfo->ipi6_ifindex &&
2705 IN6_IS_ADDR_LINKLOCAL(&opt->ip6po_pktinfo->ipi6_addr))
2706 opt->ip6po_pktinfo->ipi6_addr.s6_addr16[1] =
2707 htons(opt->ip6po_pktinfo->ipi6_ifindex);
2708
2709 if (opt->ip6po_pktinfo->ipi6_ifindex > if_index) {
2710 return(ENXIO);
2711 }
2712
2713 /*
2714 * Check if the requested source address is indeed a
2715 * unicast address assigned to the node, and can be
2716 * used as the packet's source address.
2717 */
2718 if (!IN6_IS_ADDR_UNSPECIFIED(&opt->ip6po_pktinfo->ipi6_addr)) {
2719 struct in6_ifaddr *ia6;
2720 struct sockaddr_in6 sin6;
2721
2722 bzero(&sin6, sizeof(sin6));
2723 sin6.sin6_len = sizeof(sin6);
2724 sin6.sin6_family = AF_INET6;
2725 sin6.sin6_addr =
2726 opt->ip6po_pktinfo->ipi6_addr;
2727 ia6 = (struct in6_ifaddr *)ifa_ifwithaddr(sin6tosa(&sin6));
2728 if (ia6 == NULL ||
2729 (ia6->ia6_flags & (IN6_IFF_ANYCAST |
2730 IN6_IFF_NOTREADY)) != 0) {
2731 if (ia6) ifafree(&ia6->ia_ifa);
2732 return(EADDRNOTAVAIL);
2733 }
2734 ifafree(&ia6->ia_ifa);
2735 ia6 = NULL;
2736 }
2737 break;
2738
2739 case IPV6_HOPLIMIT:
2740 if (cm->cmsg_len != CMSG_LEN(sizeof(int)))
2741 return(EINVAL);
2742
2743 opt->ip6po_hlim = *(int *)CMSG_DATA(cm);
2744 if (opt->ip6po_hlim < -1 || opt->ip6po_hlim > 255)
2745 return(EINVAL);
2746 break;
2747
2748 case IPV6_TCLASS:
2749 if (cm->cmsg_len != CMSG_LEN(sizeof(int)))
2750 return(EINVAL);
2751
2752 opt->ip6po_tclass = *(int *)CMSG_DATA(cm);
2753 if (opt->ip6po_tclass < -1 || opt->ip6po_tclass > 255)
2754 return (EINVAL);
2755 break;
2756
2757 case IPV6_NEXTHOP:
2758 if (!priv)
2759 return(EPERM);
2760
2761 if (cm->cmsg_len < sizeof(u_char) ||
2762 /* check if cmsg_len is large enough for sa_len */
2763 cm->cmsg_len < CMSG_LEN(*CMSG_DATA(cm)))
2764 return(EINVAL);
2765
2766 if (needcopy) {
2767 opt->ip6po_nexthop =
2768 _MALLOC(*CMSG_DATA(cm),
2769 M_IP6OPT, M_WAITOK);
2770 if (opt->ip6po_nexthop == NULL)
2771 return ENOBUFS;
2772 bcopy(CMSG_DATA(cm),
2773 opt->ip6po_nexthop,
2774 *CMSG_DATA(cm));
2775 } else
2776 opt->ip6po_nexthop =
2777 (struct sockaddr *)CMSG_DATA(cm);
2778 break;
2779
2780 case IPV6_HOPOPTS:
2781 {
2782 struct ip6_hbh *hbh;
2783 int hbhlen;
2784
2785 if (cm->cmsg_len < CMSG_LEN(sizeof(struct ip6_hbh)))
2786 return(EINVAL);
2787 hbh = (struct ip6_hbh *)CMSG_DATA(cm);
2788 hbhlen = (hbh->ip6h_len + 1) << 3;
2789 if (cm->cmsg_len != CMSG_LEN(hbhlen))
2790 return(EINVAL);
2791
2792 if (needcopy) {
2793 opt->ip6po_hbh =
2794 _MALLOC(hbhlen, M_IP6OPT, M_WAITOK);
2795 if (opt->ip6po_hbh == NULL)
2796 return ENOBUFS;
2797 bcopy(hbh, opt->ip6po_hbh, hbhlen);
2798 } else
2799 opt->ip6po_hbh = hbh;
2800 break;
2801 }
2802
2803 case IPV6_DSTOPTS:
2804 {
2805 struct ip6_dest *dest, **newdest;
2806 int destlen;
2807
2808 if (cm->cmsg_len < CMSG_LEN(sizeof(struct ip6_dest)))
2809 return(EINVAL);
2810 dest = (struct ip6_dest *)CMSG_DATA(cm);
2811 destlen = (dest->ip6d_len + 1) << 3;
2812 if (cm->cmsg_len != CMSG_LEN(destlen))
2813 return(EINVAL);
2814
2815 /*
2816 * The old advacned API is ambiguous on this
2817 * point. Our approach is to determine the
2818 * position based according to the existence
2819 * of a routing header. Note, however, that
2820 * this depends on the order of the extension
2821 * headers in the ancillary data; the 1st part
2822 * of the destination options header must
2823 * appear before the routing header in the
2824 * ancillary data, too.
2825 * RFC2292bis solved the ambiguity by
2826 * introducing separate cmsg types.
2827 */
2828 if (opt->ip6po_rthdr == NULL)
2829 newdest = &opt->ip6po_dest1;
2830 else
2831 newdest = &opt->ip6po_dest2;
2832
2833 if (needcopy) {
2834 *newdest = _MALLOC(destlen, M_IP6OPT, M_WAITOK);
2835 if (*newdest == NULL)
2836 return ENOBUFS;
2837 bcopy(dest, *newdest, destlen);
2838 } else
2839 *newdest = dest;
2840
2841 break;
2842 }
2843
2844 case IPV6_RTHDR:
2845 {
2846 struct ip6_rthdr *rth;
2847 int rthlen;
2848
2849 if (cm->cmsg_len < CMSG_LEN(sizeof(struct ip6_rthdr)))
2850 return(EINVAL);
2851 rth = (struct ip6_rthdr *)CMSG_DATA(cm);
2852 rthlen = (rth->ip6r_len + 1) << 3;
2853 if (cm->cmsg_len != CMSG_LEN(rthlen))
2854 return(EINVAL);
2855
2856 switch (rth->ip6r_type) {
2857 case IPV6_RTHDR_TYPE_0:
2858 /* must contain one addr */
2859 if (rth->ip6r_len == 0)
2860 return(EINVAL);
2861 /* length must be even */
2862 if (rth->ip6r_len % 2)
2863 return(EINVAL);
2864 if (rth->ip6r_len / 2 != rth->ip6r_segleft)
2865 return(EINVAL);
2866 break;
2867 default:
2868 return(EINVAL); /* not supported */
2869 }
2870
2871 if (needcopy) {
2872 opt->ip6po_rthdr = _MALLOC(rthlen, M_IP6OPT,
2873 M_WAITOK);
2874 if (opt->ip6po_rthdr == NULL)
2875 return ENOBUFS;
2876 bcopy(rth, opt->ip6po_rthdr, rthlen);
2877 } else
2878 opt->ip6po_rthdr = rth;
2879
2880 break;
2881 }
2882
2883 default:
2884 return(ENOPROTOOPT);
2885 }
2886 }
2887
2888 return(0);
2889 }
2890
2891 /*
2892 * Routine called from ip6_output() to loop back a copy of an IP6 multicast
2893 * packet to the input queue of a specified interface. Note that this
2894 * calls the output routine of the loopback "driver", but with an interface
2895 * pointer that might NOT be &loif -- easier than replicating that code here.
2896 */
2897 void
2898 ip6_mloopback(
2899 struct ifnet *ifp,
2900 struct mbuf *m,
2901 struct sockaddr_in6 *dst)
2902 {
2903 struct mbuf *copym;
2904 struct ip6_hdr *ip6;
2905
2906 copym = m_copy(m, 0, M_COPYALL);
2907 if (copym == NULL)
2908 return;
2909
2910 /*
2911 * Make sure to deep-copy IPv6 header portion in case the data
2912 * is in an mbuf cluster, so that we can safely override the IPv6
2913 * header portion later.
2914 */
2915 if ((copym->m_flags & M_EXT) != 0 ||
2916 copym->m_len < sizeof(struct ip6_hdr)) {
2917 copym = m_pullup(copym, sizeof(struct ip6_hdr));
2918 if (copym == NULL)
2919 return;
2920 }
2921
2922 #if DIAGNOSTIC
2923 if (copym->m_len < sizeof(*ip6)) {
2924 m_freem(copym);
2925 return;
2926 }
2927 #endif
2928
2929 ip6 = mtod(copym, struct ip6_hdr *);
2930 #ifndef SCOPEDROUTING
2931 /*
2932 * clear embedded scope identifiers if necessary.
2933 * in6_clearscope will touch the addresses only when necessary.
2934 */
2935 in6_clearscope(&ip6->ip6_src);
2936 in6_clearscope(&ip6->ip6_dst);
2937 #endif
2938
2939 #ifdef __APPLE__
2940
2941 /* Makes sure the HW checksum flags are cleaned before sending the packet */
2942
2943 copym->m_pkthdr.rcvif = 0;
2944 copym->m_pkthdr.csum_data = 0;
2945 copym->m_pkthdr.csum_flags = 0;
2946
2947 if (lo_ifp) {
2948 copym->m_pkthdr.rcvif = ifp;
2949 lck_mtx_unlock(ip6_mutex);
2950 dlil_output(lo_ifp, PF_INET6, copym, 0, (struct sockaddr *)dst, 0);
2951 lck_mtx_lock(ip6_mutex);
2952 } else
2953 m_free(copym);
2954 #else
2955 (void)if_simloop(ifp, copym, dst->sin6_family, NULL);
2956 #endif
2957 }
2958
2959 /*
2960 * Chop IPv6 header off from the payload.
2961 */
2962 static int
2963 ip6_splithdr(m, exthdrs)
2964 struct mbuf *m;
2965 struct ip6_exthdrs *exthdrs;
2966 {
2967 struct mbuf *mh;
2968 struct ip6_hdr *ip6;
2969
2970 ip6 = mtod(m, struct ip6_hdr *);
2971 if (m->m_len > sizeof(*ip6)) {
2972 MGETHDR(mh, M_DONTWAIT, MT_HEADER); /* MAC-OK */
2973 if (mh == 0) {
2974 m_freem(m);
2975 return ENOBUFS;
2976 }
2977 M_COPY_PKTHDR(mh, m);
2978 MH_ALIGN(mh, sizeof(*ip6));
2979 m->m_flags &= ~M_PKTHDR;
2980 m->m_len -= sizeof(*ip6);
2981 m->m_data += sizeof(*ip6);
2982 mh->m_next = m;
2983 m = mh;
2984 m->m_len = sizeof(*ip6);
2985 bcopy((caddr_t)ip6, mtod(m, caddr_t), sizeof(*ip6));
2986 }
2987 exthdrs->ip6e_ip6 = m;
2988 return 0;
2989 }
2990
2991 /*
2992 * Compute IPv6 extension header length.
2993 */
2994 int
2995 ip6_optlen(in6p)
2996 struct in6pcb *in6p;
2997 {
2998 int len;
2999
3000 if (!in6p->in6p_outputopts)
3001 return 0;
3002
3003 len = 0;
3004 #define elen(x) \
3005 (((struct ip6_ext *)(x)) ? (((struct ip6_ext *)(x))->ip6e_len + 1) << 3 : 0)
3006
3007 len += elen(in6p->in6p_outputopts->ip6po_hbh);
3008 if (in6p->in6p_outputopts->ip6po_rthdr)
3009 /* dest1 is valid with rthdr only */
3010 len += elen(in6p->in6p_outputopts->ip6po_dest1);
3011 len += elen(in6p->in6p_outputopts->ip6po_rthdr);
3012 len += elen(in6p->in6p_outputopts->ip6po_dest2);
3013 return len;
3014 #undef elen
3015 }
3016