convert interfaces to sockaddr's and add hooks for routing
authorSam Leffler <sam@ucbvax.Berkeley.EDU>
Mon, 29 Mar 1982 05:24:00 +0000 (21:24 -0800)
committerSam Leffler <sam@ucbvax.Berkeley.EDU>
Mon, 29 Mar 1982 05:24:00 +0000 (21:24 -0800)
SCCS-vsn: sys/net/if.c 4.11
SCCS-vsn: sys/net/if.h 4.11
SCCS-vsn: sys/vax/if/if_dmc.c 4.7
SCCS-vsn: sys/vax/if/if_en.c 4.44
SCCS-vsn: sys/deprecated/netimp/if_imp.c 4.20
SCCS-vsn: sys/net/if_loop.c 4.8
SCCS-vsn: sys/vax/if/if_uba.c 4.10
SCCS-vsn: sys/netinet/in_pcb.c 4.22
SCCS-vsn: sys/netinet/ip_input.c 1.35
SCCS-vsn: sys/netinet/ip_output.c 1.27
SCCS-vsn: sys/net/raw_cb.c 4.6
SCCS-vsn: sys/deprecated/netimp/raw_imp.c 4.9
SCCS-vsn: sys/netinet/raw_ip.c 4.9
SCCS-vsn: sys/deprecated/netpup/raw_pup.c 4.9
SCCS-vsn: sys/net/route.c 4.2
SCCS-vsn: sys/net/route.h 4.2
SCCS-vsn: sys/netinet/tcp_output.c 4.36
SCCS-vsn: sys/netinet/tcp_subr.c 4.20
SCCS-vsn: sys/netinet/udp_usrreq.c 4.23

19 files changed:
usr/src/sys/deprecated/netimp/if_imp.c
usr/src/sys/deprecated/netimp/raw_imp.c
usr/src/sys/deprecated/netpup/raw_pup.c
usr/src/sys/net/if.c
usr/src/sys/net/if.h
usr/src/sys/net/if_loop.c
usr/src/sys/net/raw_cb.c
usr/src/sys/net/route.c
usr/src/sys/net/route.h
usr/src/sys/netinet/in_pcb.c
usr/src/sys/netinet/ip_input.c
usr/src/sys/netinet/ip_output.c
usr/src/sys/netinet/raw_ip.c
usr/src/sys/netinet/tcp_output.c
usr/src/sys/netinet/tcp_subr.c
usr/src/sys/netinet/udp_usrreq.c
usr/src/sys/vax/if/if_dmc.c
usr/src/sys/vax/if/if_en.c
usr/src/sys/vax/if/if_uba.c

index 223dafd..e24e6b0 100644 (file)
@@ -1,4 +1,4 @@
-/*     if_imp.c        4.19    82/03/19        */
+/*     if_imp.c        4.20    82/03/28        */
 
 #include "imp.h"
 #if NIMP > 0
 
 #include "imp.h"
 #if NIMP > 0
@@ -9,7 +9,6 @@
  * hardware specifics to the lower level interface driver.
  *
  * TODO:
  * hardware specifics to the lower level interface driver.
  *
  * TODO:
- *     rethink coupling between this module and device driver
  *     pass more error indications up to protocol modules
  */
 #include "../h/param.h"
  *     pass more error indications up to protocol modules
  */
 #include "../h/param.h"
@@ -79,6 +78,7 @@ impattach(ui)
 {
        struct imp_softc *sc = &imp_softc[ui->ui_unit];
        register struct ifnet *ifp = &sc->imp_if;
 {
        struct imp_softc *sc = &imp_softc[ui->ui_unit];
        register struct ifnet *ifp = &sc->imp_if;
+       struct sockaddr_in *sin;
 
 COUNT(IMPATTACH);
        /* UNIT COULD BE AMBIGUOUS */
 
 COUNT(IMPATTACH);
        /* UNIT COULD BE AMBIGUOUS */
@@ -87,38 +87,16 @@ COUNT(IMPATTACH);
        ifp->if_mtu = IMPMTU - sizeof(struct imp_leader);
        ifp->if_net = ui->ui_flags;
        /* the host and imp fields will be filled in by the imp */
        ifp->if_mtu = IMPMTU - sizeof(struct imp_leader);
        ifp->if_net = ui->ui_flags;
        /* the host and imp fields will be filled in by the imp */
-       ifp->if_addr = if_makeaddr(ifp->if_net, 0);
+       sin = (struct sockaddr_in *)&ifp->if_addr;
+       sin->sin_family = AF_INET;
+       sin->sin_addr = if_makeaddr(ifp->if_net, 0);
        ifp->if_init = impinit;
        ifp->if_output = impoutput;
        /* reset is handled at the hardware level */
        if_attach(ifp);
        ifp->if_init = impinit;
        ifp->if_output = impoutput;
        /* reset is handled at the hardware level */
        if_attach(ifp);
-       /* kludge to hand pointers back to hardware attach routine */
        return ((int)&sc->imp_if);
 }
 
        return ((int)&sc->imp_if);
 }
 
-#ifdef notdef
-/*
- * Timer routine to keep priming the IMP until it sends
- * us the noops we need.  Since we depend on the host and
- * imp values returned in the noop messages, we must wait
- * for them before we allow any outgoing traffic.
- */
-imptimer(sc)
-       register struct imp_softc *sc;
-{
-       int s = splimp();
-
-       if (sc->imp_state != IMPS_INIT) {
-               splx(s);
-               return;
-       }
-       sc->imp_dropcnt = IMP_DROPCNT;
-       impnoops(sc);
-       timeout(imptimer, (caddr_t)sc, 30 * hz);
-       splx(s);
-}
-#endif
-
 /*
  * IMP initialization routine: call hardware module to
  * setup UNIBUS resources, init state and get ready for
 /*
  * IMP initialization routine: call hardware module to
  * setup UNIBUS resources, init state and get ready for
@@ -131,15 +109,12 @@ impinit(unit)
 
        if ((*sc->imp_cb.ic_init)(unit) == 0) {
                sc->imp_state = IMPS_DOWN;
 
        if ((*sc->imp_cb.ic_init)(unit) == 0) {
                sc->imp_state = IMPS_DOWN;
+               sc->imp_if.if_flags &= ~IFF_UP;
                return;
        }
        sc->imp_state = IMPS_INIT;
                return;
        }
        sc->imp_state = IMPS_INIT;
-#ifdef notdef
-       imptimer(sc);
-#else
        sc->imp_dropcnt = IMP_DROPCNT;
        impnoops(sc);
        sc->imp_dropcnt = IMP_DROPCNT;
        impnoops(sc);
-#endif
 }
 
 struct sockproto impproto = { PF_IMPLINK };
 }
 
 struct sockproto impproto = { PF_IMPLINK };
@@ -164,6 +139,7 @@ impinput(unit, m)
        struct control_leader *cp;
        struct in_addr addr;
        struct mbuf *next;
        struct control_leader *cp;
        struct in_addr addr;
        struct mbuf *next;
+       struct sockaddr_in *sin;
 
 COUNT(IMPINPUT);
        /* verify leader length. */
 
 COUNT(IMPINPUT);
        /* verify leader length. */
@@ -246,9 +222,7 @@ COUNT(IMPINPUT);
         * Compare the local address with that in the message.
         * Reset the local address notion if it doesn't match.
         */
         * Compare the local address with that in the message.
         * Reset the local address notion if it doesn't match.
         */
-       case IMPTYPE_NOOP: {
-               register struct in_addr *sin;
-
+       case IMPTYPE_NOOP:
                if (sc->imp_state == IMPS_DOWN) {
                        sc->imp_state = IMPS_INIT;
                        sc->imp_dropcnt = IMP_DROPCNT;
                if (sc->imp_state == IMPS_DOWN) {
                        sc->imp_state = IMPS_INIT;
                        sc->imp_dropcnt = IMP_DROPCNT;
@@ -256,15 +230,15 @@ COUNT(IMPINPUT);
                if (sc->imp_state != IMPS_INIT || --sc->imp_dropcnt > 0)
                        goto drop;
                sc->imp_state = IMPS_UP;
                if (sc->imp_state != IMPS_INIT || --sc->imp_dropcnt > 0)
                        goto drop;
                sc->imp_state = IMPS_UP;
-               sin = &sc->imp_if.if_addr;
-               sc->imp_if.if_host[0] = sin->s_host = ip->il_host;
-               sin->s_imp = ip->il_imp;
+               sc->imp_if.if_flags |= IFF_UP;
+               sin = (struct sockaddr_in *)&sc->imp_if.if_addr;
+               sc->imp_if.if_host[0] = sin->sin_addr.s_host = ip->il_host;
+               sin->sin_addr.s_imp = ip->il_imp;
                impmsg(sc, "reset (host %d/imp %d)", (u_int)ip->il_host,
                        ntohs(ip->il_imp));
                /* restart output in case something was q'd */
                (*sc->imp_cb.ic_start)(sc->imp_if.if_unit);
                goto drop;
                impmsg(sc, "reset (host %d/imp %d)", (u_int)ip->il_host,
                        ntohs(ip->il_imp));
                /* restart output in case something was q'd */
                (*sc->imp_cb.ic_start)(sc->imp_if.if_unit);
                goto drop;
-       }
 
        /*
         * RFNM or INCOMPLETE message, record in
 
        /*
         * RFNM or INCOMPLETE message, record in
@@ -341,7 +315,8 @@ COUNT(IMPINPUT);
        default:
        rawlinkin:
                impproto.sp_protocol = ip->il_link;
        default:
        rawlinkin:
                impproto.sp_protocol = ip->il_link;
-               impdst.sin_addr = sc->imp_if.if_addr;
+               sin = (struct sockaddr_in *)&sc->imp_if.if_addr;
+               impdst.sin_addr = sin->sin_addr;;
                impsrc.sin_addr.s_net = ip->il_network;
                impsrc.sin_addr.s_host = ip->il_host;
                impsrc.sin_addr.s_imp = ip->il_imp;
                impsrc.sin_addr.s_net = ip->il_network;
                impsrc.sin_addr.s_host = ip->il_host;
                impsrc.sin_addr.s_imp = ip->il_imp;
@@ -368,6 +343,7 @@ impdown(sc)
 {
 
        sc->imp_state = IMPS_DOWN;
 {
 
        sc->imp_state = IMPS_DOWN;
+       sc->imp_if.if_flags &= ~IFF_UP;
        impmsg(sc, "marked down");
        /* notify protocols with messages waiting? */
 }
        impmsg(sc, "marked down");
        /* notify protocols with messages waiting? */
 }
@@ -390,9 +366,10 @@ impmsg(sc, fmt, a1, a2)
  * transmission to the imp.  Sets up the header and calls impsnd to
  * enqueue the message for this IMP's hardware driver.
  */
  * transmission to the imp.  Sets up the header and calls impsnd to
  * enqueue the message for this IMP's hardware driver.
  */
-impoutput(ifp, m0, pf)
+impoutput(ifp, m0, dst)
        register struct ifnet *ifp;
        struct mbuf *m0;
        register struct ifnet *ifp;
        struct mbuf *m0;
+       struct sockaddr *dst;
 {
        register struct imp_leader *imp;
        register struct mbuf *m = m0;
 {
        register struct imp_leader *imp;
        register struct mbuf *m = m0;
@@ -406,25 +383,27 @@ COUNT(IMPOUTPUT);
        if (x == IMPS_DOWN || x == IMPS_GOINGDOWN)
                goto drop;
 
        if (x == IMPS_DOWN || x == IMPS_GOINGDOWN)
                goto drop;
 
-       switch (pf) {
+       switch (dst->sa_family) {
 
 #ifdef INET
 
 #ifdef INET
-       case PF_INET: {
-               register struct ip *ip = mtod(m0, struct ip *);
+       case AF_INET: {
+               struct ip *ip = mtod(m0, struct ip *);
+               struct sockaddr_in *sin = (struct sockaddr_in *)dst;
 
 
-               dhost = ip->ip_dst.s_host;
-               dimp = ip->ip_dst.s_impno;
+               dhost = sin->sin_addr.s_host;
+               dimp = sin->sin_addr.s_impno;
                dlink = IMPLINK_IP;
                dnet = 0;
                len = ntohs((u_short)ip->ip_len);
                break;
        }
 #endif
                dlink = IMPLINK_IP;
                dnet = 0;
                len = ntohs((u_short)ip->ip_len);
                break;
        }
 #endif
-       case PF_IMPLINK:
+       case AF_IMPLINK:
                goto leaderexists;
 
        default:
                goto leaderexists;
 
        default:
-               printf("imp%d: can't encapsulate pf%d\n", ifp->if_unit, pf);
+               printf("imp%d: can't handle af%d\n", ifp->if_unit, 
+                       dst->sa_family);
                goto drop;
        }
 
                goto drop;
        }
 
index 6547546..ec93c5a 100644 (file)
@@ -1,4 +1,4 @@
-/*     raw_imp.c       4.8     82/03/13        */
+/*     raw_imp.c       4.9     82/03/28        */
 
 #include "../h/param.h"
 #include "../h/mbuf.h"
 
 #include "../h/param.h"
 #include "../h/mbuf.h"
  * Raw interface to IMP.
  */
 
  * Raw interface to IMP.
  */
 
-/*ARGSUSED*/
-rimp_ctlinput(m)
-       struct mbuf *m;
-{
-COUNT(RIMP_CTLINPUT);
-}
-
+struct sockaddr_in rawimpaddr = { AF_IMPLINK };
 /*
  * Generate IMP leader and pass packet to impoutput.
  * The user must create a skeletal leader in order to
 /*
  * Generate IMP leader and pass packet to impoutput.
  * The user must create a skeletal leader in order to
@@ -76,61 +70,13 @@ COUNT(RIMP_OUTPUT);
        ip->il_network = sin->sin_addr.s_net;
        ip->il_host = sin->sin_addr.s_host;
        ip->il_imp = sin->sin_addr.s_imp;
        ip->il_network = sin->sin_addr.s_net;
        ip->il_host = sin->sin_addr.s_host;
        ip->il_imp = sin->sin_addr.s_imp;
-       ifp = if_ifonnetof(sin->sin_addr);
-       if (ifp == 0) {
-               ifp = if_gatewayfor(sin->sin_addr);
-               if (ifp == 0)
-                       goto bad;
-       }
-       return (impoutput(ifp, m, PF_IMPLINK));
+       /* no routing here */
+       ifp = if_ifonnetof(ip->il_network);
+       if (ifp == 0)
+               goto bad;
+       return (impoutput(ifp, m, (struct sockaddr *)&rawimpaddr));
 
 bad:
        m_freem(m);
        return (0);
 }
 
 bad:
        m_freem(m);
        return (0);
 }
-
-/*
- * Intercept operations required to
- * maintain interface pointer used on output.
- */
-rimp_usrreq(so, req, m, addr)
-       struct socket *so;
-       int req;
-       struct mbuf *m;
-       caddr_t addr;
-{
-       register struct rawcb *rp = sotorawcb(so);
-       register struct sockaddr_in *sin;
-       register struct ifnet *ifp;
-
-COUNT(RIMP_USRREQ);
-       if (rp == 0 && req != PRU_ATTACH)
-               return (EINVAL);
-
-       switch (req) {
-
-       /*
-        * Verify address has an interface to go with it.
-        */
-       case PRU_CONNECT:
-               if (rp->rcb_pcb)
-                       return (EISCONN);
-               sin = (struct sockaddr_in *)addr;
-               ifp = if_ifonnetof(sin->sin_addr);
-               if (ifp == 0) {
-                       ifp = if_gatewayfor(sin->sin_addr);
-                       if (ifp == 0)
-                               return (EADDRNOTAVAIL); /* XXX */
-               }
-               rp->rcb_pcb = (caddr_t)ifp;
-               break;
-
-       case PRU_DISCONNECT:
-               rp->rcb_pcb = 0;
-               break;
-
-       case PRU_CONTROL:
-               return (EOPNOTSUPP);
-       }
-       return (raw_usrreq(so, req, m, addr));
-}
index 6bfe50d..eb112f5 100644 (file)
@@ -1,4 +1,4 @@
-/*     raw_pup.c       4.8     82/03/13        */
+/*     raw_pup.c       4.9     82/03/28        */
 
 #include "../h/param.h"
 #include "../h/mbuf.h"
 
 #include "../h/param.h"
 #include "../h/mbuf.h"
  * Raw PUP protocol interface.
  */
 
  * Raw PUP protocol interface.
  */
 
-/*ARGSUSED*/
-rpup_ctlinput(m)
-       struct mbuf *m;
-{
-COUNT(RPUP_CTLINPUT);
-}
-
 /*
  * Encapsulate packet in PUP header which is supplied by the
  * user.  This is done to allow user to specify PUP identifier.
 /*
  * Encapsulate packet in PUP header which is supplied by the
  * user.  This is done to allow user to specify PUP identifier.
@@ -36,7 +29,6 @@ rpup_output(m, so)
        int len;
        struct mbuf *n;
        struct sockaddr_pup *spup;
        int len;
        struct mbuf *n;
        struct sockaddr_pup *spup;
-       struct in_addr in;
        struct ifnet *ifp;
 
 COUNT(RPUP_OUTPUT);
        struct ifnet *ifp;
 
 COUNT(RPUP_OUTPUT);
@@ -61,11 +53,10 @@ COUNT(RPUP_OUTPUT);
        spup = (struct sockaddr_pup *)&rp->rcb_addr;
        pup->pup_dport = spup->spup_addr;
 
        spup = (struct sockaddr_pup *)&rp->rcb_addr;
        pup->pup_dport = spup->spup_addr;
 
-       in.s_net = spup->spup_addr.pp_net;
-       ifp = if_ifonnetof(in);
+       ifp = if_ifonnetof(pup->pup_dnet);
        if (ifp == 0)
                goto bad;
        if (ifp == 0)
                goto bad;
-       return (enoutput(ifp, m, PF_PUP));
+       return (enoutput(ifp, m, (struct sockaddr *)spup));
 
 bad:
        m_freem(m);
 
 bad:
        m_freem(m);
index c1c6c10..bf986a2 100644 (file)
@@ -1,25 +1,38 @@
-/*     if.c    4.10    82/03/15        */
+/*     if.c    4.11    82/03/28        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
+#include "../h/socket.h"
 #include "../net/in.h"
 #include "../net/in_systm.h"
 #include "../net/if.h"
 #include "../net/in.h"
 #include "../net/in_systm.h"
 #include "../net/if.h"
+#include "../net/af.h"
 
 int    ifqmaxlen = IFQ_MAXLEN;
 
 
 int    ifqmaxlen = IFQ_MAXLEN;
 
+/*
+ * Network interface utility routines.
+ *
+ * Routines with if_ifwith* names take sockaddr *'s as
+ * parameters.  Other routines take value parameters,
+ * e.g. if_ifwithnet takes the network number.
+ */
+
 ifinit()
 {
        register struct ifnet *ifp;
 
        for (ifp = ifnet; ifp; ifp = ifp->if_next)
                if (ifp->if_init) {
 ifinit()
 {
        register struct ifnet *ifp;
 
        for (ifp = ifnet; ifp; ifp = ifp->if_next)
                if (ifp->if_init) {
-                       (*ifp->if_init)();
+                       (*ifp->if_init)(ifp->if_unit);
                        if (ifp->if_snd.ifq_maxlen == 0)
                                ifp->if_snd.ifq_maxlen = ifqmaxlen;
                }
 }
 
                        if (ifp->if_snd.ifq_maxlen == 0)
                                ifp->if_snd.ifq_maxlen = ifqmaxlen;
                }
 }
 
+/*
+ * Call each interface on a Unibus reset.
+ */
 ifubareset(uban)
        int uban;
 {
 ifubareset(uban)
        int uban;
 {
@@ -30,6 +43,10 @@ ifubareset(uban)
                        (*ifp->if_ubareset)(uban);
 }
 
                        (*ifp->if_ubareset)(uban);
 }
 
+/*
+ * Attach an interface to the
+ * list of "active" interfaces.
+ */
 if_attach(ifp)
        struct ifnet *ifp;
 {
 if_attach(ifp)
        struct ifnet *ifp;
 {
@@ -41,48 +58,86 @@ COUNT(IF_ATTACH);
        *p = ifp;
 }
 
        *p = ifp;
 }
 
+/*
+ * Locate an interface based on a complete address.
+ */
 /*ARGSUSED*/
 struct ifnet *
 /*ARGSUSED*/
 struct ifnet *
-if_ifwithaddr(in)
-       struct in_addr in;
+if_ifwithaddr(addr)
+       struct sockaddr *addr;
 {
        register struct ifnet *ifp;
 
 COUNT(IF_IFWITHADDR);
 {
        register struct ifnet *ifp;
 
 COUNT(IF_IFWITHADDR);
-       for (ifp = ifnet; ifp; ifp = ifp->if_next)
-               if (in.s_addr == ifp->if_addr.s_addr ||
-                   (ifp->if_broadaddr.s_addr != 0 &&
-                    in.s_addr == ifp->if_broadaddr.s_addr))
+#define        equal(a1, a2) \
+       (bcmp((caddr_t)((a1)->sa_data), (caddr_t)((a2)->sa_data), 14) == 0)
+       for (ifp = ifnet; ifp; ifp = ifp->if_next) {
+               if (ifp->if_addr.sa_family != addr->sa_family)
+                       continue;
+               if (equal(&ifp->if_addr, addr))
+                       break;
+               if ((ifp->if_flags & IFF_BROADCAST) &&
+                   equal(&ifp->if_broadaddr, addr))
                        break;
                        break;
+       }
        return (ifp);
 }
 
        return (ifp);
 }
 
-/*ARGSUSED*/
+/*
+ * Find an interface on a specific network.  If many, choice
+ * is first found.
+ */
 struct ifnet *
 struct ifnet *
-if_ifonnetof(in)
-       struct in_addr in;
+if_ifwithnet(addr)
+       register struct sockaddr *addr;
+{
+       register struct ifnet *ifp;
+       register int af = addr->sa_family;
+       register int (*netmatch)() = afswitch[af].af_netmatch;
+
+       for (ifp = ifnet; ifp; ifp = ifp->if_next) {
+               if (af != ifp->if_addr.sa_family)
+                       continue;
+               if ((*netmatch)(addr, &ifp->if_addr))
+                       break;
+       }
+       return (ifp);
+}
+
+/*
+ * As above, but parameter is network number.
+ */
+struct ifnet *
+if_ifonnetof(net)
+       register int net;
 {
        register struct ifnet *ifp;
 {
        register struct ifnet *ifp;
-       int net;
 
 
-COUNT(IF_IFONNETOF);
-       net = in.s_net;                 /* XXX */
        for (ifp = ifnet; ifp; ifp = ifp->if_next)
                if (ifp->if_net == net)
                        break;
        return (ifp);
 }
 
        for (ifp = ifnet; ifp; ifp = ifp->if_next)
                if (ifp->if_net == net)
                        break;
        return (ifp);
 }
 
-/*ARGSUSED*/
+/*
+ * Find an interface using a specific address family
+ */
 struct ifnet *
 struct ifnet *
-if_gatewayfor(addr)
-       struct in_addr addr;
+if_ifwithaf(af)
+       register int af;
 {
 {
+       register struct ifnet *ifp;
 
 
-COUNT(IF_GATEWAYFOR);
-       return (0);
+       for (ifp = ifnet; ifp; ifp = ifp->if_next)
+               if (ifp->if_addr.sa_family == af)
+                       break;
+       return (ifp);
 }
 
 }
 
+/*
+ * Formulate an Internet address from network + host.  Used in
+ * building addresses stored in the ifnet structure.
+ */
 struct in_addr
 if_makeaddr(net, host)
        int net, host;
 struct in_addr
 if_makeaddr(net, host)
        int net, host;
index 067db3f..4937ffa 100644 (file)
@@ -1,4 +1,4 @@
-/*     if.h    4.10    82/03/19        */
+/*     if.h    4.11    82/03/28        */
 
 /*
  * Structures defining a network interface, providing a packet
 
 /*
  * Structures defining a network interface, providing a packet
@@ -9,21 +9,20 @@
  * received from its medium.
  *
  * Output occurs when the routine if_output is called, with three parameters:
  * received from its medium.
  *
  * Output occurs when the routine if_output is called, with three parameters:
- *     (*ifp->if_output)(ifp, m, pf)
- * Here m is the mbuf chain to be sent and pf is the protocol family
- * of the internetwork datagram format in which the data is wrapped
- * (e.g. PF_PUP or PF_INET).  The output routine encapsulates the
- * supplied datagram if necessary, and then transmits it on its medium.
+ *     (*ifp->if_output)(ifp, m, dst)
+ * Here m is the mbuf chain to be sent and dst is the destination address.
+ * The output routine encapsulates the supplied datagram if necessary,
+ * and then transmits it on its medium.
  *
  * On input, each interface unwraps the data received by it, and either
  * places it on the input queue of a internetwork datagram routine
  * and posts the associated software interrupt, or passes the datagram to a raw
  * packet input routine.
  *
  *
  * On input, each interface unwraps the data received by it, and either
  * places it on the input queue of a internetwork datagram routine
  * and posts the associated software interrupt, or passes the datagram to a raw
  * packet input routine.
  *
- * Routines exist for locating interfaces by their internet addresses
+ * Routines exist for locating interfaces by their addresses
  * or for locating a interface on a certain network, as well as more general
  * routing and gateway routines maintaining information used to locate
  * or for locating a interface on a certain network, as well as more general
  * routing and gateway routines maintaining information used to locate
- * interfaces.  These routines live in the files if.c and ip_ggp.c.
+ * interfaces.  These routines live in the files if.c and route.c
  */
 
 /*
  */
 
 /*
@@ -36,9 +35,10 @@ struct ifnet {
        short   if_unit;                /* sub-unit for lower level driver */
        short   if_mtu;                 /* maximum transmission unit */
        short   if_net;                 /* network number of interface */
        short   if_unit;                /* sub-unit for lower level driver */
        short   if_mtu;                 /* maximum transmission unit */
        short   if_net;                 /* network number of interface */
+       short   if_flags;               /* up/down, broadcast, etc. */
        int     if_host[2];             /* local net host number */
        int     if_host[2];             /* local net host number */
-       struct  in_addr if_addr;        /* internet address of interface */
-       struct  in_addr if_broadaddr;   /* broadcast address of interface */
+       struct  sockaddr if_addr;       /* internet address of interface */
+       struct  sockaddr if_broadaddr;  /* broadcast address of interface */
        struct  ifqueue {
                struct  mbuf *ifq_head;
                struct  mbuf *ifq_tail;
        struct  ifqueue {
                struct  mbuf *ifq_head;
                struct  mbuf *ifq_tail;
@@ -60,6 +60,10 @@ struct ifnet {
        struct  ifnet *if_next;
 };
 
        struct  ifnet *if_next;
 };
 
+#define        IFF_UP          0x1             /* interface is up */
+#define        IFF_BROADCAST   0x2             /* broadcast address valid */
+#define        IFF_DEBUG       0x4             /* turn on debugging */
+
 /*
  * Output queues (ifp->if_snd) and internetwork datagram level (pup level 1)
  * input routines have queues of messages stored on ifqueue structures
 /*
  * Output queues (ifp->if_snd) and internetwork datagram level (pup level 1)
  * input routines have queues of messages stored on ifqueue structures
@@ -97,11 +101,12 @@ struct ifnet {
 #define        IFQ_MAXLEN      50
 
 #ifdef KERNEL
 #define        IFQ_MAXLEN      50
 
 #ifdef KERNEL
-struct ifqueue rawintrq;               /* raw packet input queue */
 #ifdef INET
 struct ifqueue ipintrq;                /* ip packet input queue */
 #endif
 #ifdef INET
 struct ifqueue ipintrq;                /* ip packet input queue */
 #endif
+struct ifqueue rawintrq;               /* raw packet input queue */
 struct ifnet *ifnet;
 struct ifnet *ifnet;
-struct ifnet *if_ifwithaddr(), *if_ifonnetof(), *if_gatewayfor();
+struct ifnet *if_ifwithaddr(), *if_ifwithnet(), *if_ifwithaf();
+struct ifnet *if_ifonnetof();
 struct in_addr if_makeaddr();
 #endif
 struct in_addr if_makeaddr();
 #endif
index ac8830e..e0b04e1 100644 (file)
@@ -1,4 +1,4 @@
-/*     if_loop.c       4.7     82/03/19        */
+/*     if_loop.c       4.8     82/03/28        */
 
 /*
  * Loopback interface driver for protocol testing and timing.
 
 /*
  * Loopback interface driver for protocol testing and timing.
@@ -24,32 +24,36 @@ int looutput();
 loattach()
 {
        register struct ifnet *ifp = &loif;
 loattach()
 {
        register struct ifnet *ifp = &loif;
+       register struct sockaddr_in *sin;
 
        ifp->if_name = "lo";
        ifp->if_mtu = LOMTU;
        ifp->if_net = LONET;
 
        ifp->if_name = "lo";
        ifp->if_mtu = LOMTU;
        ifp->if_net = LONET;
-       ifp->if_addr = if_makeaddr(ifp->if_net, 0);
+       sin = (struct sockaddr_in *)&ifp->if_addr;
+       sin->sin_family = AF_INET;
+       sin->sin_addr = if_makeaddr(ifp->if_net, 0);
+       ifp->if_flags = IFF_UP;
        ifp->if_output = looutput;
        if_attach(ifp);
 }
 
        ifp->if_output = looutput;
        if_attach(ifp);
 }
 
-looutput(ifp, m0, pf)
+looutput(ifp, m0, dst)
        struct ifnet *ifp;
        struct mbuf *m0;
        struct ifnet *ifp;
        struct mbuf *m0;
-       int pf;
+       struct sockaddr *dst;
 {
        int s = splimp();
        register struct ifqueue *ifq;
 
        ifp->if_opackets++;
 {
        int s = splimp();
        register struct ifqueue *ifq;
 
        ifp->if_opackets++;
-       switch (pf) {
+       switch (dst->sa_family) {
 
 #ifdef INET
 
 #ifdef INET
-       case PF_INET:
+       case AF_INET:
                ifq = &ipintrq;
                if (IF_QFULL(ifq)) {
                        IF_DROP(ifq);
                ifq = &ipintrq;
                if (IF_QFULL(ifq)) {
                        IF_DROP(ifq);
-                       (void) m_freem(m0);
+                       m_freem(m0);
                        splx(s);
                        return (0);
                }
                        splx(s);
                        return (0);
                }
@@ -57,11 +61,11 @@ looutput(ifp, m0, pf)
                schednetisr(NETISR_IP);
                break;
 #endif
                schednetisr(NETISR_IP);
                break;
 #endif
-
        default:
                splx(s);
        default:
                splx(s);
-               printf("lo%d: can't encapsulate pf%d\n", ifp->if_unit, pf);
-               (void) m_freem(m0);
+               printf("lo%d: can't handle af%d\n", ifp->if_unit,
+                       dst->sa_family);
+               m_freem(m0);
                return (0);
        }
        ifp->if_ipackets++;
                return (0);
        }
        ifp->if_ipackets++;
index ead8a1d..7cd10fd 100644 (file)
@@ -1,4 +1,4 @@
-/*     raw_cb.c        4.5     82/03/13        */
+/*     raw_cb.c        4.6     82/03/28        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -10,6 +10,7 @@
 #include "../net/in_systm.h"
 #include "../net/if.h"
 #include "../net/raw_cb.h"
 #include "../net/in_systm.h"
 #include "../net/if.h"
 #include "../net/raw_cb.h"
+#include "../net/pup.h"
 #include "../errno.h"
 
 /*
 #include "../errno.h"
 
 /*
@@ -17,7 +18,7 @@
  *
  * TODO:
  *     hash lookups by protocol family/protocol + address family
  *
  * TODO:
  *     hash lookups by protocol family/protocol + address family
- *     take care of unique address problems per AF
+ *     take care of unique address problems per AF?
  *     redo address binding to allow wildcards
  */
 
  *     redo address binding to allow wildcards
  */
 
@@ -31,9 +32,10 @@ raw_attach(so, addr)
 {
        struct mbuf *m;
        register struct rawcb *rp;
 {
        struct mbuf *m;
        register struct rawcb *rp;
-       struct ifnet *ifp = ifnet;
 
 COUNT(RAW_ATTACH);
 
 COUNT(RAW_ATTACH);
+       if (ifnet == 0)
+               return (EADDRNOTAVAIL);
        /*
         * Should we verify address not already in use?
         * Some say yes, others no.
        /*
         * Should we verify address not already in use?
         * Some say yes, others no.
@@ -41,24 +43,37 @@ COUNT(RAW_ATTACH);
        if (addr) switch (addr->sa_family) {
 
        case AF_IMPLINK:
        if (addr) switch (addr->sa_family) {
 
        case AF_IMPLINK:
-       case AF_INET: {
-               register struct sockaddr_in *sin = (struct sockaddr_in *)addr;
-
-               if (ifnet && sin->sin_addr.s_addr == 0)
-                       sin->sin_addr = ifnet->if_addr;
-               ifp = if_ifwithaddr(sin->sin_addr);
+       case AF_INET:
+               if (((struct sockaddr_in *)addr)->sin_addr.s_addr &&
+                   if_ifwithaddr(addr) == 0)
+                       return (EADDRNOTAVAIL);
                break;
                break;
-               }
 
 
-       case AF_PUP:
-               ifp = ifnet;
+#ifdef PUP
+       /*
+        * Curious, we convert PUP address format to internet
+        * to allow us to verify we're asking for an Ethernet
+        * interface.  This is wrong, but things are heavily
+        * oriented towards the internet addressing scheme, and
+        * converting internet to PUP would be very expensive.
+        */
+       case AF_PUP: {
+               struct sockaddr_pup *spup = (struct sockaddr_pup *)addr;
+               struct sockaddr_in inpup;
+
+               bzero((caddr_t)&inpup, sizeof(inpup));
+               inpup.sin_addr.s_net = spup->sp_net;
+               inpup.sin_addr.s_impno = spup->sp_host;
+               if (inpup.sin_addr.s_addr &&
+                   if_ifwithaddr((struct sockaddr *)&inpup) == 0)
+                       return (EADDRNOTAVAIL);
                break;
                break;
+       }
+#endif
 
        default:
                return (EAFNOSUPPORT);
        }
 
        default:
                return (EAFNOSUPPORT);
        }
-       if (ifp == 0)
-               return (EADDRNOTAVAIL);
        m = m_getclr(M_DONTWAIT);
        if (m == 0)
                return (ENOBUFS);
        m = m_getclr(M_DONTWAIT);
        if (m == 0)
                return (ENOBUFS);
@@ -71,7 +86,6 @@ COUNT(RAW_ATTACH);
        insque(rp, &rawcb);
        so->so_pcb = (caddr_t)rp;
        rp->rcb_pcb = 0;
        insque(rp, &rawcb);
        so->so_pcb = (caddr_t)rp;
        rp->rcb_pcb = 0;
-
        if (addr)
                bcopy((caddr_t)addr, (caddr_t)&so->so_addr, sizeof(*addr));
        return (0);
        if (addr)
                bcopy((caddr_t)addr, (caddr_t)&so->so_addr, sizeof(*addr));
        return (0);
@@ -95,7 +109,7 @@ COUNT(RAW_DETACH);
        so->so_pcb = 0;
        sofree(so);
        remque(rp);
        so->so_pcb = 0;
        sofree(so);
        remque(rp);
-       m_freem(dtom(rp));
+       (void) m_freem(dtom(rp));
 }
 
 /*
 }
 
 /*
@@ -119,6 +133,6 @@ raw_connaddr(rp, addr)
        struct sockaddr *addr;
 {
 COUNT(RAW_CONNADDR);
        struct sockaddr *addr;
 {
 COUNT(RAW_CONNADDR);
-       bcopy((caddr_t)addr, (caddr_t)&rp->rcb_addr, sizeof(struct sockaddr));
+       bcopy((caddr_t)addr, (caddr_t)&rp->rcb_addr, sizeof(*addr));
        rp->rcb_flags |= RAW_ADDR;
 }
        rp->rcb_flags |= RAW_ADDR;
 }
index 5734e51..255ad54 100644 (file)
@@ -1,15 +1,23 @@
-/*     route.c 4.1     82/03/27        */
+/*     route.c 4.2     82/03/28        */
 
 #include "../h/param.h"
 
 #include "../h/param.h"
+#include "../h/systm.h"
+#include "../h/dir.h"
+#include "../h/user.h"
+#include "../h/proc.h"
+#include "../h/file.h"
+#include "../h/inode.h"
+#include "../h/buf.h"
 #include "../h/mbuf.h"
 #include "../h/protosw.h"
 #include "../h/socket.h"
 #include "../h/socketvar.h"
 #include "../h/mbuf.h"
 #include "../h/protosw.h"
 #include "../h/socket.h"
 #include "../h/socketvar.h"
+#include "../h/ioctl.h"
 #include "../net/in.h"
 #include "../net/in_systm.h"
 #include "../net/in.h"
 #include "../net/in_systm.h"
+#include "../net/if.h"
 #include "../net/af.h"
 #include "../net/route.h"
 #include "../net/af.h"
 #include "../net/route.h"
-#include <errno.h>
 
 /*
  * Packet routing routines.
 
 /*
  * Packet routing routines.
@@ -24,12 +32,13 @@ route(ro)
 {
        register struct rtentry *rt, *rtmin;
        register struct mbuf *m;
 {
        register struct rtentry *rt, *rtmin;
        register struct mbuf *m;
+       register int key;
        struct afhash h;
        struct sockaddr *dst = &ro->ro_dst;
        struct afhash h;
        struct sockaddr *dst = &ro->ro_dst;
-       int af = dst->sa_family;
+       int af = dst->sa_family, doinghost;
 
 COUNT(ROUTE);
 
 COUNT(ROUTE);
-       if (ro->ro_ifp)         /* ??? */
+       if (ro && ro->ro_rt && ro->ro_rt->rt_ifp)       /* ??? */
                return;
        (*afswitch[af].af_hash)(dst, &h);
        m = routehash[h.afh_hosthash % RTHASHSIZ];
                return;
        (*afswitch[af].af_hash)(dst, &h);
        m = routehash[h.afh_hosthash % RTHASHSIZ];
@@ -62,11 +71,10 @@ again:
        }
        if (doinghost) {
                doinghost = 0;
        }
        if (doinghost) {
                doinghost = 0;
-               m = routethash[h.afh_nethash % RTHASHSIZ];
+               m = routehash[h.afh_nethash % RTHASHSIZ];
                key = h.afh_netkey;
                goto again;
        }
                key = h.afh_netkey;
                goto again;
        }
-       ro->ro_ifp = 0;
        ro->ro_rt = 0;
 }
 
        ro->ro_rt = 0;
 }
 
@@ -76,6 +84,7 @@ reroute(sa)
 {
        register struct rtentry *rt;
        register struct mbuf *m;
 {
        register struct rtentry *rt;
        register struct mbuf *m;
+       register int key;
        struct afhash h;
 
 COUNT(REROUTE);
        struct afhash h;
 
 COUNT(REROUTE);
@@ -99,13 +108,13 @@ COUNT(REROUTE);
 rtcontrol(req, addr)
        caddr_t addr;
 {
 rtcontrol(req, addr)
        caddr_t addr;
 {
-       register struct rtreq rq;
+       register struct rtentry rq;
        int x = splimp(), err = 0;
 
 COUNT(RTCONTROL);
        if (suser())
                goto bad;
        int x = splimp(), err = 0;
 
 COUNT(RTCONTROL);
        if (suser())
                goto bad;
-       if (copyin(addr, (caddr_t)&rq, sizeof(struct rtreq))) {
+       if (copyin(addr, (caddr_t)&rq, sizeof(struct rtentry))) {
                u.u_error = EFAULT;
                goto bad;
        }
                u.u_error = EFAULT;
                goto bad;
        }
@@ -124,9 +133,10 @@ rtrequest(req, new)
 {
        register struct rtentry *rt;
        register struct mbuf *m, **mprev;
 {
        register struct rtentry *rt;
        register struct mbuf *m, **mprev;
+       register int key;
        struct sockaddr *sa = &new->rt_dst;
        struct afhash h;
        struct sockaddr *sa = &new->rt_dst;
        struct afhash h;
-       int af = sa->sa_family;
+       int af = sa->sa_family, doinghost;
 
        (*afswitch[af].af_hash)(sa, &h);
        mprev = &routehash[h.afh_hosthash % RTHASHSIZ];
 
        (*afswitch[af].af_hash)(sa, &h);
        mprev = &routehash[h.afh_hosthash % RTHASHSIZ];
@@ -138,7 +148,7 @@ again:
                if (rt->rt_key != key)
                        continue;
                if (doinghost) {
                if (rt->rt_key != key)
                        continue;
                if (doinghost) {
-                       if (!equal(&rt->rt_dst, dst))
+                       if (!equal(&rt->rt_dst, &new->rt_dst))
                                continue;
                } else {
                        if (rt->rt_dst.sa_family != af)
                                continue;
                } else {
                        if (rt->rt_dst.sa_family != af)
@@ -156,7 +166,7 @@ again:
        }
 
        if (m == 0 && req != SIOCADDRT)
        }
 
        if (m == 0 && req != SIOCADDRT)
-               return (ESEARCH);
+               return (ESRCH);
        switch (req) {
 
        case SIOCDELRT:
        switch (req) {
 
        case SIOCDELRT:
@@ -169,7 +179,7 @@ again:
        case SIOCCHGRT:
                rt->rt_flags = new->rt_flags;
                if (rt->rt_refcnt > 0)
        case SIOCCHGRT:
                rt->rt_flags = new->rt_flags;
                if (rt->rt_refcnt > 0)
-                       return (EINUSE);
+                       return (EBUSY);
                if (!equal(&rt->rt_gateway, &new->rt_gateway))
                        goto newneighbor;
                break;
                if (!equal(&rt->rt_gateway, &new->rt_gateway))
                        goto newneighbor;
                break;
index 55e5548..44034b3 100644 (file)
@@ -1,4 +1,4 @@
-/*     route.h 4.1     82/03/27        */
+/*     route.h 4.2     82/03/28        */
 
 /*
  * Structure of kernel resident routing
 
 /*
  * Structure of kernel resident routing
@@ -29,7 +29,7 @@ struct route {
 /*
  * Flags and host/network status.
  */
 /*
  * Flags and host/network status.
  */
-#define        RTS_UP          0x1             /* route useable */
+#define        RTF_UP          0x1             /* route useable */
 #define        RTF_MUNGE       0x2             /* munge packet src address */
 
 #ifdef KERNEL
 #define        RTF_MUNGE       0x2             /* munge packet src address */
 
 #ifdef KERNEL
@@ -41,4 +41,6 @@ struct route {
  */
 #define        RTHASHSIZ       16
 struct mbuf *routehash[RTHASHSIZ];
  */
 #define        RTHASHSIZ       16
 struct mbuf *routehash[RTHASHSIZ];
+
+struct rtentry *reroute();
 #endif
 #endif
index da0b206..3af118b 100644 (file)
@@ -1,4 +1,4 @@
-/*     in_pcb.c        4.21    82/03/23        */
+/*     in_pcb.c        4.22    82/03/28        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -69,7 +69,7 @@ COUNT(IN_PCBATTACH);
                if (sin->sin_family != AF_INET)
                        return (EAFNOSUPPORT);
                if (sin->sin_addr.s_addr &&
                if (sin->sin_family != AF_INET)
                        return (EAFNOSUPPORT);
                if (sin->sin_addr.s_addr &&
-                   if_ifwithaddr(sin->sin_addr) == 0)
+                   if_ifwithaddr((struct sockaddr *)sin) == 0)
                        return (EADDRNOTAVAIL);
                lport = sin->sin_port;
                if (lport) {
                        return (EADDRNOTAVAIL);
                lport = sin->sin_port;
                if (lport) {
@@ -131,6 +131,7 @@ in_pcbconnect(inp, sin)
        struct sockaddr_in *sin;
 {
        struct ifnet *ifp;
        struct sockaddr_in *sin;
 {
        struct ifnet *ifp;
+       struct sockaddr_in *ifaddr;
 
 COUNT(IN_PCBCONNECT);
        if (sin->sin_family != AF_INET)
 
 COUNT(IN_PCBCONNECT);
        if (sin->sin_family != AF_INET)
@@ -138,14 +139,18 @@ COUNT(IN_PCBCONNECT);
        if (sin->sin_addr.s_addr == 0 || sin->sin_port == 0)
                return (EADDRNOTAVAIL);
        if (inp->inp_laddr.s_addr == 0) {
        if (sin->sin_addr.s_addr == 0 || sin->sin_port == 0)
                return (EADDRNOTAVAIL);
        if (inp->inp_laddr.s_addr == 0) {
-               ifp = if_ifonnetof(sin->sin_addr);
-               if (ifp == 0)
-                       ifp = ifnet;
+               ifp = if_ifonnetof(sin->sin_addr.s_net);
+               if (ifp == 0) {
+                       ifp = if_ifwithaf(AF_INET);
+                       if (ifp == 0)
+                               return (EADDRNOTAVAIL);         /* XXX */
+               }
+               ifaddr = (struct sockaddr_in *)&ifp->if_addr;
        }
        if (in_pcblookup(inp->inp_head,
            sin->sin_addr,
            sin->sin_port,
        }
        if (in_pcblookup(inp->inp_head,
            sin->sin_addr,
            sin->sin_port,
-           inp->inp_laddr.s_addr ? inp->inp_laddr : ifp->if_addr,
+           inp->inp_laddr.s_addr ? inp->inp_laddr : ifaddr->sin_addr,
            inp->inp_lport,
            0))
                return (EADDRINUSE);
            inp->inp_lport,
            0))
                return (EADDRINUSE);
@@ -153,7 +158,7 @@ COUNT(IN_PCBCONNECT);
                struct sockaddr_in *sin2 =
                    (struct sockaddr_in *)&inp->inp_socket->so_addr;
 
                struct sockaddr_in *sin2 =
                    (struct sockaddr_in *)&inp->inp_socket->so_addr;
 
-               inp->inp_laddr = ifp->if_addr;
+               inp->inp_laddr = ifaddr->sin_addr;
                sin2->sin_addr = inp->inp_laddr;
        }
        inp->inp_faddr = sin->sin_addr;
                sin2->sin_addr = inp->inp_laddr;
        }
        inp->inp_faddr = sin->sin_addr;
index 1391804..fdfb788 100644 (file)
@@ -1,4 +1,4 @@
-/*     ip_input.c      1.34    82/03/23        */
+/*     ip_input.c      1.35    82/03/28        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
 #include "../net/ip_var.h"
 #include "../net/ip_icmp.h"
 #include "../net/tcp.h"
 #include "../net/ip_var.h"
 #include "../net/ip_icmp.h"
 #include "../net/tcp.h"
+#include "../net/route.h"
+
+#define        IPTTLDEC        5               /* doesn't belong here */
 
 u_char ip_protox[IPPROTO_MAX];
 int    ipqmaxlen = IFQ_MAXLEN;
 
 u_char ip_protox[IPPROTO_MAX];
 int    ipqmaxlen = IFQ_MAXLEN;
+struct ifnet *ifinet;                  /* first inet interface */
 
 /*
  * IP initialization: fill in IP protocol switch table.
 
 /*
  * IP initialization: fill in IP protocol switch table.
@@ -39,10 +43,13 @@ COUNT(IP_INIT);
        ipq.next = ipq.prev = &ipq;
        ip_id = time & 0xffff;
        ipintrq.ifq_maxlen = ipqmaxlen;
        ipq.next = ipq.prev = &ipq;
        ip_id = time & 0xffff;
        ipintrq.ifq_maxlen = ipqmaxlen;
+       ifinet = if_ifwithaf(AF_INET);
 }
 
 u_char ipcksum = 1;
 struct ip *ip_reass();
 }
 
 u_char ipcksum = 1;
 struct ip *ip_reass();
+int    ipforwarding = 0;
+struct sockaddr_in ipaddr = { AF_INET };
 
 /*
  * Ip input routine.  Checksum and byte swap header.  If fragmented
 
 /*
  * Ip input routine.  Checksum and byte swap header.  If fragmented
@@ -121,27 +128,52 @@ next:
         */
        if (hlen > sizeof (struct ip))
                ip_dooptions(ip);
         */
        if (hlen > sizeof (struct ip))
                ip_dooptions(ip);
-       if (ifnet && ip->ip_dst.s_addr != ifnet->if_addr.s_addr &&
-           if_ifwithaddr(ip->ip_dst) == 0) {
-
-               goto bad;
-#ifdef notdef
-               printf("ip->ip_dst %x ip->ip_ttl %x\n",
-                   ip->ip_dst, ip->ip_ttl);
-               if (--ip->ip_ttl == 0) {
+
+       /*
+        * Fast check on the first interface in the list.
+        */
+       if (ifinet) {
+               struct sockaddr_in *sin;
+
+               sin = (struct sockaddr_in *)&ifinet->if_addr;
+               if (sin->sin_addr.s_addr == ip->ip_dst.s_addr)
+                       goto ours;
+       }
+       ipaddr.sin_addr = ip->ip_dst;
+       if (if_ifwithaddr((struct sockaddr *)&ipaddr) == 0) {
+               register struct rtentry *rt;
+
+printf("forward: dst %x ttl %x\n", ip->ip_dst, ip->ip_ttl);
+               if (ipforwarding == 0)
+                       goto bad;
+               if (ip->ip_ttl < IPTTLDEC) {
                        icmp_error(ip, ICMP_TIMXCEED, 0);
                        goto next;
                }
                        icmp_error(ip, ICMP_TIMXCEED, 0);
                        goto next;
                }
+               ip->ip_ttl -= IPTTLDEC;
                mopt = m_get(M_DONTWAIT);
                if (mopt == 0)
                        goto bad;
                ip_stripoptions(ip, mopt);
                mopt = m_get(M_DONTWAIT);
                if (mopt == 0)
                        goto bad;
                ip_stripoptions(ip, mopt);
+
+               /*
+                * Check the routing table in case we should
+                * munge the src address before it gets passed on.
+                */
+               ipaddr.sin_addr = ip->ip_src;
+               rt = reroute(&ipaddr);
+               if (rt && (rt->rt_flags & RTF_MUNGE)) {
+                       struct sockaddr_in *sin;
+
+                       sin = (struct sockaddr_in *)&rt->rt_dst;
+                       ip->ip_src = sin->sin_addr;
+               }
                /* 0 here means no directed broadcast */
                /* 0 here means no directed broadcast */
-               (void) ip_output(m0, mopt, 0);
+               (void) ip_output(m0, mopt, 0, 0);
                goto next;
                goto next;
-#endif
        }
 
        }
 
+ours:
        /*
         * Look for queue of fragments
         * of this datagram.
        /*
         * Look for queue of fragments
         * of this datagram.
@@ -454,7 +486,8 @@ COUNT(IP_DOOPTIONS);
                        if (cp[2] < 4 || cp[2] > optlen - (sizeof (long) - 1))
                                break;
                        sin = (struct in_addr *)(cp + cp[2]);
                        if (cp[2] < 4 || cp[2] > optlen - (sizeof (long) - 1))
                                break;
                        sin = (struct in_addr *)(cp + cp[2]);
-                       ifp = if_ifwithaddr(*sin);
+                       ipaddr.sin_addr = *sin;
+                       ifp = if_ifwithaddr((struct sockaddr *)&ipaddr);
                        if (ifp == 0) {
                                if (opt == IPOPT_SSRR)
                                        goto bad;
                        if (ifp == 0) {
                                if (opt == IPOPT_SSRR)
                                        goto bad;
@@ -465,7 +498,8 @@ COUNT(IP_DOOPTIONS);
                        if (cp[2] > optlen - (sizeof (long) - 1))
                                break;
                        ip->ip_dst = sin[1];
                        if (cp[2] > optlen - (sizeof (long) - 1))
                                break;
                        ip->ip_dst = sin[1];
-                       if (opt == IPOPT_SSRR && if_ifonnetof(ip->ip_dst)==0)
+                       if (opt == IPOPT_SSRR &&
+                           if_ifonnetof(ip->ip_dst.s_net) == 0)
                                goto bad;
                        break;
 
                                goto bad;
                        break;
 
@@ -487,12 +521,14 @@ COUNT(IP_DOOPTIONS);
                        case IPOPT_TS_TSANDADDR:
                                if (ipt->ipt_ptr + 8 > ipt->ipt_len)
                                        goto bad;
                        case IPOPT_TS_TSANDADDR:
                                if (ipt->ipt_ptr + 8 > ipt->ipt_len)
                                        goto bad;
-                               /* stamp with ``first'' interface address */
-                               *sin++ = ifnet->if_addr;
+                               if (ifinet == 0)
+                                       goto bad;       /* ??? */
+                               *sin++ = ((struct sockaddr_in *)&ifinet->if_addr)->sin_addr;
                                break;
 
                        case IPOPT_TS_PRESPEC:
                                break;
 
                        case IPOPT_TS_PRESPEC:
-                               if (if_ifwithaddr(*sin) == 0)
+                               ipaddr.sin_addr = *sin;
+                               if (if_ifwithaddr((struct sockaddr *)&ipaddr) == 0)
                                        continue;
                                if (ipt->ipt_ptr + 8 > ipt->ipt_len)
                                        goto bad;
                                        continue;
                                if (ipt->ipt_ptr + 8 > ipt->ipt_len)
                                        goto bad;
index 68a9d19..ab2763a 100644 (file)
@@ -1,4 +1,4 @@
-/*     ip_output.c     1.26    82/03/15        */
+/*     ip_output.c     1.27    82/03/28        */
 
 #include "../h/param.h"
 #include "../h/mbuf.h"
 
 #include "../h/param.h"
 #include "../h/mbuf.h"
 #include "../net/if.h"
 #include "../net/ip.h"
 #include "../net/ip_var.h"
 #include "../net/if.h"
 #include "../net/ip.h"
 #include "../net/ip_var.h"
+#include "../net/route.h"
 
 
-ip_output(m, opt, allowbroadcast)
+ip_output(m, opt, ro, allowbroadcast)
        struct mbuf *m;
        struct mbuf *opt;
        struct mbuf *m;
        struct mbuf *opt;
+       struct route *ro;
        int allowbroadcast;
 {
        register struct ip *ip = mtod(m, struct ip *);
        register struct ifnet *ifp;
        int len, hlen = sizeof (struct ip), off;
        int allowbroadcast;
 {
        register struct ip *ip = mtod(m, struct ip *);
        register struct ifnet *ifp;
        int len, hlen = sizeof (struct ip), off;
+       struct sockaddr_in tempaddr;    /* temp kludge */
+       struct route iproute;
 
 COUNT(IP_OUTPUT);
        if (opt)                                /* XXX */
 
 COUNT(IP_OUTPUT);
        if (opt)                                /* XXX */
@@ -31,18 +35,37 @@ COUNT(IP_OUTPUT);
        ip->ip_off &= IP_DF;
        ip->ip_id = htons(ip_id++);
 
        ip->ip_off &= IP_DF;
        ip->ip_id = htons(ip_id++);
 
+#ifdef notdef
        /*
         * Find interface for this packet.
         */
        /*
         * Find interface for this packet.
         */
-       ifp = if_ifonnetof(ip->ip_dst);
-       if (ifp == 0) {
-               ifp = if_gatewayfor(ip->ip_dst);
-               if (ifp == 0)
-                       goto bad;
+       if (ro == 0) {
+               ro = &iproute;
+               bzero((caddr_t)ro, sizeof (*ro));
+       }
+       if (ro->ro_rt == 0) {
+               ro->ro_dest.sin_addr = ip->ip_dst;
+               ro->ro_dest.sin_family = AF_INET;
+               route(ro);
        }
        }
-       if (!allowbroadcast && ifp->if_broadaddr.s_addr != 0 &&
-           ifp->if_broadaddr.s_addr == ip->ip_dst.s_addr)
+       if (ro->ro_rt == 0 || (ifp = ro->ro_rt->rt_ifp) == 0)
+               goto bad;
+#else
+       /* interim kludge before routing fallout */
+       ifp = if_ifonnetof(ip->ip_dst.s_net);
+       if (ifp == 0)
                goto bad;
                goto bad;
+       tempaddr.sin_family = AF_INET;
+       tempaddr.sin_addr = ip->ip_dst;
+#endif
+
+       if (!allowbroadcast && (ifp->if_flags & IFF_BROADCAST)) {
+               struct sockaddr_in *sin;
+
+               sin = (struct sockaddr_in *)&ifp->if_broadaddr;
+               if (sin->sin_addr.s_addr == ip->ip_dst.s_addr)
+                       goto bad;
+       }
 
        /*
         * If small enough for interface, can just send directly.
 
        /*
         * If small enough for interface, can just send directly.
@@ -54,7 +77,12 @@ COUNT(IP_OUTPUT);
 #endif
                ip->ip_sum = 0;
                ip->ip_sum = in_cksum(m, hlen);
 #endif
                ip->ip_sum = 0;
                ip->ip_sum = in_cksum(m, hlen);
-               return ((*ifp->if_output)(ifp, m, PF_INET));
+               return ((*ifp->if_output)(ifp, m,
+#ifdef notdef
+                 &ro->ro_rt->rt_dest));
+#else
+                 (struct sockaddr *)&tempaddr));
+#endif
        }
 
        /*
        }
 
        /*
@@ -109,7 +137,12 @@ COUNT(IP_OUTPUT);
 #endif
                mhip->ip_sum = 0;
                mhip->ip_sum = in_cksum(mh, hlen);
 #endif
                mhip->ip_sum = 0;
                mhip->ip_sum = in_cksum(mh, hlen);
-               if ((*ifp->if_output)(ifp, mh, PF_INET) == 0)
+               if ((*ifp->if_output)(ifp, mh,
+#ifdef notdef
+                 &ro->ro_rt->rt_dest) == 0)
+#else
+                 (struct sockaddr *)&tempaddr) == 0)
+#endif
                        goto bad;
        }
        m_freem(m);
                        goto bad;
        }
        m_freem(m);
index f1e9e18..46fedad 100644 (file)
@@ -1,4 +1,4 @@
-/*     raw_ip.c        4.8     82/03/15        */
+/*     raw_ip.c        4.9     82/03/28        */
 
 #include "../h/param.h"
 #include "../h/mbuf.h"
 
 #include "../h/param.h"
 #include "../h/mbuf.h"
@@ -16,9 +16,9 @@
  * Raw interface to IP protocol.
  */
 
  * Raw interface to IP protocol.
  */
 
-static struct sockaddr_in ripdst = { PF_INET };
-static struct sockaddr_in ripsrc = { PF_INET };
-static struct sockproto ripproto = { AF_INET };
+static struct sockaddr_in ripdst = { AF_INET };
+static struct sockaddr_in ripsrc = { AF_INET };
+static struct sockproto ripproto = { PF_INET };
 
 /*
  * Setup generic address and protocol structures
 
 /*
  * Setup generic address and protocol structures
@@ -38,13 +38,6 @@ COUNT(RIP_INPUT);
          (struct sockaddr *)&ripsrc);
 }
 
          (struct sockaddr *)&ripsrc);
 }
 
-/*ARGSUSED*/
-rip_ctlinput(m)
-       struct mbuf *m;
-{
-COUNT(RIP_CTLINPUT);
-}
-
 /*
  * Generate IP header and pass packet to ip_output.
  * Tack on options user may have setup with control call.
 /*
  * Generate IP header and pass packet to ip_output.
  * Tack on options user may have setup with control call.
@@ -85,35 +78,5 @@ COUNT(RIP_OUTPUT);
        ip->ip_src =
                ((struct sockaddr_in *)&so->so_addr)->sin_addr;
        ip->ip_ttl = MAXTTL;
        ip->ip_src =
                ((struct sockaddr_in *)&so->so_addr)->sin_addr;
        ip->ip_ttl = MAXTTL;
-       return (ip_output(m, (struct mbuf *)0, 1));
-}
-
-/*
- * Intercept control operations related to
- * handling of IP options.  Otherwise,
- * just pass things on to the raw_usrreq
- * routine for setup and tear down of
- * raw control block data structures.
- */
-rip_usrreq(so, req, m, addr)
-       struct socket *so;
-       int req;
-       struct mbuf *m;
-       caddr_t addr;
-{
-       register struct rawcb *rp = sotorawcb(so);
-
-COUNT(RAW_USRREQ);
-       if (rp == 0 && req != PRU_ATTACH)
-               return (EINVAL);
-
-       switch (req) {
-       
-       /*
-        * SHOULD HAVE CONTROL TO SET PROTOCOL NUMBER (e.g. GGP)
-        */
-       case PRU_CONTROL:
-               return (EOPNOTSUPP);
-       }
-       return (raw_usrreq(so, req, m, addr));
+       return (ip_output(m, (struct mbuf *)0, 0, 1));
 }
 }
index f75fda2..c156962 100644 (file)
@@ -1,4 +1,4 @@
-/*     tcp_output.c    4.35    82/03/20        */
+/*     tcp_output.c    4.36    82/03/28        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -19,6 +19,7 @@
 #include "../net/tcp_var.h"
 #include "../net/tcpip.h"
 #include "../net/tcp_debug.h"
 #include "../net/tcp_var.h"
 #include "../net/tcpip.h"
 #include "../net/tcp_debug.h"
+#include "../net/route.h"
 #include "../errno.h"
 
 char *tcpstates[]; /* XXX */
 #include "../errno.h"
 
 char *tcpstates[]; /* XXX */
@@ -308,7 +309,7 @@ noopt:
         */
        ((struct ip *)ti)->ip_len = sizeof (struct tcpiphdr) + optlen + len;
        ((struct ip *)ti)->ip_ttl = TCP_TTL;
         */
        ((struct ip *)ti)->ip_len = sizeof (struct tcpiphdr) + optlen + len;
        ((struct ip *)ti)->ip_ttl = TCP_TTL;
-       if (ip_output(m, tp->t_ipopt, 0) == 0)
+       if (ip_output(m, tp->t_ipopt, 0, 0) == 0)
                return (0);
 
        /*
                return (0);
 
        /*
index 22da4cc..697917f 100644 (file)
@@ -1,4 +1,4 @@
-/*     tcp_subr.c      4.19    82/03/24        */
+/*     tcp_subr.c      4.20    82/03/28        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -18,6 +18,7 @@
 #include "../net/tcp_timer.h"
 #include "../net/tcp_var.h"
 #include "../net/tcpip.h"
 #include "../net/tcp_timer.h"
 #include "../net/tcp_var.h"
 #include "../net/tcpip.h"
+#include "../net/route.h"
 #include "../errno.h"
 
 /*
 #include "../errno.h"
 
 /*
@@ -141,7 +142,7 @@ COUNT(TCP_RESPOND);
        ti->ti_sum = in_cksum(m, sizeof (struct tcpiphdr) + tlen);
        ((struct ip *)ti)->ip_len = sizeof (struct tcpiphdr) + tlen;
        ((struct ip *)ti)->ip_ttl = TCP_TTL;
        ti->ti_sum = in_cksum(m, sizeof (struct tcpiphdr) + tlen);
        ((struct ip *)ti)->ip_len = sizeof (struct tcpiphdr) + tlen;
        ((struct ip *)ti)->ip_ttl = TCP_TTL;
-       (void) ip_output(m, (struct mbuf *)0, 0);
+       (void) ip_output(m, (struct mbuf *)0, 0, 0);
 }
 
 /*
 }
 
 /*
index 5b5324d..9a5fb9c 100644 (file)
@@ -1,4 +1,4 @@
-/*     udp_usrreq.c    4.22    82/03/15        */
+/*     udp_usrreq.c    4.23    82/03/28        */
 
 #include "../h/param.h"
 #include "../h/dir.h"
 
 #include "../h/param.h"
 #include "../h/dir.h"
@@ -14,6 +14,7 @@
 #include "../net/ip_var.h"
 #include "../net/udp.h"
 #include "../net/udp_var.h"
 #include "../net/ip_var.h"
 #include "../net/udp.h"
 #include "../net/udp_var.h"
+#include "../net/route.h"
 
 /*
  * UDP protocol implementation.
 
 /*
  * UDP protocol implementation.
@@ -159,7 +160,7 @@ COUNT(UDP_OUTPUT);
        ui->ui_sum = in_cksum(m, sizeof (struct udpiphdr) + len);
        ((struct ip *)ui)->ip_len = sizeof (struct udpiphdr) + len;
        ((struct ip *)ui)->ip_ttl = MAXTTL;
        ui->ui_sum = in_cksum(m, sizeof (struct udpiphdr) + len);
        ((struct ip *)ui)->ip_len = sizeof (struct udpiphdr) + len;
        ((struct ip *)ui)->ip_ttl = MAXTTL;
-       (void) ip_output(m, (struct mbuf *)0,
+       (void) ip_output(m, (struct mbuf *)0, 0,
            inp->inp_socket->so_state & SS_PRIV);
        return;
 bad:
            inp->inp_socket->so_state & SS_PRIV);
        return;
 bad:
index 4d00005..5e1987b 100644 (file)
@@ -1,4 +1,4 @@
-/*     if_dmc.c        4.6     82/03/19        */
+/*     if_dmc.c        4.7     82/03/28        */
 
 #include "dmc.h"
 #if NDMC > 0
 
 #include "dmc.h"
 #if NDMC > 0
@@ -41,7 +41,7 @@ u_short       dmcstd[] = { 0 };
 struct uba_driver dmcdriver =
        { dmcprobe, 0, dmcattach, 0, dmcstd, "dmc", dmcinfo };
 
 struct uba_driver dmcdriver =
        { dmcprobe, 0, dmcattach, 0, dmcstd, "dmc", dmcinfo };
 
-#define        DMC_PF  0xff            /* 8 bits of protocol type in ui_flags */
+#define        DMC_AF  0xff            /* 8 bits of address type in ui_flags */
 #define        DMC_NET 0xff00          /* 8 bits of net number in ui_flags */
 
 /*
 #define        DMC_NET 0xff00          /* 8 bits of net number in ui_flags */
 
 /*
@@ -91,14 +91,14 @@ dmcprobe(reg)
        for (i = 100000; i && (addr->bsel1 & DMC_RUN) == 0; i--)
                ;
        if ((addr->bsel1 & DMC_RUN) == 0)
        for (i = 100000; i && (addr->bsel1 & DMC_RUN) == 0; i--)
                ;
        if ((addr->bsel1 & DMC_RUN) == 0)
-               return(0);
+               return (0);
        addr->bsel1 &= ~DMC_MCLR;
        addr->bsel0 = DMC_RQI|DMC_IEI;
        DELAY(100000);
        addr->bsel1 = DMC_MCLR;
        for (i = 100000; i && (addr->bsel1 & DMC_RUN) == 0; i--)
                ;
        addr->bsel1 &= ~DMC_MCLR;
        addr->bsel0 = DMC_RQI|DMC_IEI;
        DELAY(100000);
        addr->bsel1 = DMC_MCLR;
        for (i = 100000; i && (addr->bsel1 & DMC_RUN) == 0; i--)
                ;
-       return(1);
+       return (1);
 }
 
 /*
 }
 
 /*
@@ -110,14 +110,16 @@ dmcattach(ui)
        register struct uba_device *ui;
 {
        register struct dmc_softc *sc = &dmc_softc[ui->ui_unit];
        register struct uba_device *ui;
 {
        register struct dmc_softc *sc = &dmc_softc[ui->ui_unit];
+       register struct sockaddr_in *sin;
 
        sc->sc_if.if_unit = ui->ui_unit;
        sc->sc_if.if_name = "dmc";
        sc->sc_if.if_mtu = DMCMTU;
        sc->sc_if.if_net = (ui->ui_flags & DMC_NET) >> 8;
        sc->sc_if.if_host[0] = 17;      /* random number */
 
        sc->sc_if.if_unit = ui->ui_unit;
        sc->sc_if.if_name = "dmc";
        sc->sc_if.if_mtu = DMCMTU;
        sc->sc_if.if_net = (ui->ui_flags & DMC_NET) >> 8;
        sc->sc_if.if_host[0] = 17;      /* random number */
-       sc->sc_if.if_addr =
-           if_makeaddr(sc->sc_if.if_net, sc->sc_if.if_host[0]);
+       sin = (struct sockaddr_in *)&sc->sc_if.if_addr;
+       sin->sa_family = AF_INET;
+       sin->sin_addr = if_makeaddr(sc->sc_if.if_net, sc->sc_if.if_host[0]);
        sc->sc_if.if_init = dmcinit;
        sc->sc_if.if_output = dmcoutput;
        sc->sc_if.if_ubareset = dmcreset;
        sc->sc_if.if_init = dmcinit;
        sc->sc_if.if_output = dmcoutput;
        sc->sc_if.if_ubareset = dmcreset;
@@ -161,6 +163,7 @@ dmcinit(unit)
        if (if_ubainit(&sc->sc_ifuba, ui->ui_ubanum, 0,
            (int)btoc(DMCMTU)) == 0) {
                printf("dmc%d: can't initialize\n", unit);
        if (if_ubainit(&sc->sc_ifuba, ui->ui_ubanum, 0,
            (int)btoc(DMCMTU)) == 0) {
                printf("dmc%d: can't initialize\n", unit);
+               sc->sc_if.if_flags &= ~IFF_UP;
                return;
        }
        addr = (struct dmcdevice *)ui->ui_addr;
                return;
        }
        addr = (struct dmcdevice *)ui->ui_addr;
@@ -172,6 +175,7 @@ dmcinit(unit)
        base = sc->sc_ifuba.ifu_r.ifrw_info & 0x3ffff;
        dmcload(sc, DMC_READ, base, ((base>>2)&DMC_XMEM)|DMCMTU);
        printd("  first read queued, addr 0x%x\n", base);
        base = sc->sc_ifuba.ifu_r.ifrw_info & 0x3ffff;
        dmcload(sc, DMC_READ, base, ((base>>2)&DMC_XMEM)|DMCMTU);
        printd("  first read queued, addr 0x%x\n", base);
+       sc->sc_if.if_flags |= IFF_UP;
 }
 
 /*
 }
 
 /*
@@ -311,17 +315,17 @@ dmcxint(unit)
                                sc->sc_ifuba.ifu_r.ifrw_bdp);
                len = arg & DMC_CCOUNT;
                printd("  read done, len %d\n", len);
                                sc->sc_ifuba.ifu_r.ifrw_bdp);
                len = arg & DMC_CCOUNT;
                printd("  read done, len %d\n", len);
-               switch (ui->ui_flags & DMC_PF) {
+               switch (ui->ui_flags & DMC_AF) {
 #ifdef INET
 #ifdef INET
-               case PF_INET:
+               case AF_INET:
                        schednetisr(NETISR_IP);
                        inq = &ipintrq;
                        break;
 #endif
 
                default:
                        schednetisr(NETISR_IP);
                        inq = &ipintrq;
                        break;
 #endif
 
                default:
-                       printf("dmc%d: unknown packet type %d\n", unit,
-                           ui->ui_flags & DMC_NET);
+                       printf("dmc%d: unknown address type %d\n", unit,
+                           ui->ui_flags & DMC_AF);
                        goto setup;
                }
                m = if_rubaget(&sc->sc_ifuba, len, 0);
                        goto setup;
                }
                m = if_rubaget(&sc->sc_ifuba, len, 0);
@@ -380,24 +384,24 @@ setup:
  * Just send the data, header was supplied by
  * upper level protocol routines.
  */
  * Just send the data, header was supplied by
  * upper level protocol routines.
  */
-dmcoutput(ifp, m, pf)
+dmcoutput(ifp, m, dst)
        register struct ifnet *ifp;
        register struct mbuf *m;
        register struct ifnet *ifp;
        register struct mbuf *m;
-       int pf;
+       struct sockaddr *dst;
 {
        struct uba_device *ui = dmcinfo[ifp->if_unit];
        int s;
 
        printd("dmcoutput\n");
 {
        struct uba_device *ui = dmcinfo[ifp->if_unit];
        int s;
 
        printd("dmcoutput\n");
-       if (pf != (ui->ui_flags & DMC_PF)) {
-               printf("dmc%d: protocol %d not supported\n", ifp->if_unit, pf);
-               (void) m_freem(m);
+       if (dst->sa_family != (ui->ui_flags & DMC_AF)) {
+               printf("dmc%d: af%d not supported\n", ifp->if_unit, pf);
+               m_freem(m);
                return (0);
        }
        s = splimp();
        if (IF_QFULL(&ifp->if_snd)) {
                IF_DROP(&ifp->if_snd);
                return (0);
        }
        s = splimp();
        if (IF_QFULL(&ifp->if_snd)) {
                IF_DROP(&ifp->if_snd);
-               (void) m_freem(m);
+               m_freem(m);
                splx(s);
                return (0);
        }
                splx(s);
                return (0);
        }
index 4df49c8..8324b3c 100644 (file)
@@ -1,4 +1,4 @@
-/*     if_en.c 4.43    82/03/19        */
+/*     if_en.c 4.44    82/03/28        */
 
 #include "en.h"
 
 
 #include "en.h"
 
@@ -94,6 +94,7 @@ enattach(ui)
        struct uba_device *ui;
 {
        register struct en_softc *es = &en_softc[ui->ui_unit];
        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;
 COUNT(ENATTACH);
 
        es->es_if.if_unit = ui->ui_unit;
@@ -101,17 +102,14 @@ COUNT(ENATTACH);
        es->es_if.if_mtu = ENMTU;
        es->es_if.if_net = ui->ui_flags;
        es->es_if.if_host[0] =
        es->es_if.if_mtu = ENMTU;
        es->es_if.if_net = ui->ui_flags;
        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_if.if_init = eninit;
        es->es_if.if_output = enoutput;
        es->es_if.if_ubareset = enreset;
@@ -151,6 +149,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);
        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;
                return;
        }
        addr = (struct endevice *)ui->ui_addr;
@@ -165,6 +164,7 @@ eninit(unit)
        addr->en_iwc = -(sizeof (struct en_header) + ENMTU) >> 1;
        addr->en_istat = EN_IEN|EN_GO;
        es->es_oactive = 1;
        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);
 }
        enxint(unit);
        splx(s);
 }
@@ -222,7 +222,8 @@ restart:
         * Have request mapped to UNIBUS for transmission.
         * Purge any stale data from this BDP, and start the otput.
         */
         * 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;
        addr = (struct endevice *)ui->ui_addr;
        addr->en_oba = (int)es->es_ifuba.ifu_w.ifrw_info;
        addr->en_odelay = es->es_delay;
@@ -270,7 +271,7 @@ COUNT(ENXINT);
 /*
  * Collision on ethernet interface.  Do exponential
  * backoff, and retransmit.  If have backed off all
 /*
  * 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;
  */
 encollide(unit)
        int unit;
@@ -337,7 +338,8 @@ COUNT(ENRINT);
        /*
         * Purge BDP; drop if input error indicated.
         */
        /*
         * 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 (es->es_if.if_ierrors % 100 == 0)
        if (addr->en_istat&EN_IERROR) {
                es->es_if.if_ierrors++;
                if (es->es_if.if_ierrors % 100 == 0)
@@ -370,16 +372,18 @@ COUNT(ENRINT);
 
 #ifdef INET
        case ENPUP_IPTYPE:
 
 #ifdef INET
        case ENPUP_IPTYPE:
-               len = htons((u_short)endataaddr(en, off ? off+2 : 0, struct ip *)->ip_len);
+               len = htons((u_short)endataaddr(en,
+                       off ? off + sizeof (u_short) : 0, struct ip *)->ip_len);
                if (off)
                if (off)
-                       len += 2;
+                       len += sizeof (u_short);
                break;
 #endif
 #ifdef PUP
        case ENPUP_PUPTYPE:
                break;
 #endif
 #ifdef PUP
        case ENPUP_PUPTYPE:
-               len = endataaddr(en, off, struct pup_header *)->pup_length;
+               len = endataaddr(en, off ? off + sizeof (u_short) : 0,
+                       struct pup_header *)->pup_length;
                if (off)
                if (off)
-                       len -= 2;
+                       len -= sizeof (u_short);
                break;
 #endif
                
                break;
 #endif
                
@@ -400,8 +404,8 @@ COUNT(ENRINT);
        if (m == 0)
                goto setup;
        if (off) {
        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) {
 
        }
        switch (en->en_type) {
 
@@ -411,6 +415,7 @@ COUNT(ENRINT);
                inq = &ipintrq;
                break;
 #endif
                inq = &ipintrq;
                break;
 #endif
+#ifdef PUP
        case ENPUP_PUPTYPE: {
                struct pup_header *pup = mtod(m, struct pup_header *);
 
        case ENPUP_PUPTYPE: {
                struct pup_header *pup = mtod(m, struct pup_header *);
 
@@ -418,13 +423,15 @@ COUNT(ENRINT);
                pupdst.spup_addr = pup->pup_dport;
                pupsrc.spup_addr = pup->pup_sport;
                raw_input(m, &pupproto, (struct sockaddr *)&pupdst,
                pupdst.spup_addr = pup->pup_dport;
                pupsrc.spup_addr = pup->pup_sport;
                raw_input(m, &pupproto, (struct sockaddr *)&pupdst,
-                (struct sockaddr *)&pupsrc);
+                 (struct sockaddr *)&pupsrc);
                goto setup;
                goto setup;
-               }
        }
        }
+#endif
+       }
+
        if (IF_QFULL(inq)) {
                IF_DROP(inq);
        if (IF_QFULL(inq)) {
                IF_DROP(inq);
-               (void) m_freem(m);
+               m_freem(m);
        } else
                IF_ENQUEUE(inq, m);
 
        } else
                IF_ENQUEUE(inq, m);
 
@@ -443,63 +450,55 @@ setup:
  * Use trailer local net encapsulation if enough data in first
  * packet leaves a multiple of 512 bytes of data in remainder.
  */
  * 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;
        struct ifnet *ifp;
        struct mbuf *m0;
-       int pf;
+       struct sockaddr *dst;
 {
 {
-       int type, dest, s, off;
+       int type, dest, s;
        register struct mbuf *m = m0;
        register struct en_header *en;
        register struct mbuf *m = m0;
        register struct en_header *en;
+       register int off;
 
 COUNT(ENOUTPUT);
 
 COUNT(ENOUTPUT);
-       switch (pf) {
+       switch (dst->sa_family) {
 
 #ifdef INET
 
 #ifdef INET
-       case PF_INET: {
-               register struct ip *ip = mtod(m0, struct ip *);
-
-#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);
                        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;
                }
                        *mtod(m, u_short *) = ENPUP_IPTYPE;
                        goto gottrailertype;
                }
-#endif
                type = ENPUP_IPTYPE;
                off = 0;
                goto gottype;
                type = ENPUP_IPTYPE;
                off = 0;
                goto gottype;
-               }
 #endif
 #ifdef PUP
 #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);
                        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;
                        *mtod(m, u_short *) = ENPUP_PUPTYPE;
                        goto gottrailertype;
                }
                type = ENPUP_PUPTYPE;
                off = 0;
                goto gottype;
-               }
 #endif
 
        default:
 #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);
        }
                m_freem(m0);
                return (0);
        }
index 8b01de6..39b3a64 100644 (file)
@@ -1,4 +1,4 @@
-/*     if_uba.c        4.9     82/02/03        */
+/*     if_uba.c        4.10    82/03/28        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -11,6 +11,7 @@
 #include "../h/cmap.h"
 #include "../h/mtpr.h"
 #include "../h/vmmac.h"
 #include "../h/cmap.h"
 #include "../h/mtpr.h"
 #include "../h/vmmac.h"
+#include "../h/socket.h"
 #include "../net/in.h"
 #include "../net/in_systm.h"
 #include "../net/if.h"
 #include "../net/in.h"
 #include "../net/in_systm.h"
 #include "../net/if.h"