ip6_output.c revision 60889
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 60889 2000-05-24 21:16:56Z archie $
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
1513				struct mbuf *m = NULL;
1514				caddr_t req = NULL;
1515
1516				if (m != 0)
1517					req = mtod(m, caddr_t);
1518				error = ipsec6_get_policy(in6p, req, &m);
1519				if (error == 0)
1520					error = soopt_mcopyout(sopt, m); /*XXX*/
1521				if (error == 0)
1522					m_freem(m);
1523				break;
1524			  }
1525#endif /* IPSEC */
1526
1527#ifdef IPV6FIREWALL
1528			case IPV6_FW_GET:
1529			  {
1530				struct mbuf *m;
1531				struct mbuf **mp = &m;
1532
1533				if (ip6_fw_ctl_ptr == NULL)
1534			        {
1535					return EINVAL;
1536				}
1537				error = (*ip6_fw_ctl_ptr)(optname, mp);
1538				if (error == 0)
1539					error = soopt_mcopyout(sopt, m); /* XXX */
1540				if (m)
1541					m_freem(m);
1542			  }
1543				break;
1544#endif
1545
1546			default:
1547				error = ENOPROTOOPT;
1548				break;
1549			}
1550			break;
1551		}
1552	} else {
1553		error = EINVAL;
1554	}
1555	return(error);
1556}
1557
1558/*
1559 * Set up IP6 options in pcb for insertion in output packets.
1560 * Store in mbuf with pointer in pcbopt, adding pseudo-option
1561 * with destination address if source routed.
1562 */
1563static int
1564ip6_pcbopts(pktopt, m, so, sopt)
1565	struct ip6_pktopts **pktopt;
1566	register struct mbuf *m;
1567	struct socket *so;
1568	struct sockopt *sopt;
1569{
1570	register struct ip6_pktopts *opt = *pktopt;
1571	int error = 0;
1572	struct proc *p = sopt->sopt_p;
1573	int priv = 0;
1574
1575	/* turn off any old options. */
1576	if (opt) {
1577		if (opt->ip6po_m)
1578			(void)m_free(opt->ip6po_m);
1579	} else
1580		opt = malloc(sizeof(*opt), M_IP6OPT, M_WAITOK);
1581	*pktopt = 0;
1582
1583	if (!m || m->m_len == 0) {
1584		/*
1585		 * Only turning off any previous options.
1586		 */
1587		if (opt)
1588			free(opt, M_IP6OPT);
1589		if (m)
1590			(void)m_free(m);
1591		return(0);
1592	}
1593
1594	/*  set options specified by user. */
1595	if (p && !suser(p))
1596		priv = 1;
1597	if ((error = ip6_setpktoptions(m, opt, priv)) != 0) {
1598		(void)m_free(m);
1599		return(error);
1600	}
1601	*pktopt = opt;
1602	return(0);
1603}
1604
1605/*
1606 * Set the IP6 multicast options in response to user setsockopt().
1607 */
1608static int
1609ip6_setmoptions(optname, im6op, m)
1610	int optname;
1611	struct ip6_moptions **im6op;
1612	struct mbuf *m;
1613{
1614	int error = 0;
1615	u_int loop, ifindex;
1616	struct ipv6_mreq *mreq;
1617	struct ifnet *ifp;
1618	struct ip6_moptions *im6o = *im6op;
1619	struct route_in6 ro;
1620	struct sockaddr_in6 *dst;
1621	struct in6_multi_mship *imm;
1622	struct proc *p = curproc;	/* XXX */
1623
1624	if (im6o == NULL) {
1625		/*
1626		 * No multicast option buffer attached to the pcb;
1627		 * allocate one and initialize to default values.
1628		 */
1629		im6o = (struct ip6_moptions *)
1630			malloc(sizeof(*im6o), M_IPMOPTS, M_WAITOK);
1631
1632		if (im6o == NULL)
1633			return(ENOBUFS);
1634		*im6op = im6o;
1635		im6o->im6o_multicast_ifp = NULL;
1636		im6o->im6o_multicast_hlim = ip6_defmcasthlim;
1637		im6o->im6o_multicast_loop = IPV6_DEFAULT_MULTICAST_LOOP;
1638		LIST_INIT(&im6o->im6o_memberships);
1639	}
1640
1641	switch (optname) {
1642
1643	case IPV6_MULTICAST_IF:
1644		/*
1645		 * Select the interface for outgoing multicast packets.
1646		 */
1647		if (m == NULL || m->m_len != sizeof(u_int)) {
1648			error = EINVAL;
1649			break;
1650		}
1651		ifindex = *(mtod(m, u_int *));
1652		if (ifindex < 0 || if_index < ifindex) {
1653			error = ENXIO;	/* XXX EINVAL? */
1654			break;
1655		}
1656		ifp = ifindex2ifnet[ifindex];
1657		if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {
1658			error = EADDRNOTAVAIL;
1659			break;
1660		}
1661		im6o->im6o_multicast_ifp = ifp;
1662		break;
1663
1664	case IPV6_MULTICAST_HOPS:
1665	    {
1666		/*
1667		 * Set the IP6 hoplimit for outgoing multicast packets.
1668		 */
1669		int optval;
1670		if (m == NULL || m->m_len != sizeof(int)) {
1671			error = EINVAL;
1672			break;
1673		}
1674		optval = *(mtod(m, u_int *));
1675		if (optval < -1 || optval >= 256)
1676			error = EINVAL;
1677		else if (optval == -1)
1678			im6o->im6o_multicast_hlim = ip6_defmcasthlim;
1679		else
1680			im6o->im6o_multicast_hlim = optval;
1681		break;
1682	    }
1683
1684	case IPV6_MULTICAST_LOOP:
1685		/*
1686		 * Set the loopback flag for outgoing multicast packets.
1687		 * Must be zero or one.
1688		 */
1689		if (m == NULL || m->m_len != sizeof(u_int) ||
1690		   (loop = *(mtod(m, u_int *))) > 1) {
1691			error = EINVAL;
1692			break;
1693		}
1694		im6o->im6o_multicast_loop = loop;
1695		break;
1696
1697	case IPV6_JOIN_GROUP:
1698		/*
1699		 * Add a multicast group membership.
1700		 * Group must be a valid IP6 multicast address.
1701		 */
1702		if (m == NULL || m->m_len != sizeof(struct ipv6_mreq)) {
1703			error = EINVAL;
1704			break;
1705		}
1706		mreq = mtod(m, struct ipv6_mreq *);
1707		if (IN6_IS_ADDR_UNSPECIFIED(&mreq->ipv6mr_multiaddr)) {
1708			/*
1709			 * We use the unspecified address to specify to accept
1710			 * all multicast addresses. Only super user is allowed
1711			 * to do this.
1712			 */
1713			if (suser(p)) {
1714				error = EACCES;
1715				break;
1716			}
1717		} else if (!IN6_IS_ADDR_MULTICAST(&mreq->ipv6mr_multiaddr)) {
1718			error = EINVAL;
1719			break;
1720		}
1721
1722		/*
1723		 * If the interface is specified, validate it.
1724		 */
1725		if (mreq->ipv6mr_interface < 0
1726		 || if_index < mreq->ipv6mr_interface) {
1727			error = ENXIO;	/* XXX EINVAL? */
1728			break;
1729		}
1730		/*
1731		 * If no interface was explicitly specified, choose an
1732		 * appropriate one according to the given multicast address.
1733		 */
1734		if (mreq->ipv6mr_interface == 0) {
1735			/*
1736			 * If the multicast address is in node-local scope,
1737			 * the interface should be a loopback interface.
1738			 * Otherwise, look up the routing table for the
1739			 * address, and choose the outgoing interface.
1740			 *   XXX: is it a good approach?
1741			 */
1742			if (IN6_IS_ADDR_MC_NODELOCAL(&mreq->ipv6mr_multiaddr)) {
1743				ifp = &loif[0];
1744			} else {
1745				ro.ro_rt = NULL;
1746				dst = (struct sockaddr_in6 *)&ro.ro_dst;
1747				bzero(dst, sizeof(*dst));
1748				dst->sin6_len = sizeof(struct sockaddr_in6);
1749				dst->sin6_family = AF_INET6;
1750				dst->sin6_addr = mreq->ipv6mr_multiaddr;
1751				rtalloc((struct route *)&ro);
1752				if (ro.ro_rt == NULL) {
1753					error = EADDRNOTAVAIL;
1754					break;
1755				}
1756				ifp = ro.ro_rt->rt_ifp;
1757				rtfree(ro.ro_rt);
1758			}
1759		} else
1760			ifp = ifindex2ifnet[mreq->ipv6mr_interface];
1761
1762		/*
1763		 * See if we found an interface, and confirm that it
1764		 * supports multicast
1765		 */
1766		if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {
1767			error = EADDRNOTAVAIL;
1768			break;
1769		}
1770		/*
1771		 * Put interface index into the multicast address,
1772		 * if the address has link-local scope.
1773		 */
1774		if (IN6_IS_ADDR_MC_LINKLOCAL(&mreq->ipv6mr_multiaddr)) {
1775			mreq->ipv6mr_multiaddr.s6_addr16[1]
1776				= htons(mreq->ipv6mr_interface);
1777		}
1778		/*
1779		 * See if the membership already exists.
1780		 */
1781		LIST_FOREACH(imm, &im6o->im6o_memberships, i6mm_chain)
1782			if (imm->i6mm_maddr->in6m_ifp == ifp &&
1783			    IN6_ARE_ADDR_EQUAL(&imm->i6mm_maddr->in6m_addr,
1784					       &mreq->ipv6mr_multiaddr))
1785				break;
1786		if (imm != NULL) {
1787			error = EADDRINUSE;
1788			break;
1789		}
1790		/*
1791		 * Everything looks good; add a new record to the multicast
1792		 * address list for the given interface.
1793		 */
1794		imm = malloc(sizeof(*imm), M_IPMADDR, M_WAITOK);
1795		if (imm == NULL) {
1796			error = ENOBUFS;
1797			break;
1798		}
1799		if ((imm->i6mm_maddr =
1800		     in6_addmulti(&mreq->ipv6mr_multiaddr, ifp, &error)) == NULL) {
1801			free(imm, M_IPMADDR);
1802			break;
1803		}
1804		LIST_INSERT_HEAD(&im6o->im6o_memberships, imm, i6mm_chain);
1805		break;
1806
1807	case IPV6_LEAVE_GROUP:
1808		/*
1809		 * Drop a multicast group membership.
1810		 * Group must be a valid IP6 multicast address.
1811		 */
1812		if (m == NULL || m->m_len != sizeof(struct ipv6_mreq)) {
1813			error = EINVAL;
1814			break;
1815		}
1816		mreq = mtod(m, struct ipv6_mreq *);
1817		if (IN6_IS_ADDR_UNSPECIFIED(&mreq->ipv6mr_multiaddr)) {
1818			if (suser(p)) {
1819				error = EACCES;
1820				break;
1821			}
1822		} else if (!IN6_IS_ADDR_MULTICAST(&mreq->ipv6mr_multiaddr)) {
1823			error = EINVAL;
1824			break;
1825		}
1826		/*
1827		 * If an interface address was specified, get a pointer
1828		 * to its ifnet structure.
1829		 */
1830		if (mreq->ipv6mr_interface < 0
1831		 || if_index < mreq->ipv6mr_interface) {
1832			error = ENXIO;	/* XXX EINVAL? */
1833			break;
1834		}
1835		ifp = ifindex2ifnet[mreq->ipv6mr_interface];
1836		/*
1837		 * Put interface index into the multicast address,
1838		 * if the address has link-local scope.
1839		 */
1840		if (IN6_IS_ADDR_MC_LINKLOCAL(&mreq->ipv6mr_multiaddr)) {
1841			mreq->ipv6mr_multiaddr.s6_addr16[1]
1842				= htons(mreq->ipv6mr_interface);
1843		}
1844		/*
1845		 * Find the membership in the membership list.
1846		 */
1847		LIST_FOREACH(imm, &im6o->im6o_memberships, i6mm_chain) {
1848			if ((ifp == NULL ||
1849			     imm->i6mm_maddr->in6m_ifp == ifp) &&
1850			    IN6_ARE_ADDR_EQUAL(&imm->i6mm_maddr->in6m_addr,
1851					       &mreq->ipv6mr_multiaddr))
1852				break;
1853		}
1854		if (imm == NULL) {
1855			/* Unable to resolve interface */
1856			error = EADDRNOTAVAIL;
1857			break;
1858		}
1859		/*
1860		 * Give up the multicast address record to which the
1861		 * membership points.
1862		 */
1863		LIST_REMOVE(imm, i6mm_chain);
1864		in6_delmulti(imm->i6mm_maddr);
1865		free(imm, M_IPMADDR);
1866		break;
1867
1868	default:
1869		error = EOPNOTSUPP;
1870		break;
1871	}
1872
1873	/*
1874	 * If all options have default values, no need to keep the mbuf.
1875	 */
1876	if (im6o->im6o_multicast_ifp == NULL &&
1877	    im6o->im6o_multicast_hlim == ip6_defmcasthlim &&
1878	    im6o->im6o_multicast_loop == IPV6_DEFAULT_MULTICAST_LOOP &&
1879	    LIST_EMPTY(&im6o->im6o_memberships)) {
1880		free(*im6op, M_IPMOPTS);
1881		*im6op = NULL;
1882	}
1883
1884	return(error);
1885}
1886
1887/*
1888 * Return the IP6 multicast options in response to user getsockopt().
1889 */
1890static int
1891ip6_getmoptions(optname, im6o, mp)
1892	int optname;
1893	register struct ip6_moptions *im6o;
1894	register struct mbuf **mp;
1895{
1896	u_int *hlim, *loop, *ifindex;
1897
1898	*mp = m_get(M_WAIT, MT_HEADER);		/*XXX*/
1899
1900	switch (optname) {
1901
1902	case IPV6_MULTICAST_IF:
1903		ifindex = mtod(*mp, u_int *);
1904		(*mp)->m_len = sizeof(u_int);
1905		if (im6o == NULL || im6o->im6o_multicast_ifp == NULL)
1906			*ifindex = 0;
1907		else
1908			*ifindex = im6o->im6o_multicast_ifp->if_index;
1909		return(0);
1910
1911	case IPV6_MULTICAST_HOPS:
1912		hlim = mtod(*mp, u_int *);
1913		(*mp)->m_len = sizeof(u_int);
1914		if (im6o == NULL)
1915			*hlim = ip6_defmcasthlim;
1916		else
1917			*hlim = im6o->im6o_multicast_hlim;
1918		return(0);
1919
1920	case IPV6_MULTICAST_LOOP:
1921		loop = mtod(*mp, u_int *);
1922		(*mp)->m_len = sizeof(u_int);
1923		if (im6o == NULL)
1924			*loop = ip6_defmcasthlim;
1925		else
1926			*loop = im6o->im6o_multicast_loop;
1927		return(0);
1928
1929	default:
1930		return(EOPNOTSUPP);
1931	}
1932}
1933
1934/*
1935 * Discard the IP6 multicast options.
1936 */
1937void
1938ip6_freemoptions(im6o)
1939	register struct ip6_moptions *im6o;
1940{
1941	struct in6_multi_mship *imm;
1942
1943	if (im6o == NULL)
1944		return;
1945
1946	while ((imm = LIST_FIRST(&im6o->im6o_memberships)) != NULL) {
1947		LIST_REMOVE(imm, i6mm_chain);
1948		if (imm->i6mm_maddr)
1949			in6_delmulti(imm->i6mm_maddr);
1950		free(imm, M_IPMADDR);
1951	}
1952	free(im6o, M_IPMOPTS);
1953}
1954
1955/*
1956 * Set IPv6 outgoing packet options based on advanced API.
1957 */
1958int
1959ip6_setpktoptions(control, opt, priv)
1960	struct mbuf *control;
1961	struct ip6_pktopts *opt;
1962	int priv;
1963{
1964	register struct cmsghdr *cm = 0;
1965
1966	if (control == 0 || opt == 0)
1967		return(EINVAL);
1968
1969	bzero(opt, sizeof(*opt));
1970	opt->ip6po_hlim = -1; /* -1 means to use default hop limit */
1971
1972	/*
1973	 * XXX: Currently, we assume all the optional information is stored
1974	 * in a single mbuf.
1975	 */
1976	if (control->m_next)
1977		return(EINVAL);
1978
1979	opt->ip6po_m = control;
1980
1981	for (; control->m_len; control->m_data += ALIGN(cm->cmsg_len),
1982		     control->m_len -= ALIGN(cm->cmsg_len)) {
1983		cm = mtod(control, struct cmsghdr *);
1984		if (cm->cmsg_len == 0 || cm->cmsg_len > control->m_len)
1985			return(EINVAL);
1986		if (cm->cmsg_level != IPPROTO_IPV6)
1987			continue;
1988
1989		switch(cm->cmsg_type) {
1990		case IPV6_PKTINFO:
1991			if (cm->cmsg_len != CMSG_LEN(sizeof(struct in6_pktinfo)))
1992				return(EINVAL);
1993			opt->ip6po_pktinfo = (struct in6_pktinfo *)CMSG_DATA(cm);
1994			if (opt->ip6po_pktinfo->ipi6_ifindex &&
1995			    IN6_IS_ADDR_LINKLOCAL(&opt->ip6po_pktinfo->ipi6_addr))
1996				opt->ip6po_pktinfo->ipi6_addr.s6_addr16[1] =
1997					htons(opt->ip6po_pktinfo->ipi6_ifindex);
1998
1999			if (opt->ip6po_pktinfo->ipi6_ifindex > if_index
2000			 || opt->ip6po_pktinfo->ipi6_ifindex < 0) {
2001				return(ENXIO);
2002			}
2003
2004			if (!IN6_IS_ADDR_UNSPECIFIED(&opt->ip6po_pktinfo->ipi6_addr)) {
2005				struct ifaddr *ia;
2006				struct sockaddr_in6 sin6;
2007
2008				bzero(&sin6, sizeof(sin6));
2009				sin6.sin6_len = sizeof(sin6);
2010				sin6.sin6_family = AF_INET6;
2011				sin6.sin6_addr =
2012					opt->ip6po_pktinfo->ipi6_addr;
2013				ia = ifa_ifwithaddr(sin6tosa(&sin6));
2014				if (ia == NULL ||
2015				    (opt->ip6po_pktinfo->ipi6_ifindex &&
2016				     (ia->ifa_ifp->if_index !=
2017				      opt->ip6po_pktinfo->ipi6_ifindex))) {
2018					return(EADDRNOTAVAIL);
2019				}
2020				/*
2021				 * Check if the requested source address is
2022				 * indeed a unicast address assigned to the
2023				 * node.
2024				 */
2025				if (IN6_IS_ADDR_MULTICAST(&opt->ip6po_pktinfo->ipi6_addr))
2026					return(EADDRNOTAVAIL);
2027			}
2028			break;
2029
2030		case IPV6_HOPLIMIT:
2031			if (cm->cmsg_len != CMSG_LEN(sizeof(int)))
2032				return(EINVAL);
2033
2034			opt->ip6po_hlim = *(int *)CMSG_DATA(cm);
2035			if (opt->ip6po_hlim < -1 || opt->ip6po_hlim > 255)
2036				return(EINVAL);
2037			break;
2038
2039		case IPV6_NEXTHOP:
2040			if (!priv)
2041				return(EPERM);
2042			if (cm->cmsg_len < sizeof(u_char) ||
2043			    cm->cmsg_len < CMSG_LEN(*CMSG_DATA(cm)))
2044				return(EINVAL);
2045
2046			opt->ip6po_nexthop = (struct sockaddr *)CMSG_DATA(cm);
2047
2048			break;
2049
2050		case IPV6_HOPOPTS:
2051			if (cm->cmsg_len < CMSG_LEN(sizeof(struct ip6_hbh)))
2052				return(EINVAL);
2053			opt->ip6po_hbh = (struct ip6_hbh *)CMSG_DATA(cm);
2054			if (cm->cmsg_len !=
2055			    CMSG_LEN((opt->ip6po_hbh->ip6h_len + 1) << 3))
2056				return(EINVAL);
2057			break;
2058
2059		case IPV6_DSTOPTS:
2060			if (cm->cmsg_len < CMSG_LEN(sizeof(struct ip6_dest)))
2061				return(EINVAL);
2062
2063			/*
2064			 * If there is no routing header yet, the destination
2065			 * options header should be put on the 1st part.
2066			 * Otherwise, the header should be on the 2nd part.
2067			 * (See RFC 2460, section 4.1)
2068			 */
2069			if (opt->ip6po_rthdr == NULL) {
2070				opt->ip6po_dest1 =
2071					(struct ip6_dest *)CMSG_DATA(cm);
2072				if (cm->cmsg_len !=
2073				    CMSG_LEN((opt->ip6po_dest1->ip6d_len + 1)
2074					     << 3))
2075					return(EINVAL);
2076			} else {
2077				opt->ip6po_dest2 =
2078					(struct ip6_dest *)CMSG_DATA(cm);
2079				if (cm->cmsg_len !=
2080				    CMSG_LEN((opt->ip6po_dest2->ip6d_len + 1)
2081					     << 3))
2082					return(EINVAL);
2083			}
2084			break;
2085
2086		case IPV6_RTHDR:
2087			if (cm->cmsg_len < CMSG_LEN(sizeof(struct ip6_rthdr)))
2088				return(EINVAL);
2089			opt->ip6po_rthdr = (struct ip6_rthdr *)CMSG_DATA(cm);
2090			if (cm->cmsg_len !=
2091			    CMSG_LEN((opt->ip6po_rthdr->ip6r_len + 1) << 3))
2092				return(EINVAL);
2093			switch(opt->ip6po_rthdr->ip6r_type) {
2094			case IPV6_RTHDR_TYPE_0:
2095				if (opt->ip6po_rthdr->ip6r_segleft == 0)
2096					return(EINVAL);
2097				break;
2098			default:
2099				return(EINVAL);
2100			}
2101			break;
2102
2103		default:
2104			return(ENOPROTOOPT);
2105		}
2106	}
2107
2108	return(0);
2109}
2110
2111/*
2112 * Routine called from ip6_output() to loop back a copy of an IP6 multicast
2113 * packet to the input queue of a specified interface.  Note that this
2114 * calls the output routine of the loopback "driver", but with an interface
2115 * pointer that might NOT be &loif -- easier than replicating that code here.
2116 */
2117void
2118ip6_mloopback(ifp, m, dst)
2119	struct ifnet *ifp;
2120	register struct mbuf *m;
2121	register struct sockaddr_in6 *dst;
2122{
2123	struct	mbuf *copym;
2124
2125	copym = m_copy(m, 0, M_COPYALL);
2126	if (copym != NULL) {
2127		(void)if_simloop(ifp, copym, dst->sin6_family, 0);
2128	}
2129}
2130
2131/*
2132 * Chop IPv6 header off from the payload.
2133 */
2134static int
2135ip6_splithdr(m, exthdrs)
2136	struct mbuf *m;
2137	struct ip6_exthdrs *exthdrs;
2138{
2139	struct mbuf *mh;
2140	struct ip6_hdr *ip6;
2141
2142	ip6 = mtod(m, struct ip6_hdr *);
2143	if (m->m_len > sizeof(*ip6)) {
2144		MGETHDR(mh, M_DONTWAIT, MT_HEADER);
2145		if (mh == 0) {
2146			m_freem(m);
2147			return ENOBUFS;
2148		}
2149		M_COPY_PKTHDR(mh, m);
2150		MH_ALIGN(mh, sizeof(*ip6));
2151		m->m_flags &= ~M_PKTHDR;
2152		m->m_len -= sizeof(*ip6);
2153		m->m_data += sizeof(*ip6);
2154		mh->m_next = m;
2155		m = mh;
2156		m->m_len = sizeof(*ip6);
2157		bcopy((caddr_t)ip6, mtod(m, caddr_t), sizeof(*ip6));
2158	}
2159	exthdrs->ip6e_ip6 = m;
2160	return 0;
2161}
2162
2163/*
2164 * Compute IPv6 extension header length.
2165 */
2166int
2167ip6_optlen(in6p)
2168	struct in6pcb *in6p;
2169{
2170	int len;
2171
2172	if (!in6p->in6p_outputopts)
2173		return 0;
2174
2175	len = 0;
2176#define elen(x) \
2177    (((struct ip6_ext *)(x)) ? (((struct ip6_ext *)(x))->ip6e_len + 1) << 3 : 0)
2178
2179	len += elen(in6p->in6p_outputopts->ip6po_hbh);
2180	len += elen(in6p->in6p_outputopts->ip6po_dest1);
2181	len += elen(in6p->in6p_outputopts->ip6po_rthdr);
2182	len += elen(in6p->in6p_outputopts->ip6po_dest2);
2183	return len;
2184#undef elen
2185}
2186
2187