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