X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/1dd558906323cb5eb855a1722ce15f6b9e5b8f2e..e3631d0610b4a2d85a5b228a5648eb49d08b0e00:/usr/src/sys/vax/if/if_en.c diff --git a/usr/src/sys/vax/if/if_en.c b/usr/src/sys/vax/if/if_en.c index 7fa716cd3c..4b59e35234 100644 --- a/usr/src/sys/vax/if/if_en.c +++ b/usr/src/sys/vax/if/if_en.c @@ -1,6 +1,7 @@ -/* if_en.c 4.37 82/03/09 */ +/* if_en.c 4.49 82/04/01 */ #include "en.h" +#include "imp.h" /* * Xerox prototype (3 Mb) Ethernet interface driver. @@ -27,6 +28,7 @@ #include "../net/ip.h" #include "../net/ip_var.h" #include "../net/pup.h" +#include "../net/route.h" #define ENMTU (1024+512) @@ -94,29 +96,31 @@ enattach(ui) struct uba_device *ui; { register struct en_softc *es = &en_softc[ui->ui_unit]; + register struct sockaddr_in *sin; COUNT(ENATTACH); es->es_if.if_unit = ui->ui_unit; es->es_if.if_name = "en"; es->es_if.if_mtu = ENMTU; - es->es_if.if_net = ui->ui_flags; + es->es_if.if_net = ui->ui_flags & 0xff; es->es_if.if_host[0] = - (~(((struct endevice *)eninfo[ui->ui_unit]->ui_addr)->en_addr)) & 0xff; -#ifdef ENKLUDGE - if (es->es_if.if_net == 10) { - es->es_if.if_host[0] <<= 16; - es->es_if.if_host[0] |= 0x4e; - } -#endif - es->es_if.if_addr = - if_makeaddr(es->es_if.if_net, es->es_if.if_host[0]); - es->es_if.if_broadaddr = - if_makeaddr(es->es_if.if_net, 0); + (~(((struct endevice *)eninfo[ui->ui_unit]->ui_addr)->en_addr)) & 0xff; + sin = (struct sockaddr_in *)&es->es_if.if_addr; + sin->sin_family = AF_INET; + sin->sin_addr = if_makeaddr(es->es_if.if_net, es->es_if.if_host[0]); + sin = (struct sockaddr_in *)&es->es_if.if_broadaddr; + sin->sin_family = AF_INET; + sin->sin_addr = if_makeaddr(es->es_if.if_net, 0); + es->es_if.if_flags = IFF_BROADCAST; 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; if_attach(&es->es_if); +#if NIMP == 0 + /* here's one for you john baby.... */ + enlhinit((ui->ui_flags &~ 0xff) | 0x0a); +#endif } /* @@ -151,6 +155,7 @@ eninit(unit) if (if_ubainit(&es->es_ifuba, ui->ui_ubanum, sizeof (struct en_header), (int)btoc(ENMTU)) == 0) { printf("en%d: can't initialize\n", unit); + es->es_if.if_flags &= ~IFF_UP; return; } addr = (struct endevice *)ui->ui_addr; @@ -165,8 +170,10 @@ eninit(unit) addr->en_iwc = -(sizeof (struct en_header) + ENMTU) >> 1; addr->en_istat = EN_IEN|EN_GO; es->es_oactive = 1; + es->es_if.if_flags |= IFF_UP; enxint(unit); splx(s); + if_rtinit(&es->es_if, RTF_DIRECT|RTF_UP); } int enlastdel = 25; @@ -222,7 +229,8 @@ restart: * Have request mapped to UNIBUS for transmission. * Purge any stale data from this BDP, and start the otput. */ - UBAPURGE(es->es_ifuba.ifu_uba, es->es_ifuba.ifu_w.ifrw_bdp); + if (es->es_ifuba.ifu_flags & UBA_NEEDBDP) + UBAPURGE(es->es_ifuba.ifu_uba, es->es_ifuba.ifu_w.ifrw_bdp); addr = (struct endevice *)ui->ui_addr; addr->en_oba = (int)es->es_ifuba.ifu_w.ifrw_info; addr->en_odelay = es->es_delay; @@ -240,20 +248,22 @@ enxint(unit) { register struct uba_device *ui = eninfo[unit]; register struct en_softc *es = &en_softc[unit]; - register struct endevice *addr; + register struct endevice *addr = (struct endevice *)ui->ui_addr; COUNT(ENXINT); if (es->es_oactive == 0) return; - addr = (struct endevice *)ui->ui_addr; + if (es->es_mask && (addr->en_ostat&EN_OERROR)) { + es->es_if.if_oerrors++; + if (es->es_if.if_oerrors % 100 == 0) + printf("en%d: += 100 output errors\n", unit); + endocoll(unit); + return; + } es->es_if.if_opackets++; es->es_oactive = 0; es->es_delay = 0; es->es_mask = ~0; - if (addr->en_ostat&EN_OERROR) { - es->es_if.if_oerrors++; - printf("en%d: output error\n", unit); - } if (es->es_ifuba.ifu_xtofree) { m_freem(es->es_ifuba.ifu_xtofree); es->es_ifuba.ifu_xtofree = 0; @@ -268,17 +278,25 @@ COUNT(ENXINT); /* * Collision on ethernet interface. Do exponential * backoff, and retransmit. If have backed off all - * the way printing warning diagnostic, and drop packet. + * the way print warning diagnostic, and drop packet. */ encollide(unit) int unit; { - register struct en_softc *es = &en_softc[unit]; + struct en_softc *es = &en_softc[unit]; COUNT(ENCOLLIDE); es->es_if.if_collisions++; if (es->es_oactive == 0) return; + endocoll(unit); +} + +endocoll(unit) + int unit; +{ + register struct en_softc *es = &en_softc[unit]; + /* * Es_mask is a 16 bit number with n low zero bits, with * n the number of backoffs. When es_mask is 0 we have @@ -298,7 +316,6 @@ COUNT(ENCOLLIDE); enstart(unit); } -int enprintierrors; struct sockaddr_pup pupsrc = { AF_PUP }; struct sockaddr_pup pupdst = { AF_PUP }; struct sockproto pupproto = { PF_PUP }; @@ -328,11 +345,12 @@ COUNT(ENRINT); /* * Purge BDP; drop if input error indicated. */ - UBAPURGE(es->es_ifuba.ifu_uba, es->es_ifuba.ifu_r.ifrw_bdp); + if (es->es_ifuba.ifu_flags & UBA_NEEDBDP) + UBAPURGE(es->es_ifuba.ifu_uba, es->es_ifuba.ifu_r.ifrw_bdp); if (addr->en_istat&EN_IERROR) { es->es_if.if_ierrors++; - if (enprintierrors) - printf("en%d: input error\n", unit); + if (es->es_if.if_ierrors % 100 == 0) + printf("en%d: += 100 input errors\n", unit); goto setup; } @@ -361,16 +379,14 @@ COUNT(ENRINT); #ifdef INET case ENPUP_IPTYPE: - len = htons((u_short)endataaddr(en, off ? off+2 : 0, struct ip *)->ip_len); - if (off) - len += 2; + len = htons((u_short)endataaddr(en, + off ? off + sizeof (u_short) : 0, struct ip *)->ip_len); break; #endif #ifdef PUP case ENPUP_PUPTYPE: - len = endataaddr(en, off, struct pup_header *)->pup_length; - if (off) - len -= 2; + len = endataaddr(en, off ? off + sizeof (u_short) : 0, + struct pup_header *)->pup_length; break; #endif @@ -378,6 +394,8 @@ COUNT(ENRINT); printf("en%d: unknown pkt type 0x%x\n", unit, en->en_type); goto setup; } + if (off) + len += sizeof (u_short); if (len == 0) goto setup; @@ -391,28 +409,36 @@ COUNT(ENRINT); if (m == 0) goto setup; if (off) { - m->m_off += 2; - m->m_len -= 2; + m->m_off += sizeof (u_short); + m->m_len -= sizeof (u_short); } switch (en->en_type) { #ifdef INET case ENPUP_IPTYPE: - setipintr(); + schednetisr(NETISR_IP); inq = &ipintrq; break; #endif +#ifdef PUP case ENPUP_PUPTYPE: { struct pup_header *pup = mtod(m, struct pup_header *); pupproto.sp_protocol = pup->pup_type; pupdst.spup_addr = pup->pup_dport; pupsrc.spup_addr = pup->pup_sport; - raw_input(m, &pupproto, &pupdst, &pupsrc); + raw_input(m, &pupproto, (struct sockaddr *)&pupdst, + (struct sockaddr *)&pupsrc); goto setup; - } } - IF_ENQUEUE(inq, m); +#endif + } + + if (IF_QFULL(inq)) { + IF_DROP(inq); + m_freem(m); + } else + IF_ENQUEUE(inq, m); setup: /* @@ -429,65 +455,55 @@ setup: * Use trailer local net encapsulation if enough data in first * packet leaves a multiple of 512 bytes of data in remainder. */ -enoutput(ifp, m0, pf) +enoutput(ifp, m0, dst) struct ifnet *ifp; struct mbuf *m0; - int pf; + struct sockaddr *dst; { - int type, dest; + int type, dest, s; register struct mbuf *m = m0; register struct en_header *en; - int s; + register int off; COUNT(ENOUTPUT); - switch (pf) { + switch (dst->sa_family) { #ifdef INET - case PF_INET: { - register struct ip *ip = mtod(m0, struct ip *); - int off; - -#ifndef ENKLUDGE - dest = ip->ip_dst.s_addr >> 24; -#else - dest = (ip->ip_dst.s_addr >> 8) & 0xff; -#endif - off = ntohs((u_short)ip->ip_len) - m->m_len; -#ifndef ENKLUDGE - if (off > 0 && (off & 0x1ff) == 0 && m->m_off >= MMINOFF + 2) { + case AF_INET: + dest = ((struct sockaddr_in *)dst)->sin_addr.s_addr >> 24; + off = ntohs((u_short)mtod(m, struct ip *)->ip_len) - m->m_len; + if (off > 0 && (off & 0x1ff) == 0 && + m->m_off >= MMINOFF + sizeof (u_short)) { type = ENPUP_TRAIL + (off>>9); - m->m_off -= 2; - m->m_len += 2; + m->m_off -= sizeof (u_short); + m->m_len += sizeof (u_short); *mtod(m, u_short *) = ENPUP_IPTYPE; goto gottrailertype; } -#endif type = ENPUP_IPTYPE; off = 0; goto gottype; - } #endif #ifdef PUP - case PF_PUP: { - register struct pup_header *pup = mtod(m, struct pup_header *); - - dest = pup->pup_dhost; - off = pup->pup_length - m->m_len; - if (off > 0 && (off & 0x1ff) == 0 && m->m_off >= MMINOFF + 2) { + case AF_PUP: + dest = ((struct sockaddr_pup *)dst)->spup_addr.pp_host; + off = mtod(m, struct pup_header *)->pup_length - m->m_len; + if (off > 0 && (off & 0x1ff) == 0 && + m->m_off >= MMINOFF + sizeof (u_short)) { type = ENPUP_TRAIL + (off>>9); - m->m_off -= 2; - m->m_len += 2; + m->m_off -= sizeof (u_short); + m->m_len += sizeof (u_short); *mtod(m, u_short *) = ENPUP_PUPTYPE; goto gottrailertype; } type = ENPUP_PUPTYPE; off = 0; goto gottype; - } #endif default: - printf("en%d: can't encapsulate pf%d\n", ifp->if_unit, pf); + printf("en%d: can't handle af%d\n", ifp->if_unit, + dst->sa_family); m_freem(m0); return (0); } @@ -533,9 +549,63 @@ gottype: * not yet active. */ s = splimp(); + if (IF_QFULL(&ifp->if_snd)) { + IF_DROP(&ifp->if_snd); + m_freem(m); + splx(s); + return (0); + } IF_ENQUEUE(&ifp->if_snd, m); if (en_softc[ifp->if_unit].es_oactive == 0) enstart(ifp->if_unit); splx(s); return (1); } + +#if NIMP == 0 && NEN > 0 +/* + * Logical host interface driver. + * Allows host to appear as an ARPAnet + * logical host. Must also have routing + * table entry set up to forward packets + * to appropriate gateway on localnet. + */ + +struct ifnet enlhif; +int enlhoutput(); + +/* + * Called by localnet interface to allow logical + * host interface to "attach". Nothing should ever + * be sent locally to this interface, it's purpose + * is simply to establish the host's arpanet address. + */ +enlhinit(addr) + int addr; +{ + register struct ifnet *ifp = &enlhif; + register struct sockaddr_in *sin; + +COUNT(ENLHINIT); + ifp->if_name = "lh"; + ifp->if_mtu = ENMTU; + sin = (struct sockaddr_in *)&ifp->if_addr; + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = addr; + ifp->if_net = sin->sin_addr.s_net; + ifp->if_flags = IFF_UP; + ifp->if_output = enlhoutput; /* should never be used */ + 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); +} +#endif