one more time
[unix-history] / usr / src / sys / vax / if / if_en.c
index 5f1e7bf..ceff1ec 100644 (file)
@@ -1,4 +1,4 @@
-/*     if_en.c 4.50    82/04/04        */
+/*     if_en.c 4.63    82/05/27        */
 
 #include "en.h"
 #include "imp.h"
 
 #include "en.h"
 #include "imp.h"
 #include "../net/ip_var.h"
 #include "../net/pup.h"
 #include "../net/route.h"
 #include "../net/ip_var.h"
 #include "../net/pup.h"
 #include "../net/route.h"
+#include <errno.h>
 
 #define        ENMTU   (1024+512)
 
 #define        ENMTU   (1024+512)
+#define        ENMRU   (1024+512+16)           /* 16 is enough to receive trailer */
 
 int    enprobe(), enattach(), enrint(), enxint(), encollide();
 struct uba_device *eninfo[NEN];
 
 int    enprobe(), enattach(), enrint(), enxint(), encollide();
 struct uba_device *eninfo[NEN];
@@ -84,6 +86,9 @@ COUNT(ENPROBE);
        addr->en_ostat = EN_IEN|EN_GO;
        DELAY(100000);
        addr->en_ostat = 0;
        addr->en_ostat = EN_IEN|EN_GO;
        DELAY(100000);
        addr->en_ostat = 0;
+#ifdef ECHACK
+       br = 0x16;
+#endif
        return (1);
 }
 
        return (1);
 }
 
@@ -115,11 +120,12 @@ COUNT(ENATTACH);
        es->es_if.if_init = eninit;
        es->es_if.if_output = enoutput;
        es->es_if.if_ubareset = enreset;
        es->es_if.if_init = eninit;
        es->es_if.if_output = enoutput;
        es->es_if.if_ubareset = enreset;
-       es->es_ifuba.ifu_flags = UBA_NEEDBDP | UBA_NEED16;
+       es->es_ifuba.ifu_flags = UBA_NEEDBDP | UBA_NEED16 | UBA_CANTWAIT;
        if_attach(&es->es_if);
 #if NIMP == 0
        /* here's one for you john baby.... */
        if_attach(&es->es_if);
 #if NIMP == 0
        /* here's one for you john baby.... */
-       enlhinit((ui->ui_flags &~ 0xff) | 0x0a);
+       if (ui->ui_flags &~ 0xff)
+               enlhinit(&es->es_if, (ui->ui_flags &~ 0xff) | 0x0a);
 #endif
 }
 
 #endif
 }
 
@@ -153,7 +159,7 @@ eninit(unit)
        int s;
 
        if (if_ubainit(&es->es_ifuba, ui->ui_ubanum,
        int s;
 
        if (if_ubainit(&es->es_ifuba, ui->ui_ubanum,
-           sizeof (struct en_header), (int)btoc(ENMTU)) == 0) { 
+           sizeof (struct en_header), (int)btoc(ENMRU)) == 0) { 
                printf("en%d: can't initialize\n", unit);
                es->es_if.if_flags &= ~IFF_UP;
                return;
                printf("en%d: can't initialize\n", unit);
                es->es_if.if_flags &= ~IFF_UP;
                return;
@@ -167,7 +173,7 @@ eninit(unit)
         */
        s = splimp();
        addr->en_iba = es->es_ifuba.ifu_r.ifrw_info;
         */
        s = splimp();
        addr->en_iba = es->es_ifuba.ifu_r.ifrw_info;
-       addr->en_iwc = -(sizeof (struct en_header) + ENMTU) >> 1;
+       addr->en_iwc = -(sizeof (struct en_header) + ENMRU) >> 1;
        addr->en_istat = EN_IEN|EN_GO;
        es->es_oactive = 1;
        es->es_if.if_flags |= IFF_UP;
        addr->en_istat = EN_IEN|EN_GO;
        es->es_oactive = 1;
        es->es_if.if_flags |= IFF_UP;
@@ -177,7 +183,7 @@ eninit(unit)
 }
 
 int    enalldelay = 0;
 }
 
 int    enalldelay = 0;
-int    enlastdel = 25;
+int    enlastdel = 50;
 int    enlastmask = (~0) << 5;
 
 /*
 int    enlastmask = (~0) << 5;
 
 /*
@@ -369,16 +375,16 @@ COUNT(ENRINT);
        resid = addr->en_iwc;
        if (resid)
                resid |= 0176000;
        resid = addr->en_iwc;
        if (resid)
                resid |= 0176000;
-       len = (((sizeof (struct en_header) + ENMTU) >> 1) + resid) << 1;
+       len = (((sizeof (struct en_header) + ENMRU) >> 1) + resid) << 1;
        len -= sizeof (struct en_header);
        len -= sizeof (struct en_header);
-       if (len >= ENMTU)
+       if (len > ENMRU)
                goto setup;                     /* sanity */
        en = (struct en_header *)(es->es_ifuba.ifu_r.ifrw_addr);
 #define        endataaddr(en, off, type)       ((type)(((caddr_t)((en)+1)+(off))))
        if (en->en_type >= ENPUP_TRAIL &&
            en->en_type < ENPUP_TRAIL+ENPUP_NTRAILER) {
                off = (en->en_type - ENPUP_TRAIL) * 512;
                goto setup;                     /* sanity */
        en = (struct en_header *)(es->es_ifuba.ifu_r.ifrw_addr);
 #define        endataaddr(en, off, type)       ((type)(((caddr_t)((en)+1)+(off))))
        if (en->en_type >= ENPUP_TRAIL &&
            en->en_type < ENPUP_TRAIL+ENPUP_NTRAILER) {
                off = (en->en_type - ENPUP_TRAIL) * 512;
-               if (off >= ENMTU)
+               if (off > ENMTU)
                        goto setup;             /* sanity */
                en->en_type = *endataaddr(en, off, u_short *);
                resid = *(endataaddr(en, off+2, u_short *));
                        goto setup;             /* sanity */
                en->en_type = *endataaddr(en, off, u_short *);
                resid = *(endataaddr(en, off+2, u_short *));
@@ -417,11 +423,14 @@ COUNT(ENRINT);
                pupproto.sp_protocol = pup->pup_type;
                pupdst.spup_addr = pup->pup_dport;
                pupsrc.spup_addr = pup->pup_sport;
                pupproto.sp_protocol = pup->pup_type;
                pupdst.spup_addr = pup->pup_dport;
                pupsrc.spup_addr = pup->pup_sport;
-               raw_input(m, &pupproto, (struct sockaddr *)&pupdst,
-                 (struct sockaddr *)&pupsrc);
+               raw_input(m, &pupproto, (struct sockaddr *)&pupsrc,
+                 (struct sockaddr *)&pupdst);
                goto setup;
        }
 #endif
                goto setup;
        }
 #endif
+       default:
+               m_freem(m);
+               goto setup;
        }
 
        if (IF_QFULL(inq)) {
        }
 
        if (IF_QFULL(inq)) {
@@ -435,7 +444,7 @@ setup:
         * Reset for next packet.
         */
        addr->en_iba = es->es_ifuba.ifu_r.ifrw_info;
         * Reset for next packet.
         */
        addr->en_iba = es->es_ifuba.ifu_r.ifrw_info;
-       addr->en_iwc = -(sizeof (struct en_header) + ENMTU) >> 1;
+       addr->en_iwc = -(sizeof (struct en_header) + ENMRU) >> 1;
        addr->en_istat = EN_IEN|EN_GO;
 }
 
        addr->en_istat = EN_IEN|EN_GO;
 }
 
@@ -450,7 +459,7 @@ enoutput(ifp, m0, dst)
        struct mbuf *m0;
        struct sockaddr *dst;
 {
        struct mbuf *m0;
        struct sockaddr *dst;
 {
-       int type, dest, s;
+       int type, dest, s, error;
        register struct mbuf *m = m0;
        register struct en_header *en;
        register int off;
        register struct mbuf *m = m0;
        register struct en_header *en;
        register int off;
@@ -460,7 +469,12 @@ COUNT(ENOUTPUT);
 
 #ifdef INET
        case AF_INET:
 
 #ifdef INET
        case AF_INET:
-               dest = ((struct sockaddr_in *)dst)->sin_addr.s_addr >> 24;
+               dest = ((struct sockaddr_in *)dst)->sin_addr.s_addr;
+               if (dest & 0x00ffff00) {
+                       error = EPERM;          /* ??? */
+                       goto bad;
+               }
+               dest = (dest >> 24) & 0xff;
                off = ntohs((u_short)mtod(m, struct ip *)->ip_len) - m->m_len;
                if (off > 0 && (off & 0x1ff) == 0 &&
                    m->m_off >= MMINOFF + 2 * sizeof (u_short)) {
                off = ntohs((u_short)mtod(m, struct ip *)->ip_len) - m->m_len;
                if (off > 0 && (off & 0x1ff) == 0 &&
                    m->m_off >= MMINOFF + 2 * sizeof (u_short)) {
@@ -486,8 +500,8 @@ COUNT(ENOUTPUT);
        default:
                printf("en%d: can't handle af%d\n", ifp->if_unit,
                        dst->sa_family);
        default:
                printf("en%d: can't handle af%d\n", ifp->if_unit,
                        dst->sa_family);
-               m_freem(m0);
-               return (0);
+               error = EAFNOSUPPORT;
+               goto bad;
        }
 
 gottrailertype:
        }
 
 gottrailertype:
@@ -511,8 +525,8 @@ gottype:
            MMINOFF + sizeof (struct en_header) > m->m_off) {
                m = m_get(M_DONTWAIT);
                if (m == 0) {
            MMINOFF + sizeof (struct en_header) > m->m_off) {
                m = m_get(M_DONTWAIT);
                if (m == 0) {
-                       m_freem(m0);
-                       return (0);
+                       error = ENOBUFS;
+                       goto bad;
                }
                m->m_next = m0;
                m->m_off = MMINOFF;
                }
                m->m_next = m0;
                m->m_off = MMINOFF;
@@ -533,15 +547,20 @@ gottype:
        s = splimp();
        if (IF_QFULL(&ifp->if_snd)) {
                IF_DROP(&ifp->if_snd);
        s = splimp();
        if (IF_QFULL(&ifp->if_snd)) {
                IF_DROP(&ifp->if_snd);
-               m_freem(m);
-               splx(s);
-               return (0);
+               error = ENOBUFS;
+               goto qfull;
        }
        IF_ENQUEUE(&ifp->if_snd, m);
        if (en_softc[ifp->if_unit].es_oactive == 0)
                enstart(ifp->if_unit);
        splx(s);
        }
        IF_ENQUEUE(&ifp->if_snd, m);
        if (en_softc[ifp->if_unit].es_oactive == 0)
                enstart(ifp->if_unit);
        splx(s);
-       return (1);
+       return (0);
+qfull:
+       m0 = m;
+       splx(s);
+bad:
+       m_freem(m0);
+       return (error);
 }
 
 #if NIMP == 0 && NEN > 0
 }
 
 #if NIMP == 0 && NEN > 0
@@ -554,19 +573,19 @@ gottype:
  */
 
 struct ifnet enlhif;
  */
 
 struct ifnet enlhif;
-int    enlhoutput();
+int    looutput();
 
 /*
  * Called by localnet interface to allow logical
 
 /*
  * Called by localnet interface to allow logical
- * host interface to "attach".  Nothing should ever
- * be sent locally to this interface, it's purpose
+ * host interface to "attach", it's purpose
  * is simply to establish the host's arpanet address.
  */
  * is simply to establish the host's arpanet address.
  */
-enlhinit(addr)
+enlhinit(esifp, addr)
+       struct ifnet *esifp;
        int addr;
 {
        register struct ifnet *ifp = &enlhif;
        int addr;
 {
        register struct ifnet *ifp = &enlhif;
-       register struct sockaddr_in *sin;
+       struct sockaddr_in *sin;
 
 COUNT(ENLHINIT);
        ifp->if_name = "lh";
 
 COUNT(ENLHINIT);
        ifp->if_name = "lh";
@@ -574,20 +593,12 @@ COUNT(ENLHINIT);
        sin = (struct sockaddr_in *)&ifp->if_addr;
        sin->sin_family = AF_INET;
        sin->sin_addr.s_addr = addr;
        sin = (struct sockaddr_in *)&ifp->if_addr;
        sin->sin_family = AF_INET;
        sin->sin_addr.s_addr = addr;
+       sin->sin_addr.s_lh = esifp->if_host[0];
        ifp->if_net = sin->sin_addr.s_net;
        ifp->if_net = sin->sin_addr.s_net;
-       ifp->if_flags = IFF_UP;
-       ifp->if_output = enlhoutput;    /* should never be used */
+       ifp->if_flags = IFF_UP|IFF_POINTOPOINT;
+       ifp->if_dstaddr = ifp->if_addr;
+       ifp->if_output = looutput;
        if_attach(ifp);
        if_attach(ifp);
-}
-
-enlhoutput(ifp, m0, dst)
-       struct ifnet *ifp;
-       struct mbuf *m0;
-       struct sockaddr *dst;
-{
-COUNT(ENLHOUTPUT);
-       ifp->if_oerrors++;
-       m_freem(m0);
-       return (0);
+       rtinit(&ifp->if_addr, &ifp->if_addr, RTF_UP|RTF_DIRECT|RTF_HOST);
 }
 #endif
 }
 #endif