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