BSD 4_3_Net_2 release
[unix-history] / usr / src / sys / net / if_ethersubr.c
index 469f106..69e8554 100644 (file)
@@ -2,26 +2,40 @@
  * Copyright (c) 1982, 1989 Regents of the University of California.
  * All rights reserved.
  *
  * Copyright (c) 1982, 1989 Regents of the University of California.
  * All rights reserved.
  *
- * Redistribution is only permitted until one year after the first shipment
- * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
- * binary forms are permitted provided that: (1) source distributions retain
- * this entire copyright notice and comment, and (2) distributions including
- * binaries display the following acknowledgement:  This product includes
- * software developed by the University of California, Berkeley and its
- * contributors'' in the documentation or other materials provided with the
- * distribution and in all advertising materials mentioning features or use
- * of this software.  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 AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * 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.
  *
  *
- *     @(#)if_ethersubr.c      7.10 (Berkeley) 6/28/90
+ * 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.
+ *
+ *     @(#)if_ethersubr.c      7.13 (Berkeley) 4/20/91
  */
 
 #include "param.h"
 #include "systm.h"
  */
 
 #include "param.h"
 #include "systm.h"
+#include "kernel.h"
 #include "malloc.h"
 #include "mbuf.h"
 #include "protosw.h"
 #include "malloc.h"
 #include "mbuf.h"
 #include "protosw.h"
@@ -41,8 +55,8 @@
 #ifdef INET
 #include "../netinet/in.h"
 #include "../netinet/in_var.h"
 #ifdef INET
 #include "../netinet/in.h"
 #include "../netinet/in_var.h"
-#include "../netinet/if_ether.h"
 #endif
 #endif
+#include "../netinet/if_ether.h"
 
 #ifdef NS
 #include "../netns/ns.h"
 
 #ifdef NS
 #include "../netns/ns.h"
@@ -80,7 +94,6 @@ ether_output(ifp, m0, dst, rt)
        struct mbuf *mcopy = (struct mbuf *)0;
        register struct ether_header *eh;
        int usetrailers, off, len = m->m_pkthdr.len;
        struct mbuf *mcopy = (struct mbuf *)0;
        register struct ether_header *eh;
        int usetrailers, off, len = m->m_pkthdr.len;
-       extern struct timeval time;
 #define        ac ((struct arpcom *)ifp)
 
        if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) {
 #define        ac ((struct arpcom *)ifp)
 
        if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) {
@@ -118,7 +131,7 @@ ether_output(ifp, m0, dst, rt)
                bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host),
                    (caddr_t)edst, sizeof (edst));
                if (!bcmp((caddr_t)edst, (caddr_t)&ns_thishost, sizeof(edst)))
                bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host),
                    (caddr_t)edst, sizeof (edst));
                if (!bcmp((caddr_t)edst, (caddr_t)&ns_thishost, sizeof(edst)))
-                       return (looutput(&loif, m, dst));
+                       return (looutput(ifp, m, dst, rt));
                if ((ifp->if_flags & IFF_SIMPLEX) && (*edst & 1))
                        mcopy = m_copy(m, 0, (int)M_COPYALL);
                goto gottype;
                if ((ifp->if_flags & IFF_SIMPLEX) && (*edst & 1))
                        mcopy = m_copy(m, 0, (int)M_COPYALL);
                goto gottype;
@@ -129,7 +142,6 @@ ether_output(ifp, m0, dst, rt)
                struct  llc *l;
 
        iso_again:
                struct  llc *l;
 
        iso_again:
-               iso_etherout();
                if (rt && rt->rt_gateway && (rt->rt_flags & RTF_UP)) {
                        if (rt->rt_flags & RTF_GATEWAY) {
                                if (rt->rt_llinfo) {
                if (rt && rt->rt_gateway && (rt->rt_flags & RTF_UP)) {
                        if (rt->rt_flags & RTF_GATEWAY) {
                                if (rt->rt_llinfo) {
@@ -151,6 +163,17 @@ ether_output(ifp, m0, dst, rt)
                                        (char *)edst, &snpalen)) > 0)
                        goto bad; /* Not Resolved */
        iso_resolved:
                                        (char *)edst, &snpalen)) > 0)
                        goto bad; /* Not Resolved */
        iso_resolved:
+               if ((ifp->if_flags & IFF_SIMPLEX) && (*edst & 1) &&
+                   (mcopy = m_copy(m, 0, (int)M_COPYALL))) {
+                       M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT);
+                       if (mcopy) {
+                               eh = mtod(mcopy, struct ether_header *);
+                               bcopy((caddr_t)edst,
+                                     (caddr_t)eh->ether_dhost, sizeof (edst));
+                               bcopy((caddr_t)ac->ac_enaddr,
+                                     (caddr_t)eh->ether_shost, sizeof (edst));
+                       }
+               }
                M_PREPEND(m, 3, M_DONTWAIT);
                if (m == NULL)
                        return (0);
                M_PREPEND(m, 3, M_DONTWAIT);
                if (m == NULL)
                        return (0);
@@ -204,6 +227,8 @@ gottrailertype:
        m0->m_next = 0;
 
 gottype:
        m0->m_next = 0;
 
 gottype:
+       if (mcopy)
+               (void) looutput(ifp, mcopy, dst, rt);
        /*
         * Add local net header.  If no space in first mbuf,
         * allocate another.
        /*
         * Add local net header.  If no space in first mbuf,
         * allocate another.
@@ -220,11 +245,11 @@ gottype:
        bcopy((caddr_t)edst, (caddr_t)eh->ether_dhost, sizeof (edst));
        bcopy((caddr_t)ac->ac_enaddr, (caddr_t)eh->ether_shost,
            sizeof(eh->ether_shost));
        bcopy((caddr_t)edst, (caddr_t)eh->ether_dhost, sizeof (edst));
        bcopy((caddr_t)ac->ac_enaddr, (caddr_t)eh->ether_shost,
            sizeof(eh->ether_shost));
+       s = splimp();
        /*
         * Queue message on interface, and start output if interface
         * not yet active.
         */
        /*
         * Queue message on interface, and start output if interface
         * not yet active.
         */
-       s = splimp();
        if (IF_QFULL(&ifp->if_snd)) {
                IF_DROP(&ifp->if_snd);
                splx(s);
        if (IF_QFULL(&ifp->if_snd)) {
                IF_DROP(&ifp->if_snd);
                splx(s);
@@ -235,16 +260,12 @@ gottype:
        if ((ifp->if_flags & IFF_OACTIVE) == 0)
                (*ifp->if_start)(ifp);
        splx(s);
        if ((ifp->if_flags & IFF_OACTIVE) == 0)
                (*ifp->if_start)(ifp);
        splx(s);
-       if (mcopy)
-               (void) looutput(&loif, mcopy, dst);
        ifp->if_obytes += len + sizeof (struct ether_header);
        if (edst[0] & 1)
                ifp->if_omcasts++;
        return (error);
 
 bad:
        ifp->if_obytes += len + sizeof (struct ether_header);
        if (edst[0] & 1)
                ifp->if_omcasts++;
        return (error);
 
 bad:
-       if (mcopy)
-               m_freem(mcopy);
        if (m)
                m_freem(m);
        return (error);
        if (m)
                m_freem(m);
        return (error);
@@ -303,6 +324,8 @@ ether_input(ifp, eh, m)
                    if ((l->llc_dsap == LLC_ISO_LSAP) &&
                        (l->llc_ssap == LLC_ISO_LSAP)) {
                                /* LSAP for ISO */
                    if ((l->llc_dsap == LLC_ISO_LSAP) &&
                        (l->llc_ssap == LLC_ISO_LSAP)) {
                                /* LSAP for ISO */
+                       if (m->m_pkthdr.len > eh->ether_type)
+                               m_adj(m, eh->ether_type - m->m_pkthdr.len);
                        m->m_data += 3;         /* XXX */
                        m->m_len -= 3;          /* XXX */
                        m->m_pkthdr.len -= 3;   /* XXX */
                        m->m_data += 3;         /* XXX */
                        m->m_len -= 3;          /* XXX */
                        m->m_pkthdr.len -= 3;   /* XXX */
@@ -392,4 +415,3 @@ ether_sprintf(ap)
        *--cp = 0;
        return (etherbuf);
 }
        *--cp = 0;
        return (etherbuf);
 }
-iso_etherout() {}