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