]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/netinet6/ip6_input.c
This commit was generated by cvs2svn to compensate for changes in r90926,
[FreeBSD/FreeBSD.git] / sys / netinet6 / ip6_input.c
1 /*      $FreeBSD$       */
2 /*      $KAME: ip6_input.c,v 1.194 2001/05/27 13:28:35 itojun Exp $     */
3
4 /*
5  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the project nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32
33 /*
34  * Copyright (c) 1982, 1986, 1988, 1993
35  *      The Regents of the University of California.  All rights reserved.
36  *
37  * Redistribution and use in source and binary forms, with or without
38  * modification, are permitted provided that the following conditions
39  * are met:
40  * 1. Redistributions of source code must retain the above copyright
41  *    notice, this list of conditions and the following disclaimer.
42  * 2. Redistributions in binary form must reproduce the above copyright
43  *    notice, this list of conditions and the following disclaimer in the
44  *    documentation and/or other materials provided with the distribution.
45  * 3. All advertising materials mentioning features or use of this software
46  *    must display the following acknowledgement:
47  *      This product includes software developed by the University of
48  *      California, Berkeley and its contributors.
49  * 4. Neither the name of the University nor the names of its contributors
50  *    may be used to endorse or promote products derived from this software
51  *    without specific prior written permission.
52  *
53  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
54  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
57  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63  * SUCH DAMAGE.
64  *
65  *      @(#)ip_input.c  8.2 (Berkeley) 1/4/94
66  */
67
68 #include "opt_ip6fw.h"
69 #include "opt_inet.h"
70 #include "opt_inet6.h"
71 #include "opt_ipsec.h"
72 #include "opt_pfil_hooks.h"
73
74 #include <sys/param.h>
75 #include <sys/systm.h>
76 #include <sys/malloc.h>
77 #include <sys/mbuf.h>
78 #include <sys/proc.h>
79 #include <sys/domain.h>
80 #include <sys/protosw.h>
81 #include <sys/socket.h>
82 #include <sys/socketvar.h>
83 #include <sys/errno.h>
84 #include <sys/time.h>
85 #include <sys/kernel.h>
86 #include <sys/syslog.h>
87
88 #include <net/if.h>
89 #include <net/if_types.h>
90 #include <net/if_dl.h>
91 #include <net/route.h>
92 #include <net/netisr.h>
93 #include <net/intrq.h>
94 #ifdef PFIL_HOOKS
95 #include <net/pfil.h>
96 #endif
97
98 #include <netinet/in.h>
99 #include <netinet/in_systm.h>
100 #ifdef INET
101 #include <netinet/ip.h>
102 #include <netinet/ip_icmp.h>
103 #endif /*INET*/
104 #include <netinet/ip6.h>
105 #include <netinet6/in6_var.h>
106 #include <netinet6/ip6_var.h>
107 #include <netinet/in_pcb.h>
108 #include <netinet/icmp6.h>
109 #include <netinet6/in6_ifattach.h>
110 #include <netinet6/nd6.h>
111 #include <netinet6/in6_prefix.h>
112
113 #ifdef IPSEC
114 #include <netinet6/ipsec.h>
115 #ifdef INET6
116 #include <netinet6/ipsec6.h>
117 #endif
118 #endif
119
120 #include <netinet6/ip6_fw.h>
121
122 #include <netinet6/ip6protosw.h>
123
124 #include <net/net_osdep.h>
125
126 extern struct domain inet6domain;
127 extern struct ip6protosw inet6sw[];
128
129 u_char ip6_protox[IPPROTO_MAX];
130 static int ip6qmaxlen = IFQ_MAXLEN;
131 struct in6_ifaddr *in6_ifaddr;
132
133 extern struct callout in6_tmpaddrtimer_ch;
134
135 int ip6_forward_srcrt;                  /* XXX */
136 int ip6_sourcecheck;                    /* XXX */
137 int ip6_sourcecheck_interval;           /* XXX */
138
139 int ip6_ours_check_algorithm;
140
141
142 /* firewall hooks */
143 ip6_fw_chk_t *ip6_fw_chk_ptr;
144 ip6_fw_ctl_t *ip6_fw_ctl_ptr;
145 int ip6_fw_enable = 1;
146
147 struct ip6stat ip6stat;
148
149 static void ip6_init2 __P((void *));
150 static struct mbuf *ip6_setdstifaddr __P((struct mbuf *, struct in6_ifaddr *));
151
152 static int ip6_hopopts_input __P((u_int32_t *, u_int32_t *, struct mbuf **, int *));
153 #ifdef PULLDOWN_TEST
154 static struct mbuf *ip6_pullexthdr __P((struct mbuf *, size_t, int));
155 #endif
156
157
158 /*
159  * IP6 initialization: fill in IP6 protocol switch table.
160  * All protocols not implemented in kernel go to raw IP6 protocol handler.
161  */
162 void
163 ip6_init()
164 {
165         struct ip6protosw *pr;
166         int i;
167         struct timeval tv;
168
169 #ifdef DIAGNOSTIC
170         if (sizeof(struct protosw) != sizeof(struct ip6protosw))
171                 panic("sizeof(protosw) != sizeof(ip6protosw)");
172 #endif
173         pr = (struct ip6protosw *)pffindproto(PF_INET6, IPPROTO_RAW, SOCK_RAW);
174         if (pr == 0)
175                 panic("ip6_init");
176         for (i = 0; i < IPPROTO_MAX; i++)
177                 ip6_protox[i] = pr - inet6sw;
178         for (pr = (struct ip6protosw *)inet6domain.dom_protosw;
179             pr < (struct ip6protosw *)inet6domain.dom_protoswNPROTOSW; pr++)
180                 if (pr->pr_domain->dom_family == PF_INET6 &&
181                     pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW)
182                         ip6_protox[pr->pr_protocol] = pr - inet6sw;
183         ip6intrq.ifq_maxlen = ip6qmaxlen;
184         mtx_init(&ip6intrq.ifq_mtx, "ip6_inq", MTX_DEF);
185         ip6intrq_present = 1;
186         register_netisr(NETISR_IPV6, ip6intr);
187         nd6_init();
188         frag6_init();
189         /*
190          * in many cases, random() here does NOT return random number
191          * as initialization during bootstrap time occur in fixed order.
192          */
193         microtime(&tv);
194         ip6_flow_seq = random() ^ tv.tv_usec;
195         microtime(&tv);
196         ip6_desync_factor = (random() ^ tv.tv_usec) % MAX_TEMP_DESYNC_FACTOR;
197 }
198
199 static void
200 ip6_init2(dummy)
201         void *dummy;
202 {
203
204         /*
205          * to route local address of p2p link to loopback,
206          * assign loopback address first.
207          */
208         in6_ifattach(&loif[0], NULL);
209
210         /* nd6_timer_init */
211         callout_init(&nd6_timer_ch, 0);
212         callout_reset(&nd6_timer_ch, hz, nd6_timer, NULL);
213
214         /* router renumbering prefix list maintenance */
215         callout_init(&in6_rr_timer_ch, 0);
216         callout_reset(&in6_rr_timer_ch, hz, in6_rr_timer, NULL);
217
218         /* timer for regeneranation of temporary addresses randomize ID */
219         callout_reset(&in6_tmpaddrtimer_ch,
220                       (ip6_temp_preferred_lifetime - ip6_desync_factor -
221                        ip6_temp_regen_advance) * hz,
222                       in6_tmpaddrtimer, NULL);
223 }
224
225 /* cheat */
226 /* This must be after route_init(), which is now SI_ORDER_THIRD */
227 SYSINIT(netinet6init2, SI_SUB_PROTO_DOMAIN, SI_ORDER_MIDDLE, ip6_init2, NULL);
228
229 /*
230  * IP6 input interrupt handling. Just pass the packet to ip6_input.
231  */
232 void
233 ip6intr()
234 {
235         int s;
236         struct mbuf *m;
237
238         for (;;) {
239                 s = splimp();
240                 IF_DEQUEUE(&ip6intrq, m);
241                 splx(s);
242                 if (m == 0)
243                         return;
244                 ip6_input(m);
245         }
246 }
247
248 extern struct   route_in6 ip6_forward_rt;
249
250 void
251 ip6_input(m)
252         struct mbuf *m;
253 {
254         struct ip6_hdr *ip6;
255         int off = sizeof(struct ip6_hdr), nest;
256         u_int32_t plen;
257         u_int32_t rtalert = ~0;
258         int nxt, ours = 0;
259         struct ifnet *deliverifp = NULL;
260 #ifdef  PFIL_HOOKS
261         struct packet_filter_hook *pfh;
262         struct mbuf *m0;
263         int rv;
264 #endif  /* PFIL_HOOKS */
265
266 #ifdef IPSEC
267         /*
268          * should the inner packet be considered authentic?
269          * see comment in ah4_input().
270          */
271         if (m) {
272                 m->m_flags &= ~M_AUTHIPHDR;
273                 m->m_flags &= ~M_AUTHIPDGM;
274         }
275 #endif
276
277         /*
278          * make sure we don't have onion peering information into m_aux.
279          */
280         ip6_delaux(m);
281
282         /*
283          * mbuf statistics by kazu
284          */
285         if (m->m_flags & M_EXT) {
286                 if (m->m_next)
287                         ip6stat.ip6s_mext2m++;
288                 else
289                         ip6stat.ip6s_mext1++;
290         } else {
291 #define M2MMAX  (sizeof(ip6stat.ip6s_m2m)/sizeof(ip6stat.ip6s_m2m[0]))
292                 if (m->m_next) {
293                         if (m->m_flags & M_LOOP) {
294                                 ip6stat.ip6s_m2m[loif[0].if_index]++;   /*XXX*/
295                         } else if (m->m_pkthdr.rcvif->if_index < M2MMAX)
296                                 ip6stat.ip6s_m2m[m->m_pkthdr.rcvif->if_index]++;
297                         else
298                                 ip6stat.ip6s_m2m[0]++;
299                 } else
300                         ip6stat.ip6s_m1++;
301 #undef M2MMAX
302         }
303
304         in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_receive);
305         ip6stat.ip6s_total++;
306
307 #ifndef PULLDOWN_TEST
308         /*
309          * L2 bridge code and some other code can return mbuf chain
310          * that does not conform to KAME requirement.  too bad.
311          * XXX: fails to join if interface MTU > MCLBYTES.  jumbogram?
312          */
313         if (m && m->m_next != NULL && m->m_pkthdr.len < MCLBYTES) {
314                 struct mbuf *n;
315
316                 MGETHDR(n, M_DONTWAIT, MT_HEADER);
317                 if (n)
318                         M_COPY_PKTHDR(n, m);
319                 if (n && m->m_pkthdr.len > MHLEN) {
320                         MCLGET(n, M_DONTWAIT);
321                         if ((n->m_flags & M_EXT) == 0) {
322                                 m_freem(n);
323                                 n = NULL;
324                         }
325                 }
326                 if (!n) {
327                         m_freem(m);
328                         return; /*ENOBUFS*/
329                 }
330
331                 m_copydata(m, 0, m->m_pkthdr.len, mtod(n, caddr_t));
332                 n->m_len = m->m_pkthdr.len;
333                 m_freem(m);
334                 m = n;
335         }
336         IP6_EXTHDR_CHECK(m, 0, sizeof(struct ip6_hdr), /*nothing*/);
337 #endif
338
339         if (m->m_len < sizeof(struct ip6_hdr)) {
340                 struct ifnet *inifp;
341                 inifp = m->m_pkthdr.rcvif;
342                 if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == 0) {
343                         ip6stat.ip6s_toosmall++;
344                         in6_ifstat_inc(inifp, ifs6_in_hdrerr);
345                         return;
346                 }
347         }
348
349         ip6 = mtod(m, struct ip6_hdr *);
350
351         if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) {
352                 ip6stat.ip6s_badvers++;
353                 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr);
354                 goto bad;
355         }
356
357 #ifdef PFIL_HOOKS
358         /*
359          * Run through list of hooks for input packets.  If there are any
360          * filters which require that additional packets in the flow are
361          * not fast-forwarded, they must clear the M_CANFASTFWD flag.
362          * Note that filters must _never_ set this flag, as another filter
363          * in the list may have previously cleared it.
364          */
365         m0 = m;
366         pfh = pfil_hook_get(PFIL_IN, &inet6sw[ip6_protox[IPPROTO_IPV6]].pr_pfh);
367         for (; pfh; pfh = pfh->pfil_link.tqe_next)
368                 if (pfh->pfil_func) {
369                         rv = pfh->pfil_func(ip6, sizeof(*ip6),
370                                             m->m_pkthdr.rcvif, 0, &m0);
371                         if (rv)
372                                 return;
373                         m = m0;
374                         if (m == NULL)
375                                 return;
376                         ip6 = mtod(m, struct ip6_hdr *);
377                 }
378 #endif /* PFIL_HOOKS */
379
380         ip6stat.ip6s_nxthist[ip6->ip6_nxt]++;
381
382         /*
383          * Check with the firewall...
384          */
385         if (ip6_fw_enable && ip6_fw_chk_ptr) {
386                 u_short port = 0;
387                 /* If ipfw says divert, we have to just drop packet */
388                 /* use port as a dummy argument */
389                 if ((*ip6_fw_chk_ptr)(&ip6, NULL, &port, &m)) {
390                         m_freem(m);
391                         m = NULL;
392                 }
393                 if (!m)
394                         return;
395         }
396
397         /*
398          * Check against address spoofing/corruption.
399          */
400         if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_src) ||
401             IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_dst)) {
402                 /*
403                  * XXX: "badscope" is not very suitable for a multicast source.
404                  */
405                 ip6stat.ip6s_badscope++;
406                 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr);
407                 goto bad;
408         }
409         if ((IN6_IS_ADDR_LOOPBACK(&ip6->ip6_src) ||
410              IN6_IS_ADDR_LOOPBACK(&ip6->ip6_dst)) &&
411             (m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) == 0) {
412                 ip6stat.ip6s_badscope++;
413                 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr);
414                 goto bad;
415         }
416         /*
417          * The following check is not documented in specs.  A malicious
418          * party may be able to use IPv4 mapped addr to confuse tcp/udp stack
419          * and bypass security checks (act as if it was from 127.0.0.1 by using
420          * IPv6 src ::ffff:127.0.0.1).  Be cautious.
421          *
422          * This check chokes if we are in an SIIT cloud.  As none of BSDs
423          * support IPv4-less kernel compilation, we cannot support SIIT
424          * environment at all.  So, it makes more sense for us to reject any
425          * malicious packets for non-SIIT environment, than try to do a
426          * partical support for SIIT environment.
427          */
428         if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) ||
429             IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) {
430                 ip6stat.ip6s_badscope++;
431                 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr);
432                 goto bad;
433         }
434 #if 0
435         /*
436          * Reject packets with IPv4 compatible addresses (auto tunnel).
437          *
438          * The code forbids auto tunnel relay case in RFC1933 (the check is
439          * stronger than RFC1933).  We may want to re-enable it if mech-xx
440          * is revised to forbid relaying case.
441          */
442         if (IN6_IS_ADDR_V4COMPAT(&ip6->ip6_src) ||
443             IN6_IS_ADDR_V4COMPAT(&ip6->ip6_dst)) {
444                 ip6stat.ip6s_badscope++;
445                 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr);
446                 goto bad;
447         }
448 #endif
449
450         /* drop packets if interface ID portion is already filled */
451         if ((m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) == 0) {
452                 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src) &&
453                     ip6->ip6_src.s6_addr16[1]) {
454                         ip6stat.ip6s_badscope++;
455                         goto bad;
456                 }
457                 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst) &&
458                     ip6->ip6_dst.s6_addr16[1]) {
459                         ip6stat.ip6s_badscope++;
460                         goto bad;
461                 }
462         }
463
464         if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src))
465                 ip6->ip6_src.s6_addr16[1]
466                         = htons(m->m_pkthdr.rcvif->if_index);
467         if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst))
468                 ip6->ip6_dst.s6_addr16[1]
469                         = htons(m->m_pkthdr.rcvif->if_index);
470
471 #if 0 /* this case seems to be unnecessary. (jinmei, 20010401) */
472         /*
473          * We use rt->rt_ifp to determine if the address is ours or not.
474          * If rt_ifp is lo0, the address is ours.
475          * The problem here is, rt->rt_ifp for fe80::%lo0/64 is set to lo0,
476          * so any address under fe80::%lo0/64 will be mistakenly considered
477          * local.  The special case is supplied to handle the case properly
478          * by actually looking at interface addresses
479          * (using in6ifa_ifpwithaddr).
480          */
481         if ((m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) != 0 &&
482             IN6_IS_ADDR_LINKLOCAL(&ip6->ip6_dst)) {
483                 if (!in6ifa_ifpwithaddr(m->m_pkthdr.rcvif, &ip6->ip6_dst)) {
484                         icmp6_error(m, ICMP6_DST_UNREACH,
485                             ICMP6_DST_UNREACH_ADDR, 0);
486                         /* m is already freed */
487                         return;
488                 }
489
490                 ours = 1;
491                 deliverifp = m->m_pkthdr.rcvif;
492                 goto hbhcheck;
493         }
494 #endif
495
496         /*
497          * Multicast check
498          */
499         if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
500                 struct  in6_multi *in6m = 0;
501
502                 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_mcast);
503                 /*
504                  * See if we belong to the destination multicast group on the
505                  * arrival interface.
506                  */
507                 IN6_LOOKUP_MULTI(ip6->ip6_dst, m->m_pkthdr.rcvif, in6m);
508                 if (in6m)
509                         ours = 1;
510                 else if (!ip6_mrouter) {
511                         ip6stat.ip6s_notmember++;
512                         ip6stat.ip6s_cantforward++;
513                         in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);
514                         goto bad;
515                 }
516                 deliverifp = m->m_pkthdr.rcvif;
517                 goto hbhcheck;
518         }
519
520         /*
521          *  Unicast check
522          */
523         switch (ip6_ours_check_algorithm) {
524         default:
525                 /*
526                  * XXX: I intentionally broke our indentation rule here,
527                  *      since this switch-case is just for measurement and
528                  *      therefore should soon be removed.
529                  */
530         if (ip6_forward_rt.ro_rt != NULL &&
531             (ip6_forward_rt.ro_rt->rt_flags & RTF_UP) != 0 && 
532             IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst,
533                                &((struct sockaddr_in6 *)(&ip6_forward_rt.ro_dst))->sin6_addr))
534                 ip6stat.ip6s_forward_cachehit++;
535         else {
536                 struct sockaddr_in6 *dst6;
537
538                 if (ip6_forward_rt.ro_rt) {
539                         /* route is down or destination is different */
540                         ip6stat.ip6s_forward_cachemiss++;
541                         RTFREE(ip6_forward_rt.ro_rt);
542                         ip6_forward_rt.ro_rt = 0;
543                 }
544
545                 bzero(&ip6_forward_rt.ro_dst, sizeof(struct sockaddr_in6));
546                 dst6 = (struct sockaddr_in6 *)&ip6_forward_rt.ro_dst;
547                 dst6->sin6_len = sizeof(struct sockaddr_in6);
548                 dst6->sin6_family = AF_INET6;
549                 dst6->sin6_addr = ip6->ip6_dst;
550 #ifdef SCOPEDROUTING
551                 ip6_forward_rt.ro_dst.sin6_scope_id =
552                         in6_addr2scopeid(m->m_pkthdr.rcvif, &ip6->ip6_dst);
553 #endif
554
555                 rtalloc_ign((struct route *)&ip6_forward_rt, RTF_PRCLONING);
556         }
557
558 #define rt6_key(r) ((struct sockaddr_in6 *)((r)->rt_nodes->rn_key))
559
560         /*
561          * Accept the packet if the forwarding interface to the destination
562          * according to the routing table is the loopback interface,
563          * unless the associated route has a gateway.
564          * Note that this approach causes to accept a packet if there is a
565          * route to the loopback interface for the destination of the packet.
566          * But we think it's even useful in some situations, e.g. when using
567          * a special daemon which wants to intercept the packet.
568          *
569          * XXX: some OSes automatically make a cloned route for the destination
570          * of an outgoing packet.  If the outgoing interface of the packet
571          * is a loopback one, the kernel would consider the packet to be
572          * accepted, even if we have no such address assinged on the interface.
573          * We check the cloned flag of the route entry to reject such cases,
574          * assuming that route entries for our own addresses are not made by
575          * cloning (it should be true because in6_addloop explicitly installs
576          * the host route).  However, we might have to do an explicit check
577          * while it would be less efficient.  Or, should we rather install a
578          * reject route for such a case?
579          */
580         if (ip6_forward_rt.ro_rt &&
581             (ip6_forward_rt.ro_rt->rt_flags &
582              (RTF_HOST|RTF_GATEWAY)) == RTF_HOST &&
583 #ifdef RTF_WASCLONED
584             !(ip6_forward_rt.ro_rt->rt_flags & RTF_WASCLONED) &&
585 #endif
586 #ifdef RTF_CLONED
587             !(ip6_forward_rt.ro_rt->rt_flags & RTF_CLONED) &&
588 #endif
589 #if 0
590             /*
591              * The check below is redundant since the comparison of
592              * the destination and the key of the rtentry has
593              * already done through looking up the routing table.
594              */
595             IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst,
596                                 &rt6_key(ip6_forward_rt.ro_rt)->sin6_addr)
597 #endif
598             ip6_forward_rt.ro_rt->rt_ifp->if_type == IFT_LOOP) {
599                 struct in6_ifaddr *ia6 =
600                         (struct in6_ifaddr *)ip6_forward_rt.ro_rt->rt_ifa;
601
602                 /*
603                  * record address information into m_aux.
604                  */
605                 (void)ip6_setdstifaddr(m, ia6);
606
607                 /*
608                  * packets to a tentative, duplicated, or somehow invalid
609                  * address must not be accepted.
610                  */
611                 if (!(ia6->ia6_flags & IN6_IFF_NOTREADY)) {
612                         /* this address is ready */
613                         ours = 1;
614                         deliverifp = ia6->ia_ifp;       /* correct? */
615                         /* Count the packet in the ip address stats */
616                         ia6->ia_ifa.if_ipackets++;
617                         ia6->ia_ifa.if_ibytes += m->m_pkthdr.len;
618                         goto hbhcheck;
619                 } else {
620                         /* address is not ready, so discard the packet. */
621                         nd6log((LOG_INFO,
622                             "ip6_input: packet to an unready address %s->%s\n",
623                             ip6_sprintf(&ip6->ip6_src),
624                             ip6_sprintf(&ip6->ip6_dst)));
625
626                         goto bad;
627                 }
628         }
629         } /* XXX indentation (see above) */
630
631         /*
632          * FAITH(Firewall Aided Internet Translator)
633          */
634         if (ip6_keepfaith) {
635                 if (ip6_forward_rt.ro_rt && ip6_forward_rt.ro_rt->rt_ifp
636                  && ip6_forward_rt.ro_rt->rt_ifp->if_type == IFT_FAITH) {
637                         /* XXX do we need more sanity checks? */
638                         ours = 1;
639                         deliverifp = ip6_forward_rt.ro_rt->rt_ifp; /*faith*/
640                         goto hbhcheck;
641                 }
642         }
643
644         /*
645          * Now there is no reason to process the packet if it's not our own
646          * and we're not a router.
647          */
648         if (!ip6_forwarding) {
649                 ip6stat.ip6s_cantforward++;
650                 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);
651                 goto bad;
652         }
653
654   hbhcheck:
655         /*
656          * record address information into m_aux, if we don't have one yet.
657          * note that we are unable to record it, if the address is not listed
658          * as our interface address (e.g. multicast addresses, addresses
659          * within FAITH prefixes and such).
660          */
661         if (deliverifp && !ip6_getdstifaddr(m)) {
662                 struct in6_ifaddr *ia6;
663
664                 ia6 = in6_ifawithifp(deliverifp, &ip6->ip6_dst);
665                 if (ia6) {
666                         if (!ip6_setdstifaddr(m, ia6)) {
667                                 /*
668                                  * XXX maybe we should drop the packet here,
669                                  * as we could not provide enough information
670                                  * to the upper layers.
671                                  */
672                         }
673                 }
674         }
675
676         /*
677          * Process Hop-by-Hop options header if it's contained.
678          * m may be modified in ip6_hopopts_input().
679          * If a JumboPayload option is included, plen will also be modified.
680          */
681         plen = (u_int32_t)ntohs(ip6->ip6_plen);
682         if (ip6->ip6_nxt == IPPROTO_HOPOPTS) {
683                 struct ip6_hbh *hbh;
684
685                 if (ip6_hopopts_input(&plen, &rtalert, &m, &off)) {
686 #if 0   /*touches NULL pointer*/
687                         in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);
688 #endif
689                         return; /* m have already been freed */
690                 }
691
692                 /* adjust pointer */
693                 ip6 = mtod(m, struct ip6_hdr *);
694
695                 /*
696                  * if the payload length field is 0 and the next header field  
697                  * indicates Hop-by-Hop Options header, then a Jumbo Payload
698                  * option MUST be included.
699                  */
700                 if (ip6->ip6_plen == 0 && plen == 0) {
701                         /*
702                          * Note that if a valid jumbo payload option is
703                          * contained, ip6_hoptops_input() must set a valid
704                          * (non-zero) payload length to the variable plen. 
705                          */
706                         ip6stat.ip6s_badoptions++;
707                         in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);
708                         in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr);
709                         icmp6_error(m, ICMP6_PARAM_PROB,
710                                     ICMP6_PARAMPROB_HEADER,
711                                     (caddr_t)&ip6->ip6_plen - (caddr_t)ip6);
712                         return;
713                 }
714 #ifndef PULLDOWN_TEST
715                 /* ip6_hopopts_input() ensures that mbuf is contiguous */
716                 hbh = (struct ip6_hbh *)(ip6 + 1);
717 #else
718                 IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr),
719                         sizeof(struct ip6_hbh));
720                 if (hbh == NULL) {
721                         ip6stat.ip6s_tooshort++;
722                         return;
723                 }
724 #endif
725                 nxt = hbh->ip6h_nxt;
726
727                 /*
728                  * accept the packet if a router alert option is included
729                  * and we act as an IPv6 router.
730                  */
731                 if (rtalert != ~0 && ip6_forwarding)
732                         ours = 1;
733         } else
734                 nxt = ip6->ip6_nxt;
735
736         /*
737          * Check that the amount of data in the buffers
738          * is as at least much as the IPv6 header would have us expect.
739          * Trim mbufs if longer than we expect.
740          * Drop packet if shorter than we expect.
741          */
742         if (m->m_pkthdr.len - sizeof(struct ip6_hdr) < plen) {
743                 ip6stat.ip6s_tooshort++;
744                 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated);
745                 goto bad;
746         }
747         if (m->m_pkthdr.len > sizeof(struct ip6_hdr) + plen) {
748                 if (m->m_len == m->m_pkthdr.len) {
749                         m->m_len = sizeof(struct ip6_hdr) + plen;
750                         m->m_pkthdr.len = sizeof(struct ip6_hdr) + plen;
751                 } else
752                         m_adj(m, sizeof(struct ip6_hdr) + plen - m->m_pkthdr.len);
753         }
754
755         /*
756          * Forward if desirable.
757          */
758         if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
759                 /*
760                  * If we are acting as a multicast router, all
761                  * incoming multicast packets are passed to the
762                  * kernel-level multicast forwarding function.
763                  * The packet is returned (relatively) intact; if
764                  * ip6_mforward() returns a non-zero value, the packet
765                  * must be discarded, else it may be accepted below.
766                  */
767                 if (ip6_mrouter && ip6_mforward(ip6, m->m_pkthdr.rcvif, m)) {
768                         ip6stat.ip6s_cantforward++;
769                         m_freem(m);
770                         return;
771                 }
772                 if (!ours) {
773                         m_freem(m);
774                         return;
775                 }
776         } else if (!ours) {
777                 ip6_forward(m, 0);
778                 return;
779         }       
780
781         ip6 = mtod(m, struct ip6_hdr *);
782
783         /*
784          * Malicious party may be able to use IPv4 mapped addr to confuse
785          * tcp/udp stack and bypass security checks (act as if it was from
786          * 127.0.0.1 by using IPv6 src ::ffff:127.0.0.1).  Be cautious.
787          *
788          * For SIIT end node behavior, you may want to disable the check.
789          * However, you will  become vulnerable to attacks using IPv4 mapped
790          * source.
791          */
792         if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) ||
793             IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) {
794                 ip6stat.ip6s_badscope++;
795                 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr);
796                 goto bad;
797         }
798
799         /*
800          * Tell launch routine the next header
801          */
802         ip6stat.ip6s_delivered++;
803         in6_ifstat_inc(deliverifp, ifs6_in_deliver);
804         nest = 0;
805
806         while (nxt != IPPROTO_DONE) {
807                 if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) {
808                         ip6stat.ip6s_toomanyhdr++;
809                         goto bad;
810                 }
811
812                 /*
813                  * protection against faulty packet - there should be
814                  * more sanity checks in header chain processing.
815                  */
816                 if (m->m_pkthdr.len < off) {
817                         ip6stat.ip6s_tooshort++;
818                         in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated);
819                         goto bad;
820                 }
821
822 #if 0
823                 /*
824                  * do we need to do it for every header?  yeah, other
825                  * functions can play with it (like re-allocate and copy).
826                  */
827                 mhist = ip6_addaux(m);
828                 if (mhist && M_TRAILINGSPACE(mhist) >= sizeof(nxt)) {
829                         hist = mtod(mhist, caddr_t) + mhist->m_len;
830                         bcopy(&nxt, hist, sizeof(nxt));
831                         mhist->m_len += sizeof(nxt);
832                 } else {
833                         ip6stat.ip6s_toomanyhdr++;
834                         goto bad;
835                 }
836 #endif
837
838 #ifdef IPSEC
839                 /*
840                  * enforce IPsec policy checking if we are seeing last header.
841                  * note that we do not visit this with protocols with pcb layer
842                  * code - like udp/tcp/raw ip.
843                  */
844                 if ((inet6sw[ip6_protox[nxt]].pr_flags & PR_LASTHDR) != 0 &&
845                     ipsec6_in_reject(m, NULL)) {
846                         ipsec6stat.in_polvio++;
847                         goto bad;
848                 }
849 #endif
850
851                 nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt);
852         }
853         return;
854  bad:
855         m_freem(m);
856 }
857
858 /*
859  * set/grab in6_ifaddr correspond to IPv6 destination address.
860  * XXX backward compatibility wrapper
861  */
862 static struct mbuf *
863 ip6_setdstifaddr(m, ia6)
864         struct mbuf *m;
865         struct in6_ifaddr *ia6;
866 {
867         struct mbuf *n;
868
869         n = ip6_addaux(m);
870         if (n)
871                 mtod(n, struct ip6aux *)->ip6a_dstia6 = ia6;
872         return n;       /* NULL if failed to set */
873 }
874
875 struct in6_ifaddr *
876 ip6_getdstifaddr(m)
877         struct mbuf *m;
878 {
879         struct mbuf *n;
880
881         n = ip6_findaux(m);
882         if (n)
883                 return mtod(n, struct ip6aux *)->ip6a_dstia6;
884         else
885                 return NULL;
886 }
887
888 /*
889  * Hop-by-Hop options header processing. If a valid jumbo payload option is
890  * included, the real payload length will be stored in plenp.
891  */
892 static int
893 ip6_hopopts_input(plenp, rtalertp, mp, offp)
894         u_int32_t *plenp;
895         u_int32_t *rtalertp;    /* XXX: should be stored more smart way */
896         struct mbuf **mp;
897         int *offp;
898 {
899         struct mbuf *m = *mp;
900         int off = *offp, hbhlen;
901         struct ip6_hbh *hbh;
902         u_int8_t *opt;
903
904         /* validation of the length of the header */
905 #ifndef PULLDOWN_TEST
906         IP6_EXTHDR_CHECK(m, off, sizeof(*hbh), -1);
907         hbh = (struct ip6_hbh *)(mtod(m, caddr_t) + off);
908         hbhlen = (hbh->ip6h_len + 1) << 3;
909
910         IP6_EXTHDR_CHECK(m, off, hbhlen, -1);
911         hbh = (struct ip6_hbh *)(mtod(m, caddr_t) + off);
912 #else
913         IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m,
914                 sizeof(struct ip6_hdr), sizeof(struct ip6_hbh));
915         if (hbh == NULL) {
916                 ip6stat.ip6s_tooshort++;
917                 return -1;
918         }
919         hbhlen = (hbh->ip6h_len + 1) << 3;
920         IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr),
921                 hbhlen);
922         if (hbh == NULL) {
923                 ip6stat.ip6s_tooshort++;
924                 return -1;
925         }
926 #endif
927         off += hbhlen;
928         hbhlen -= sizeof(struct ip6_hbh);
929         opt = (u_int8_t *)hbh + sizeof(struct ip6_hbh);
930
931         if (ip6_process_hopopts(m, (u_int8_t *)hbh + sizeof(struct ip6_hbh),
932                                 hbhlen, rtalertp, plenp) < 0)
933                 return(-1);
934
935         *offp = off;
936         *mp = m;
937         return(0);
938 }
939
940 /*
941  * Search header for all Hop-by-hop options and process each option.
942  * This function is separate from ip6_hopopts_input() in order to
943  * handle a case where the sending node itself process its hop-by-hop
944  * options header. In such a case, the function is called from ip6_output().
945  *
946  * The function assumes that hbh header is located right after the IPv6 header
947  * (RFC2460 p7), opthead is pointer into data content in m, and opthead to
948  * opthead + hbhlen is located in continuous memory region.
949  */
950 int
951 ip6_process_hopopts(m, opthead, hbhlen, rtalertp, plenp)
952         struct mbuf *m;
953         u_int8_t *opthead;
954         int hbhlen;
955         u_int32_t *rtalertp;
956         u_int32_t *plenp;
957 {
958         struct ip6_hdr *ip6;
959         int optlen = 0;
960         u_int8_t *opt = opthead;
961         u_int16_t rtalert_val;
962         u_int32_t jumboplen;
963         const int erroff = sizeof(struct ip6_hdr) + sizeof(struct ip6_hbh);
964
965         for (; hbhlen > 0; hbhlen -= optlen, opt += optlen) {
966                 switch (*opt) {
967                 case IP6OPT_PAD1:
968                         optlen = 1;
969                         break;
970                 case IP6OPT_PADN:
971                         if (hbhlen < IP6OPT_MINLEN) {
972                                 ip6stat.ip6s_toosmall++;
973                                 goto bad;
974                         }
975                         optlen = *(opt + 1) + 2;
976                         break;
977                 case IP6OPT_RTALERT:
978                         /* XXX may need check for alignment */
979                         if (hbhlen < IP6OPT_RTALERT_LEN) {
980                                 ip6stat.ip6s_toosmall++;
981                                 goto bad;
982                         }
983                         if (*(opt + 1) != IP6OPT_RTALERT_LEN - 2) {
984                                 /* XXX stat */
985                                 icmp6_error(m, ICMP6_PARAM_PROB,
986                                             ICMP6_PARAMPROB_HEADER,
987                                             erroff + opt + 1 - opthead);
988                                 return(-1);
989                         }
990                         optlen = IP6OPT_RTALERT_LEN;
991                         bcopy((caddr_t)(opt + 2), (caddr_t)&rtalert_val, 2);
992                         *rtalertp = ntohs(rtalert_val);
993                         break;
994                 case IP6OPT_JUMBO:
995                         /* XXX may need check for alignment */
996                         if (hbhlen < IP6OPT_JUMBO_LEN) {
997                                 ip6stat.ip6s_toosmall++;
998                                 goto bad;
999                         }
1000                         if (*(opt + 1) != IP6OPT_JUMBO_LEN - 2) {
1001                                 /* XXX stat */
1002                                 icmp6_error(m, ICMP6_PARAM_PROB,
1003                                             ICMP6_PARAMPROB_HEADER,
1004                                             erroff + opt + 1 - opthead);
1005                                 return(-1);
1006                         }
1007                         optlen = IP6OPT_JUMBO_LEN;
1008
1009                         /*
1010                          * IPv6 packets that have non 0 payload length
1011                          * must not contain a jumbo payload option.
1012                          */
1013                         ip6 = mtod(m, struct ip6_hdr *);
1014                         if (ip6->ip6_plen) {
1015                                 ip6stat.ip6s_badoptions++;
1016                                 icmp6_error(m, ICMP6_PARAM_PROB,
1017                                             ICMP6_PARAMPROB_HEADER,
1018                                             erroff + opt - opthead);
1019                                 return(-1);
1020                         }
1021
1022                         /*
1023                          * We may see jumbolen in unaligned location, so
1024                          * we'd need to perform bcopy().
1025                          */
1026                         bcopy(opt + 2, &jumboplen, sizeof(jumboplen));
1027                         jumboplen = (u_int32_t)htonl(jumboplen);
1028
1029 #if 1
1030                         /*
1031                          * if there are multiple jumbo payload options,
1032                          * *plenp will be non-zero and the packet will be
1033                          * rejected.
1034                          * the behavior may need some debate in ipngwg -
1035                          * multiple options does not make sense, however,
1036                          * there's no explicit mention in specification.
1037                          */
1038                         if (*plenp != 0) {
1039                                 ip6stat.ip6s_badoptions++;
1040                                 icmp6_error(m, ICMP6_PARAM_PROB,
1041                                             ICMP6_PARAMPROB_HEADER,
1042                                             erroff + opt + 2 - opthead);
1043                                 return(-1);
1044                         }
1045 #endif
1046
1047                         /*
1048                          * jumbo payload length must be larger than 65535.
1049                          */
1050                         if (jumboplen <= IPV6_MAXPACKET) {
1051                                 ip6stat.ip6s_badoptions++;
1052                                 icmp6_error(m, ICMP6_PARAM_PROB,
1053                                             ICMP6_PARAMPROB_HEADER,
1054                                             erroff + opt + 2 - opthead);
1055                                 return(-1);
1056                         }
1057                         *plenp = jumboplen;
1058
1059                         break;
1060                 default:                /* unknown option */
1061                         if (hbhlen < IP6OPT_MINLEN) {
1062                                 ip6stat.ip6s_toosmall++;
1063                                 goto bad;
1064                         }
1065                         optlen = ip6_unknown_opt(opt, m,
1066                             erroff + opt - opthead);
1067                         if (optlen == -1)
1068                                 return(-1);
1069                         optlen += 2;
1070                         break;
1071                 }
1072         }
1073
1074         return(0);
1075
1076   bad:
1077         m_freem(m);
1078         return(-1);
1079 }
1080
1081 /*
1082  * Unknown option processing.
1083  * The third argument `off' is the offset from the IPv6 header to the option,
1084  * which is necessary if the IPv6 header the and option header and IPv6 header
1085  * is not continuous in order to return an ICMPv6 error.
1086  */
1087 int
1088 ip6_unknown_opt(optp, m, off)
1089         u_int8_t *optp;
1090         struct mbuf *m;
1091         int off;
1092 {
1093         struct ip6_hdr *ip6;
1094
1095         switch (IP6OPT_TYPE(*optp)) {
1096         case IP6OPT_TYPE_SKIP: /* ignore the option */
1097                 return((int)*(optp + 1));
1098         case IP6OPT_TYPE_DISCARD:       /* silently discard */
1099                 m_freem(m);
1100                 return(-1);
1101         case IP6OPT_TYPE_FORCEICMP: /* send ICMP even if multicasted */
1102                 ip6stat.ip6s_badoptions++;
1103                 icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION, off);
1104                 return(-1);
1105         case IP6OPT_TYPE_ICMP: /* send ICMP if not multicasted */
1106                 ip6stat.ip6s_badoptions++;
1107                 ip6 = mtod(m, struct ip6_hdr *);
1108                 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) ||
1109                     (m->m_flags & (M_BCAST|M_MCAST)))
1110                         m_freem(m);
1111                 else
1112                         icmp6_error(m, ICMP6_PARAM_PROB,
1113                                     ICMP6_PARAMPROB_OPTION, off);
1114                 return(-1);
1115         }
1116
1117         m_freem(m);             /* XXX: NOTREACHED */
1118         return(-1);
1119 }
1120
1121 /*
1122  * Create the "control" list for this pcb.
1123  * The function will not modify mbuf chain at all.
1124  *
1125  * with KAME mbuf chain restriction:
1126  * The routine will be called from upper layer handlers like tcp6_input().
1127  * Thus the routine assumes that the caller (tcp6_input) have already
1128  * called IP6_EXTHDR_CHECK() and all the extension headers are located in the
1129  * very first mbuf on the mbuf chain.
1130  */
1131 void
1132 ip6_savecontrol(in6p, mp, ip6, m)
1133         struct inpcb *in6p;
1134         struct mbuf **mp;
1135         struct ip6_hdr *ip6;
1136         struct mbuf *m;
1137 {
1138         struct proc *p = curproc;       /* XXX */
1139         int privileged = 0;
1140         int rthdr_exist = 0;
1141
1142
1143         if (p && !suser(p))
1144                 privileged++;
1145
1146 #ifdef SO_TIMESTAMP
1147         if ((in6p->in6p_socket->so_options & SO_TIMESTAMP) != 0) {
1148                 struct timeval tv;
1149
1150                 microtime(&tv);
1151                 *mp = sbcreatecontrol((caddr_t) &tv, sizeof(tv),
1152                                       SCM_TIMESTAMP, SOL_SOCKET);
1153                 if (*mp) {
1154                         mp = &(*mp)->m_next;
1155                 }
1156         }
1157 #endif
1158
1159         /* RFC 2292 sec. 5 */
1160         if ((in6p->in6p_flags & IN6P_PKTINFO) != 0) {
1161                 struct in6_pktinfo pi6;
1162                 bcopy(&ip6->ip6_dst, &pi6.ipi6_addr, sizeof(struct in6_addr));
1163                 if (IN6_IS_SCOPE_LINKLOCAL(&pi6.ipi6_addr))
1164                         pi6.ipi6_addr.s6_addr16[1] = 0;
1165                 pi6.ipi6_ifindex = (m && m->m_pkthdr.rcvif)
1166                                         ? m->m_pkthdr.rcvif->if_index
1167                                         : 0;
1168                 *mp = sbcreatecontrol((caddr_t) &pi6,
1169                         sizeof(struct in6_pktinfo), IPV6_PKTINFO,
1170                         IPPROTO_IPV6);
1171                 if (*mp)
1172                         mp = &(*mp)->m_next;
1173         }
1174
1175         if ((in6p->in6p_flags & IN6P_HOPLIMIT) != 0) {
1176                 int hlim = ip6->ip6_hlim & 0xff;
1177                 *mp = sbcreatecontrol((caddr_t) &hlim,
1178                         sizeof(int), IPV6_HOPLIMIT, IPPROTO_IPV6);
1179                 if (*mp)
1180                         mp = &(*mp)->m_next;
1181         }
1182
1183         /*
1184          * IPV6_HOPOPTS socket option. We require super-user privilege
1185          * for the option, but it might be too strict, since there might
1186          * be some hop-by-hop options which can be returned to normal user.
1187          * See RFC 2292 section 6.
1188          */
1189         if ((in6p->in6p_flags & IN6P_HOPOPTS) != 0 && privileged) {
1190                 /*
1191                  * Check if a hop-by-hop options header is contatined in the
1192                  * received packet, and if so, store the options as ancillary
1193                  * data. Note that a hop-by-hop options header must be
1194                  * just after the IPv6 header, which fact is assured through
1195                  * the IPv6 input processing.
1196                  */
1197                 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
1198                 if (ip6->ip6_nxt == IPPROTO_HOPOPTS) {
1199                         struct ip6_hbh *hbh;
1200                         int hbhlen = 0;
1201 #ifdef PULLDOWN_TEST
1202                         struct mbuf *ext;
1203 #endif
1204
1205 #ifndef PULLDOWN_TEST
1206                         hbh = (struct ip6_hbh *)(ip6 + 1);
1207                         hbhlen = (hbh->ip6h_len + 1) << 3;
1208 #else
1209                         ext = ip6_pullexthdr(m, sizeof(struct ip6_hdr),
1210                             ip6->ip6_nxt);
1211                         if (ext == NULL) {
1212                                 ip6stat.ip6s_tooshort++;
1213                                 return;
1214                         }
1215                         hbh = mtod(ext, struct ip6_hbh *);
1216                         hbhlen = (hbh->ip6h_len + 1) << 3;
1217                         if (hbhlen != ext->m_len) {
1218                                 m_freem(ext);
1219                                 ip6stat.ip6s_tooshort++;
1220                                 return;
1221                         }
1222 #endif
1223
1224                         /*
1225                          * XXX: We copy whole the header even if a jumbo
1226                          * payload option is included, which option is to
1227                          * be removed before returning in the RFC 2292.
1228                          * Note: this constraint is removed in 2292bis.
1229                          */
1230                         *mp = sbcreatecontrol((caddr_t)hbh, hbhlen,
1231                                               IPV6_HOPOPTS, IPPROTO_IPV6);
1232                         if (*mp)
1233                                 mp = &(*mp)->m_next;
1234 #ifdef PULLDOWN_TEST
1235                         m_freem(ext);
1236 #endif
1237                 }
1238         }
1239
1240         /* IPV6_DSTOPTS and IPV6_RTHDR socket options */
1241         if ((in6p->in6p_flags & (IN6P_DSTOPTS | IN6P_RTHDRDSTOPTS)) != 0) {
1242                 int proto, off, nxt;
1243
1244                 /*
1245                  * go through the header chain to see if a routing header is
1246                  * contained in the packet. We need this information to store
1247                  * destination options headers (if any) properly.
1248                  * XXX: performance issue. We should record this info when
1249                  * processing extension headers in incoming routine.
1250                  * (todo) use m_aux? 
1251                  */
1252                 proto = IPPROTO_IPV6;
1253                 off = 0;
1254                 nxt = -1;
1255                 while (1) {
1256                         int newoff;
1257
1258                         newoff = ip6_nexthdr(m, off, proto, &nxt);
1259                         if (newoff < 0)
1260                                 break;
1261                         if (newoff < off) /* invalid, check for safety */
1262                                 break;
1263                         if ((proto = nxt) == IPPROTO_ROUTING) {
1264                                 rthdr_exist = 1;
1265                                 break;
1266                         }
1267                         off = newoff;
1268                 }
1269         }
1270
1271         if ((in6p->in6p_flags &
1272              (IN6P_RTHDR | IN6P_DSTOPTS | IN6P_RTHDRDSTOPTS)) != 0) {
1273                 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
1274                 int nxt = ip6->ip6_nxt, off = sizeof(struct ip6_hdr);
1275
1276                 /*
1277                  * Search for destination options headers or routing
1278                  * header(s) through the header chain, and stores each
1279                  * header as ancillary data.
1280                  * Note that the order of the headers remains in
1281                  * the chain of ancillary data.
1282                  */
1283                 while (1) {     /* is explicit loop prevention necessary? */
1284                         struct ip6_ext *ip6e = NULL;
1285                         int elen;
1286 #ifdef PULLDOWN_TEST
1287                         struct mbuf *ext = NULL;
1288 #endif
1289
1290                         /*
1291                          * if it is not an extension header, don't try to
1292                          * pull it from the chain.
1293                          */
1294                         switch (nxt) {
1295                         case IPPROTO_DSTOPTS:
1296                         case IPPROTO_ROUTING:
1297                         case IPPROTO_HOPOPTS:
1298                         case IPPROTO_AH: /* is it possible? */
1299                                 break;
1300                         default:
1301                                 goto loopend;
1302                         }
1303
1304 #ifndef PULLDOWN_TEST
1305                         if (off + sizeof(*ip6e) > m->m_len)
1306                                 goto loopend;
1307                         ip6e = (struct ip6_ext *)(mtod(m, caddr_t) + off);
1308                         if (nxt == IPPROTO_AH)
1309                                 elen = (ip6e->ip6e_len + 2) << 2;
1310                         else
1311                                 elen = (ip6e->ip6e_len + 1) << 3;
1312                         if (off + elen > m->m_len)
1313                                 goto loopend;
1314 #else
1315                         ext = ip6_pullexthdr(m, off, nxt);
1316                         if (ext == NULL) {
1317                                 ip6stat.ip6s_tooshort++;
1318                                 return;
1319                         }
1320                         ip6e = mtod(ext, struct ip6_ext *);
1321                         if (nxt == IPPROTO_AH)
1322                                 elen = (ip6e->ip6e_len + 2) << 2;
1323                         else
1324                                 elen = (ip6e->ip6e_len + 1) << 3;
1325                         if (elen != ext->m_len) {
1326                                 m_freem(ext);
1327                                 ip6stat.ip6s_tooshort++;
1328                                 return;
1329                         }
1330 #endif
1331
1332                         switch (nxt) {
1333                         case IPPROTO_DSTOPTS:
1334                                 if ((in6p->in6p_flags & IN6P_DSTOPTS) == 0)
1335                                         break;
1336
1337                                 /*
1338                                  * We also require super-user privilege for
1339                                  * the option.
1340                                  * See the comments on IN6_HOPOPTS.
1341                                  */
1342                                 if (!privileged)
1343                                         break;
1344
1345                                 *mp = sbcreatecontrol((caddr_t)ip6e, elen,
1346                                                       IPV6_DSTOPTS,
1347                                                       IPPROTO_IPV6);
1348                                 if (*mp)
1349                                         mp = &(*mp)->m_next;
1350                                 break;
1351                         case IPPROTO_ROUTING:
1352                                 if (!in6p->in6p_flags & IN6P_RTHDR)
1353                                         break;
1354
1355                                 *mp = sbcreatecontrol((caddr_t)ip6e, elen,
1356                                                       IPV6_RTHDR,
1357                                                       IPPROTO_IPV6);
1358                                 if (*mp)
1359                                         mp = &(*mp)->m_next;
1360                                 break;
1361                         case IPPROTO_HOPOPTS:
1362                         case IPPROTO_AH: /* is it possible? */
1363                                 break;
1364
1365                         default:
1366                                 /*
1367                                  * other cases have been filtered in the above.
1368                                  * none will visit this case.  here we supply
1369                                  * the code just in case (nxt overwritten or
1370                                  * other cases).
1371                                  */
1372 #ifdef PULLDOWN_TEST
1373                                 m_freem(ext);
1374 #endif
1375                                 goto loopend;
1376
1377                         }
1378
1379                         /* proceed with the next header. */
1380                         off += elen;
1381                         nxt = ip6e->ip6e_nxt;
1382                         ip6e = NULL;
1383 #ifdef PULLDOWN_TEST
1384                         m_freem(ext);
1385                         ext = NULL;
1386 #endif
1387                 }
1388           loopend:
1389                 ;
1390         }
1391
1392 }
1393
1394 #ifdef PULLDOWN_TEST
1395 /*
1396  * pull single extension header from mbuf chain.  returns single mbuf that
1397  * contains the result, or NULL on error.
1398  */
1399 static struct mbuf *
1400 ip6_pullexthdr(m, off, nxt)
1401         struct mbuf *m;
1402         size_t off;
1403         int nxt;
1404 {
1405         struct ip6_ext ip6e;
1406         size_t elen;
1407         struct mbuf *n;
1408
1409 #ifdef DIAGNOSTIC
1410         switch (nxt) {
1411         case IPPROTO_DSTOPTS:
1412         case IPPROTO_ROUTING:
1413         case IPPROTO_HOPOPTS:
1414         case IPPROTO_AH: /* is it possible? */
1415                 break;
1416         default:
1417                 printf("ip6_pullexthdr: invalid nxt=%d\n", nxt);
1418         }
1419 #endif
1420
1421         m_copydata(m, off, sizeof(ip6e), (caddr_t)&ip6e);
1422         if (nxt == IPPROTO_AH)
1423                 elen = (ip6e.ip6e_len + 2) << 2;
1424         else
1425                 elen = (ip6e.ip6e_len + 1) << 3;
1426
1427         MGET(n, M_DONTWAIT, MT_DATA);
1428         if (n && elen >= MLEN) {
1429                 MCLGET(n, M_DONTWAIT);
1430                 if ((n->m_flags & M_EXT) == 0) {
1431                         m_free(n);
1432                         n = NULL;
1433                 }
1434         }
1435         if (!n)
1436                 return NULL;
1437
1438         n->m_len = 0;
1439         if (elen >= M_TRAILINGSPACE(n)) {
1440                 m_free(n);
1441                 return NULL;
1442         }
1443
1444         m_copydata(m, off, elen, mtod(n, caddr_t));
1445         n->m_len = elen;
1446         return n;
1447 }
1448 #endif
1449
1450 /*
1451  * Get pointer to the previous header followed by the header
1452  * currently processed.
1453  * XXX: This function supposes that
1454  *      M includes all headers,
1455  *      the next header field and the header length field of each header
1456  *      are valid, and
1457  *      the sum of each header length equals to OFF.
1458  * Because of these assumptions, this function must be called very
1459  * carefully. Moreover, it will not be used in the near future when
1460  * we develop `neater' mechanism to process extension headers.
1461  */
1462 char *
1463 ip6_get_prevhdr(m, off)
1464         struct mbuf *m;
1465         int off;
1466 {
1467         struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
1468
1469         if (off == sizeof(struct ip6_hdr))
1470                 return(&ip6->ip6_nxt);
1471         else {
1472                 int len, nxt;
1473                 struct ip6_ext *ip6e = NULL;
1474
1475                 nxt = ip6->ip6_nxt;
1476                 len = sizeof(struct ip6_hdr);
1477                 while (len < off) {
1478                         ip6e = (struct ip6_ext *)(mtod(m, caddr_t) + len);
1479
1480                         switch (nxt) {
1481                         case IPPROTO_FRAGMENT:
1482                                 len += sizeof(struct ip6_frag);
1483                                 break;
1484                         case IPPROTO_AH:
1485                                 len += (ip6e->ip6e_len + 2) << 2;
1486                                 break;
1487                         default:
1488                                 len += (ip6e->ip6e_len + 1) << 3;
1489                                 break;
1490                         }
1491                         nxt = ip6e->ip6e_nxt;
1492                 }
1493                 if (ip6e)
1494                         return(&ip6e->ip6e_nxt);
1495                 else
1496                         return NULL;
1497         }
1498 }
1499
1500 /*
1501  * get next header offset.  m will be retained.
1502  */
1503 int
1504 ip6_nexthdr(m, off, proto, nxtp)
1505         struct mbuf *m;
1506         int off;
1507         int proto;
1508         int *nxtp;
1509 {
1510         struct ip6_hdr ip6;
1511         struct ip6_ext ip6e;
1512         struct ip6_frag fh;
1513
1514         /* just in case */
1515         if (m == NULL)
1516                 panic("ip6_nexthdr: m == NULL");
1517         if ((m->m_flags & M_PKTHDR) == 0 || m->m_pkthdr.len < off)
1518                 return -1;
1519
1520         switch (proto) {
1521         case IPPROTO_IPV6:
1522                 if (m->m_pkthdr.len < off + sizeof(ip6))
1523                         return -1;
1524                 m_copydata(m, off, sizeof(ip6), (caddr_t)&ip6);
1525                 if (nxtp)
1526                         *nxtp = ip6.ip6_nxt;
1527                 off += sizeof(ip6);
1528                 return off;
1529
1530         case IPPROTO_FRAGMENT:
1531                 /*
1532                  * terminate parsing if it is not the first fragment,
1533                  * it does not make sense to parse through it.
1534                  */
1535                 if (m->m_pkthdr.len < off + sizeof(fh))
1536                         return -1;
1537                 m_copydata(m, off, sizeof(fh), (caddr_t)&fh);
1538                 if ((ntohs(fh.ip6f_offlg) & IP6F_OFF_MASK) != 0)
1539                         return -1;
1540                 if (nxtp)
1541                         *nxtp = fh.ip6f_nxt;
1542                 off += sizeof(struct ip6_frag);
1543                 return off;
1544
1545         case IPPROTO_AH:
1546                 if (m->m_pkthdr.len < off + sizeof(ip6e))
1547                         return -1;
1548                 m_copydata(m, off, sizeof(ip6e), (caddr_t)&ip6e);
1549                 if (nxtp)
1550                         *nxtp = ip6e.ip6e_nxt;
1551                 off += (ip6e.ip6e_len + 2) << 2;
1552                 return off;
1553
1554         case IPPROTO_HOPOPTS:
1555         case IPPROTO_ROUTING:
1556         case IPPROTO_DSTOPTS:
1557                 if (m->m_pkthdr.len < off + sizeof(ip6e))
1558                         return -1;
1559                 m_copydata(m, off, sizeof(ip6e), (caddr_t)&ip6e);
1560                 if (nxtp)
1561                         *nxtp = ip6e.ip6e_nxt;
1562                 off += (ip6e.ip6e_len + 1) << 3;
1563                 return off;
1564
1565         case IPPROTO_NONE:
1566         case IPPROTO_ESP:
1567         case IPPROTO_IPCOMP:
1568                 /* give up */
1569                 return -1;
1570
1571         default:
1572                 return -1;
1573         }
1574
1575         return -1;
1576 }
1577
1578 /*
1579  * get offset for the last header in the chain.  m will be kept untainted.
1580  */
1581 int
1582 ip6_lasthdr(m, off, proto, nxtp)
1583         struct mbuf *m;
1584         int off;
1585         int proto;
1586         int *nxtp;
1587 {
1588         int newoff;
1589         int nxt;
1590
1591         if (!nxtp) {
1592                 nxt = -1;
1593                 nxtp = &nxt;
1594         }
1595         while (1) {
1596                 newoff = ip6_nexthdr(m, off, proto, nxtp);
1597                 if (newoff < 0)
1598                         return off;
1599                 else if (newoff < off)
1600                         return -1;      /* invalid */
1601                 else if (newoff == off)
1602                         return newoff;
1603
1604                 off = newoff;
1605                 proto = *nxtp;
1606         }
1607 }
1608
1609 struct mbuf *
1610 ip6_addaux(m)
1611         struct mbuf *m;
1612 {
1613         struct mbuf *n;
1614
1615 #ifdef DIAGNOSTIC
1616         if (sizeof(struct ip6aux) > MHLEN)
1617                 panic("assumption failed on sizeof(ip6aux)");
1618 #endif
1619         n = m_aux_find(m, AF_INET6, -1);
1620         if (n) {
1621                 if (n->m_len < sizeof(struct ip6aux)) {
1622                         printf("conflicting use of ip6aux");
1623                         return NULL;
1624                 }
1625         } else {
1626                 n = m_aux_add(m, AF_INET6, -1);
1627                 n->m_len = sizeof(struct ip6aux);
1628                 bzero(mtod(n, caddr_t), n->m_len);
1629         }
1630         return n;
1631 }
1632
1633 struct mbuf *
1634 ip6_findaux(m)
1635         struct mbuf *m;
1636 {
1637         struct mbuf *n;
1638
1639         n = m_aux_find(m, AF_INET6, -1);
1640         if (n && n->m_len < sizeof(struct ip6aux)) {
1641                 printf("conflicting use of ip6aux");
1642                 n = NULL;
1643         }
1644         return n;
1645 }
1646
1647 void
1648 ip6_delaux(m)
1649         struct mbuf *m;
1650 {
1651         struct mbuf *n;
1652
1653         n = m_aux_find(m, AF_INET6, -1);
1654         if (n)
1655                 m_aux_delete(m, n);
1656 }
1657
1658 /*
1659  * System control for IP6
1660  */
1661
1662 u_char  inet6ctlerrmap[PRC_NCMDS] = {
1663         0,              0,              0,              0,
1664         0,              EMSGSIZE,       EHOSTDOWN,      EHOSTUNREACH,
1665         EHOSTUNREACH,   EHOSTUNREACH,   ECONNREFUSED,   ECONNREFUSED,
1666         EMSGSIZE,       EHOSTUNREACH,   0,              0,
1667         0,              0,              0,              0,
1668         ENOPROTOOPT
1669 };