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