Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-1-5]: src/sys/netinet6 Pull up revision 1.29 (via patch, requeste...



details:   https://anonhg.NetBSD.org/src/rev/a785846b4f05
branches:  netbsd-1-5
changeset: 490654:a785846b4f05
user:      he <he%NetBSD.org@localhost>
date:      Sun Feb 04 19:22:08 2001 +0000

description:
Pull up revision 1.29 (via patch, requested by itojun):
  Avoid panic when a packet with nonexistent link-local address is
  issued.

diffstat:

 sys/netinet6/ip6_output.c |  2212 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 2212 insertions(+), 0 deletions(-)

diffs (truncated from 2216 to 300 lines):

diff -r 581cb7dc2e87 -r a785846b4f05 sys/netinet6/ip6_output.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/netinet6/ip6_output.c Sun Feb 04 19:22:08 2001 +0000
@@ -0,0 +1,2212 @@
+/*     $NetBSD: ip6_output.c,v 1.23.2.2 2001/02/04 19:22:08 he Exp $   */
+/*     $KAME: ip6_output.c,v 1.109 2000/05/31 05:03:09 jinmei Exp $    */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)ip_output.c 8.3 (Berkeley) 1/21/94
+ */
+
+#include "opt_inet.h"
+#include "opt_ipsec.h"
+#include "opt_pfil_hooks.h"
+
+#include <sys/param.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/errno.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+
+#include <net/if.h>
+#include <net/route.h>
+#ifdef PFIL_HOOKS
+#include <net/pfil.h>
+#endif
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip6.h>
+#include <netinet/icmp6.h>
+#include <netinet6/ip6_var.h>
+#include <netinet6/in6_pcb.h>
+#include <netinet6/nd6.h>
+
+#ifdef IPSEC
+#include <netinet6/ipsec.h>
+#include <netkey/key.h>
+#include <netkey/key_debug.h>
+#endif /* IPSEC */
+
+#include "loop.h"
+
+#include <net/net_osdep.h>
+
+#ifdef IPV6FIREWALL
+#include <netinet6/ip6_fw.h>
+#endif
+
+struct ip6_exthdrs {
+       struct mbuf *ip6e_ip6;
+       struct mbuf *ip6e_hbh;
+       struct mbuf *ip6e_dest1;
+       struct mbuf *ip6e_rthdr;
+       struct mbuf *ip6e_dest2;
+};
+
+static int ip6_pcbopts __P((struct ip6_pktopts **, struct mbuf *,
+                           struct socket *));
+static int ip6_setmoptions __P((int, struct ip6_moptions **, struct mbuf *));
+static int ip6_getmoptions __P((int, struct ip6_moptions *, struct mbuf **));
+static int ip6_copyexthdr __P((struct mbuf **, caddr_t, int));
+static int ip6_insertfraghdr __P((struct mbuf *, struct mbuf *, int,
+                                 struct ip6_frag **));
+static int ip6_insert_jumboopt __P((struct ip6_exthdrs *, u_int32_t));
+static int ip6_splithdr __P((struct mbuf *, struct ip6_exthdrs *));
+
+extern struct ifnet loif[NLOOP];
+
+/*
+ * IP6 output. The packet in mbuf chain m contains a skeletal IP6
+ * header (with pri, len, nxt, hlim, src, dst).
+ * This function may modify ver and hlim only.
+ * The mbuf chain containing the packet will be freed.
+ * The mbuf opt, if present, will not be freed.
+ */
+int
+ip6_output(m0, opt, ro, flags, im6o, ifpp)
+       struct mbuf *m0;
+       struct ip6_pktopts *opt;
+       struct route_in6 *ro;
+       int flags;
+       struct ip6_moptions *im6o;
+       struct ifnet **ifpp;            /* XXX: just for statistics */
+{
+       struct ip6_hdr *ip6, *mhip6;
+       struct ifnet *ifp, *origifp;
+       struct mbuf *m = m0;
+       int hlen, tlen, len, off;
+       struct route_in6 ip6route;
+       struct sockaddr_in6 *dst;
+       int error = 0;
+       struct in6_ifaddr *ia;
+       u_long mtu;
+       u_int32_t optlen = 0, plen = 0, unfragpartlen = 0;
+       struct ip6_exthdrs exthdrs;
+       struct in6_addr finaldst;
+       struct route_in6 *ro_pmtu = NULL;
+       int hdrsplit = 0;
+       int needipsec = 0;
+#ifdef PFIL_HOOKS
+       struct packet_filter_hook *pfh;
+       struct mbuf *m1;
+       int rv;
+#endif /* PFIL_HOOKS */
+#ifdef IPSEC
+       int needipsectun = 0;
+       struct socket *so;
+       struct secpolicy *sp = NULL;
+
+       /* for AH processing. stupid to have "socket" variable in IP layer... */
+       so = ipsec_getsocket(m);
+       ipsec_setsocket(m, NULL);
+       ip6 = mtod(m, struct ip6_hdr *);
+#endif /* IPSEC */
+
+#define MAKE_EXTHDR(hp, mp)                                            \
+    do {                                                               \
+       if (hp) {                                                       \
+               struct ip6_ext *eh = (struct ip6_ext *)(hp);            \
+               error = ip6_copyexthdr((mp), (caddr_t)(hp),             \
+                                      ((eh)->ip6e_len + 1) << 3);      \
+               if (error)                                              \
+                       goto freehdrs;                                  \
+       }                                                               \
+    } while (0)
+       
+       bzero(&exthdrs, sizeof(exthdrs));
+       if (opt) {
+               /* Hop-by-Hop options header */
+               MAKE_EXTHDR(opt->ip6po_hbh, &exthdrs.ip6e_hbh);
+               /* Destination options header(1st part) */
+               MAKE_EXTHDR(opt->ip6po_dest1, &exthdrs.ip6e_dest1);
+               /* Routing header */
+               MAKE_EXTHDR(opt->ip6po_rthdr, &exthdrs.ip6e_rthdr);
+               /* Destination options header(2nd part) */
+               MAKE_EXTHDR(opt->ip6po_dest2, &exthdrs.ip6e_dest2);
+       }
+
+#ifdef IPSEC
+       /* get a security policy for this packet */
+       if (so == NULL)
+               sp = ipsec6_getpolicybyaddr(m, IPSEC_DIR_OUTBOUND, 0, &error);
+       else
+               sp = ipsec6_getpolicybysock(m, IPSEC_DIR_OUTBOUND, so, &error);
+
+       if (sp == NULL) {
+               ipsec6stat.out_inval++;
+               goto freehdrs;
+       }
+
+       error = 0;
+
+       /* check policy */
+       switch (sp->policy) {
+       case IPSEC_POLICY_DISCARD:
+               /*
+                * This packet is just discarded.
+                */
+               ipsec6stat.out_polvio++;
+               goto freehdrs;
+
+       case IPSEC_POLICY_BYPASS:
+       case IPSEC_POLICY_NONE:
+               /* no need to do IPsec. */
+               needipsec = 0;
+               break;
+       
+       case IPSEC_POLICY_IPSEC:
+               if (sp->req == NULL) {
+                       /* XXX should be panic ? */
+                       printf("ip6_output: No IPsec request specified.\n");
+                       error = EINVAL;
+                       goto freehdrs;
+               }
+               needipsec = 1;
+               break;
+
+       case IPSEC_POLICY_ENTRUST:
+       default:
+               printf("ip6_output: Invalid policy found. %d\n", sp->policy);
+       }
+#endif /* IPSEC */
+
+       /*
+        * Calculate the total length of the extension header chain.
+        * Keep the length of the unfragmentable part for fragmentation.
+        */
+       optlen = 0;
+       if (exthdrs.ip6e_hbh) optlen += exthdrs.ip6e_hbh->m_len;
+       if (exthdrs.ip6e_dest1) optlen += exthdrs.ip6e_dest1->m_len;
+       if (exthdrs.ip6e_rthdr) optlen += exthdrs.ip6e_rthdr->m_len;
+       unfragpartlen = optlen + sizeof(struct ip6_hdr);
+       /* NOTE: we don't add AH/ESP length here. do that later. */
+       if (exthdrs.ip6e_dest2) optlen += exthdrs.ip6e_dest2->m_len;
+
+       /*
+        * If we need IPsec, or there is at least one extension header,
+        * separate IP6 header from the payload.
+        */
+       if ((needipsec || optlen) && !hdrsplit) {
+               if ((error = ip6_splithdr(m, &exthdrs)) != 0) {
+                       m = NULL;
+                       goto freehdrs;
+               }
+               m = exthdrs.ip6e_ip6;
+               hdrsplit++;
+       }
+
+       /* adjust pointer */
+       ip6 = mtod(m, struct ip6_hdr *);
+
+       /* adjust mbuf packet header length */
+       m->m_pkthdr.len += optlen;
+       plen = m->m_pkthdr.len - sizeof(*ip6);
+
+       /* If this is a jumbo payload, insert a jumbo payload option. */
+       if (plen > IPV6_MAXPACKET) {
+               if (!hdrsplit) {
+                       if ((error = ip6_splithdr(m, &exthdrs)) != 0) {
+                               m = NULL;
+                               goto freehdrs;
+                       }
+                       m = exthdrs.ip6e_ip6;
+                       hdrsplit++;
+               }
+               /* adjust pointer */
+               ip6 = mtod(m, struct ip6_hdr *);
+               if ((error = ip6_insert_jumboopt(&exthdrs, plen)) != 0)
+                       goto freehdrs;
+               ip6->ip6_plen = 0;
+       } else
+               ip6->ip6_plen = htons(plen);
+
+       /*
+        * Concatenate headers and fill in next header fields.



Home | Main Index | Thread Index | Old Index