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