checkpoint at first working tp4 connection; before gnodes
authorKeith Sklower <sklower@ucbvax.Berkeley.EDU>
Sun, 23 Apr 1989 03:11:33 +0000 (19:11 -0800)
committerKeith Sklower <sklower@ucbvax.Berkeley.EDU>
Sun, 23 Apr 1989 03:11:33 +0000 (19:11 -0800)
SCCS-vsn: sys/net/route.h 7.6
SCCS-vsn: sys/net/route.c 7.9
SCCS-vsn: sys/net/raw_cb.h 7.5
SCCS-vsn: sys/net/raw_cb.c 7.8
SCCS-vsn: sys/net/netisr.h 7.5
SCCS-vsn: sys/net/raw_usrreq.c 7.5
SCCS-vsn: sys/net/if_loop.c 7.6
SCCS-vsn: sys/net/if.h 7.5
SCCS-vsn: sys/net/if_sl.c 7.11
SCCS-vsn: sys/net/if_ethersubr.c 7.2
SCCS-vsn: sys/net/radix.c 7.3
SCCS-vsn: sys/net/radix.h 7.3
SCCS-vsn: sys/net/rtsock.c 7.2

13 files changed:
usr/src/sys/net/if.h
usr/src/sys/net/if_ethersubr.c
usr/src/sys/net/if_loop.c
usr/src/sys/net/if_sl.c
usr/src/sys/net/netisr.h
usr/src/sys/net/radix.c
usr/src/sys/net/radix.h
usr/src/sys/net/raw_cb.c
usr/src/sys/net/raw_cb.h
usr/src/sys/net/raw_usrreq.c
usr/src/sys/net/route.c
usr/src/sys/net/route.h
usr/src/sys/net/rtsock.c

index 19e5b6f..1bcdb8e 100644 (file)
@@ -14,7 +14,7 @@
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- *     @(#)if.h        7.4 (Berkeley) %G%
+ *     @(#)if.h        7.5 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -78,6 +78,9 @@ struct ifnet {
        int     if_collisions;          /* collisions on csma interfaces */
 /* end statistics */
        struct  ifnet *if_next;
        int     if_collisions;          /* collisions on csma interfaces */
 /* end statistics */
        struct  ifnet *if_next;
+       u_char  if_type;                /* ethernet, tokenring, etc */
+       u_char  if_addrlen;             /* media address length */
+       u_char  if_hdrlen;              /* media header length */
 };
 
 #define        IFF_UP          0x1             /* interface is up */
 };
 
 #define        IFF_UP          0x1             /* interface is up */
@@ -141,17 +144,13 @@ struct ifnet {
  * together so all addresses for an interface can be located.
  */
 struct ifaddr {
  * together so all addresses for an interface can be located.
  */
 struct ifaddr {
-       struct  sockaddr ifa_addr;      /* address of interface */
-       union {
-               struct  sockaddr ifu_broadaddr;
-               struct  sockaddr ifu_dstaddr;
-       } ifa_ifu;
-#define        ifa_broadaddr   ifa_ifu.ifu_broadaddr   /* broadcast address */
-#define        ifa_dstaddr     ifa_ifu.ifu_dstaddr     /* other end of p-to-p link */
+       struct  sockaddr *ifa_addr;     /* address of interface */
+       struct  sockaddr *ifa_dstaddr;  /* other end of p-to-p link */
+#define        ifa_broadaddr   ifa_dstaddr     /* broadcast address interface */
+       struct  sockaddr *ifa_netmask;  /* used to determine subnet */
        struct  ifnet *ifa_ifp;         /* back-pointer to interface */
        struct  ifaddr *ifa_next;       /* next address for interface */
 };
        struct  ifnet *ifa_ifp;         /* back-pointer to interface */
        struct  ifaddr *ifa_next;       /* next address for interface */
 };
-
 /*
  * Interface request structure used for socket
  * ioctl's.  All interface ioctl's must have parameter
 /*
  * Interface request structure used for socket
  * ioctl's.  All interface ioctl's must have parameter
@@ -177,6 +176,13 @@ struct     ifreq {
 #define        ifr_data        ifr_ifru.ifru_data      /* for use by interface */
 };
 
 #define        ifr_data        ifr_ifru.ifru_data      /* for use by interface */
 };
 
+struct ifaliasreq {
+       char    ifra_name[IFNAMSIZ];            /* if name, e.g. "en0" */
+       struct  sockaddr ifra_addr;
+       struct  sockaddr ifra_broadaddr;
+       struct  sockaddr ifra_mask;
+};
+
 /*
  * Structure used in SIOCGIFCONF request.
  * Used to retrieve interface configuration
 /*
  * Structure used in SIOCGIFCONF request.
  * Used to retrieve interface configuration
index 7e14d06..9aec93a 100644 (file)
@@ -14,7 +14,7 @@
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- *     @(#)if_ethersubr.c      7.1 (Berkeley) %G%
+ *     @(#)if_ethersubr.c      7.2 (Berkeley) %G%
  */
 
 #include "param.h"
  */
 
 #include "param.h"
 #include "../netns/ns_if.h"
 #endif
 
 #include "../netns/ns_if.h"
 #endif
 
+#ifdef ISO
+#include "../netiso/argo_debug.h"
+#include "../netiso/iso.h"
+#include "../netiso/iso_var.h"
+#endif
+
 u_char etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 extern struct ifnet loif;
 
 u_char etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 extern struct ifnet loif;
 
@@ -55,7 +61,7 @@ extern        struct ifnet loif;
  * packet leaves a multiple of 512 bytes of data in remainder.
  * Assumes that ifp is actually pointer to arpcom structure.
  */
  * packet leaves a multiple of 512 bytes of data in remainder.
  * Assumes that ifp is actually pointer to arpcom structure.
  */
-enoutput(ifp, m0, dst)
+ether_output(ifp, m0, dst)
        register struct ifnet *ifp;
        struct mbuf *m0;
        struct sockaddr *dst;
        register struct ifnet *ifp;
        struct mbuf *m0;
        struct sockaddr *dst;
@@ -74,6 +80,9 @@ enoutput(ifp, m0, dst)
                error = ENETDOWN;
                goto bad;
        }
                error = ENETDOWN;
                goto bad;
        }
+       if (ifp->if_flags & IFF_SIMPLEX && dst->sa_family != AF_UNSPEC &&
+           !bcmp((caddr_t)edst, (caddr_t)etherbroadcastaddr, sizeof (edst)))
+               mcopy = m_copy(m, 0, (int)M_COPYALL);
        switch (dst->sa_family) {
 
 #ifdef INET
        switch (dst->sa_family) {
 
 #ifdef INET
@@ -81,6 +90,8 @@ enoutput(ifp, m0, dst)
                idst = ((struct sockaddr_in *)dst)->sin_addr;
                if (!arpresolve(ac, m, &idst, edst, &usetrailers))
                        return (0);     /* if not yet resolved */
                idst = ((struct sockaddr_in *)dst)->sin_addr;
                if (!arpresolve(ac, m, &idst, edst, &usetrailers))
                        return (0);     /* if not yet resolved */
+               if ((ifp->if_flags & IFF_SIMPLEX) && (*edst & 1))
+                   mcopy = m_copy(m, 0, (int)M_COPYALL);
                off = m->m_pkthdr.len - m->m_len;
                if (usetrailers && off > 0 && (off & 0x1ff) == 0 &&
                    (m->m_flags & M_EXT) == 0 &&
                off = m->m_pkthdr.len - m->m_len;
                if (usetrailers && off > 0 && (off & 0x1ff) == 0 &&
                    (m->m_flags & M_EXT) == 0 &&
@@ -102,27 +113,27 @@ enoutput(ifp, m0, dst)
                        return(looutput(&loif, m, dst));
                bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host),
                    (caddr_t)edst, sizeof (edst));
                        return(looutput(&loif, m, dst));
                bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host),
                    (caddr_t)edst, sizeof (edst));
+               if ((ifp->if_flags & IFF_SIMPLEX) && (*edst & 1))
+                   mcopy = m_copy(m, 0, (int)M_COPYALL);
                goto gottype;
 #endif
 #ifdef ISO
        case AF_ISO: {
                goto gottype;
 #endif
 #ifdef ISO
        case AF_ISO: {
+               int     len;
                int     ret;
                int     ret;
-               ret = clnp_arpresolve(&us->us_ac.ac_if, m, dst, edst);
-               struct llc *l;
-               if (ret <= 0) {
-                       if (ret == -1) {
-                       /* not resolved */
-                               IFDEBUG(D_ETHER)
-                                       printf("unoutput: clnp packet dropped\n");
-                               ENDDEBUG
-                       }
-                       return(0);
+               struct  llc *l;
+
+               if ((ret = iso_tryloopback(m, (struct sockaddr_iso *)dst)) >= 0)
+                       return (ret);
+               ret = iso_snparesolve(ifp, (struct sockaddr_iso *)dst,
+                                       (char *)edst, &len);
+               if (ret > 0) {
+                       m_freem(m); /* Not Resolved */
+                       return(ret);
                }
                M_PREPEND(m, 3, M_DONTWAIT);
                }
                M_PREPEND(m, 3, M_DONTWAIT);
-               if (m == NULL) {
-                       m_freem(mm);
+               if (m == NULL)
                        return(0);
                        return(0);
-               }
                type = m->m_pkthdr.len;
                l = mtod(m, struct llc *);
                l->llc_dsap = l->llc_ssap = LLC_ISO_LSAP;
                type = m->m_pkthdr.len;
                l = mtod(m, struct llc *);
                l->llc_dsap = l->llc_ssap = LLC_ISO_LSAP;
@@ -136,7 +147,6 @@ enoutput(ifp, m0, dst)
                ENDDEBUG
                } goto gottype;
 #endif ISO
                ENDDEBUG
                } goto gottype;
 #endif ISO
-
        case AF_UNSPEC:
                eh = (struct ether_header *)dst->sa_data;
                bcopy((caddr_t)eh->ether_dhost, (caddr_t)edst, sizeof (edst));
        case AF_UNSPEC:
                eh = (struct ether_header *)dst->sa_data;
                bcopy((caddr_t)eh->ether_dhost, (caddr_t)edst, sizeof (edst));
@@ -178,10 +188,6 @@ gottype:
        bcopy((caddr_t)edst, (caddr_t)eh->ether_dhost, sizeof (edst));
        bcopy((caddr_t)ac->ac_enaddr, (caddr_t)eh->ether_shost,
            sizeof(eh->ether_shost));
        bcopy((caddr_t)edst, (caddr_t)eh->ether_dhost, sizeof (edst));
        bcopy((caddr_t)ac->ac_enaddr, (caddr_t)eh->ether_shost,
            sizeof(eh->ether_shost));
-       if (ifp->if_flags & IFF_SIMPLEX && dst->sa_family != AF_UNSPEC &&
-           !bcmp((caddr_t)edst, (caddr_t)etherbroadcastaddr, sizeof (edst)))
-               mcopy = m_copy(m, 0, (int)M_COPYALL);
-
        /*
         * Queue message on interface, and start output if interface
         * not yet active.
        /*
         * Queue message on interface, and start output if interface
         * not yet active.
@@ -214,7 +220,7 @@ bad:
  * has trailing header; we still have to drop
  * the type and length which are at the front of any trailer data.
  */
  * has trailing header; we still have to drop
  * the type and length which are at the front of any trailer data.
  */
-en_doproto(ifp, eh, m)
+ether_input(ifp, eh, m)
        struct ifnet *ifp;
        register struct ether_header *eh;
        struct mbuf *m;
        struct ifnet *ifp;
        register struct ether_header *eh;
        struct mbuf *m;
@@ -248,7 +254,7 @@ en_doproto(ifp, eh, m)
 
 #endif
        default:
 
 #endif
        default:
-               if (eh->ether_type > 1500)
+               if (eh->ether_type > ETHERMTU)
                        goto dropanyway;
                l = mtod(m, struct llc *);
                switch (l->llc_control) {
                        goto dropanyway;
                l = mtod(m, struct llc *);
                switch (l->llc_control) {
@@ -258,20 +264,26 @@ en_doproto(ifp, eh, m)
                        (l->llc_ssap == LLC_ISO_LSAP)) {
 #ifdef ISO
                                /* LSAP for ISO */
                        (l->llc_ssap == LLC_ISO_LSAP)) {
 #ifdef ISO
                                /* LSAP for ISO */
-                       m->m_data += 3;
-                       m->m_len -= 3;
-                       if (m->m_flags & M_PKTHDR)
-                               m->m_pkthdr.len -= 3;
-                       DEBUGF(undebug & 0x2, printf("clnp packet\n");)
-                       schednetisr(NETISR_CLNP);
+                       M_PREPEND(m, sizeof *eh, M_DONTWAIT);
+                       if (m == 0)
+                               return;
+                       *mtod(m, struct ether_header *) = *eh;
+                       IFDEBUG(D_ETHER)
+                           printf("clnp packet");
+                       ENDDEBUG
+                       schednetisr(NETISR_ISO);
                        inq = &clnlintrq;
                        if (IF_QFULL(inq)){
                        inq = &clnlintrq;
                        if (IF_QFULL(inq)){
-                               DEBUGF(undebug & 0x2, printf(" qfull\n");)
+                               IFDEBUG(D_ETHER)
+                                   printf(" qfull\n");
+                               ENDDEBUG
                                IF_DROP(inq);
                                m_freem(m);
                        } else {
                                IF_ENQUEUE(inq, m);
                                IF_DROP(inq);
                                m_freem(m);
                        } else {
                                IF_ENQUEUE(inq, m);
-                               DEBUGF(undebug & 0x2, printf(" queued\n");)
+                               IFDEBUG(D_ETHER)
+                                   printf(" queued\n");
+                               ENDDEBUG
                        }
                        return;
 #endif ISO
                        }
                        return;
 #endif ISO
@@ -295,7 +307,11 @@ en_doproto(ifp, eh, m)
                    u_char c = l->llc_dsap;
                    l->llc_dsap = l->llc_ssap;
                    l->llc_ssap = c;
                    u_char c = l->llc_dsap;
                    l->llc_dsap = l->llc_ssap;
                    l->llc_ssap = c;
+                   if (m->m_flags & (M_BCAST | M_MCAST))
+                       bcopy((caddr_t)ac->ac_enaddr,
+                             (caddr_t)eh->ether_dhost, 6);
                    sa.sa_family = AF_UNSPEC;
                    sa.sa_family = AF_UNSPEC;
+                   sa.sa_len = sizeof(sa);
                    eh2 = (struct ether_header *)sa.sa_data;
                    for (i = 0; i < 6; i++) {
                        eh2->ether_shost[i] = c = eh->ether_dhost[i];
                    eh2 = (struct ether_header *)sa.sa_data;
                    for (i = 0; i < 6; i++) {
                        eh2->ether_shost[i] = c = eh->ether_dhost[i];
@@ -325,6 +341,7 @@ en_doproto(ifp, eh, m)
 /*
  * Convert Ethernet address to printable (loggable) representation.
  */
 /*
  * Convert Ethernet address to printable (loggable) representation.
  */
+static char digits[] = "0123456789abcdef";
 char *
 ether_sprintf(ap)
        register u_char *ap;
 char *
 ether_sprintf(ap)
        register u_char *ap;
@@ -332,7 +349,6 @@ ether_sprintf(ap)
        register i;
        static char etherbuf[18];
        register char *cp = etherbuf;
        register i;
        static char etherbuf[18];
        register char *cp = etherbuf;
-       static char digits[] = "0123456789abcdef";
 
        for (i = 0; i < 6; i++) {
                *cp++ = digits[*ap >> 4];
 
        for (i = 0; i < 6; i++) {
                *cp++ = digits[*ap >> 4];
index dca1d80..b488b99 100644 (file)
@@ -14,7 +14,7 @@
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- *     @(#)if_loop.c   7.5 (Berkeley) %G%
+ *     @(#)if_loop.c   7.6 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -29,6 +29,7 @@
 #include "ioctl.h"
 
 #include "../net/if.h"
 #include "ioctl.h"
 
 #include "../net/if.h"
+#include "../net/iftypes.h"
 #include "../net/netisr.h"
 #include "../net/route.h"
 
 #include "../net/netisr.h"
 #include "../net/route.h"
 
 #include "../netns/ns_if.h"
 #endif
 
 #include "../netns/ns_if.h"
 #endif
 
+#ifdef ISO
+#include "../netiso/iso.h"
+#include "../netiso/iso_var.h"
+#endif
+
 #define        LOMTU   (1024+512)
 
 struct ifnet loif;
 #define        LOMTU   (1024+512)
 
 struct ifnet loif;
@@ -60,6 +66,9 @@ loattach()
        ifp->if_flags = IFF_LOOPBACK;
        ifp->if_ioctl = loioctl;
        ifp->if_output = looutput;
        ifp->if_flags = IFF_LOOPBACK;
        ifp->if_ioctl = loioctl;
        ifp->if_output = looutput;
+       ifp->if_type = IFT_LOOP;
+       ifp->if_hdrlen = 0;
+       ifp->if_addrlen = 0;
        if_attach(ifp);
 }
 
        if_attach(ifp);
 }
 
@@ -78,13 +87,13 @@ looutput(ifp, m, dst)
        m->m_pkthdr.rcvif = ifp;
 
 {struct mbuf *mm; int mlen = 0;
        m->m_pkthdr.rcvif = ifp;
 
 {struct mbuf *mm; int mlen = 0;
-for (mm = m; m; m = m->m_next) /* XXX debugging code -- sklwoer */
+for (mm = m; m; m = m->m_next) /* XXX debugging code -- sklower */
     mlen += m->m_len;
 m = mm;
 if (mlen != m->m_pkthdr.len) {
        if (Loop_Sanity)
                m_freem(Loop_Sanity);
     mlen += m->m_len;
 m = mm;
 if (mlen != m->m_pkthdr.len) {
        if (Loop_Sanity)
                m_freem(Loop_Sanity);
-       Loop_Sanity = m_copy(m, 0, M_COPYALL);
+       Loop_Sanity = m_copy(m, 0, (int)M_COPYALL);
 }
 }
 
 }
 }
 
@@ -117,6 +126,19 @@ if (mlen != m->m_pkthdr.len) {
                IF_ENQUEUE(ifq, m);
                schednetisr(NETISR_NS);
                break;
                IF_ENQUEUE(ifq, m);
                schednetisr(NETISR_NS);
                break;
+#endif
+#ifdef ISO
+       case AF_ISO:
+               ifq = &clnlintrq;
+               if (IF_QFULL(ifq)) {
+                       IF_DROP(ifq);
+                       m_freem(m);
+                       splx(s);
+                       return (ENOBUFS);
+               }
+               IF_ENQUEUE(ifq, m);
+               schednetisr(NETISR_ISO);
+               break;
 #endif
        default:
                splx(s);
 #endif
        default:
                splx(s);
index 019cf2f..88ede68 100644 (file)
@@ -14,7 +14,7 @@
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- *     @(#)if_sl.c     7.6.1.2 (Berkeley) %G%
+ *     @(#)if_sl.c     7.11 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -388,10 +388,11 @@ sl_btom(sc, len, ifp)
        cp = sc->sc_buf + sizeof(struct ifnet *);
        mp = &top;
        while (len > 0) {
        cp = sc->sc_buf + sizeof(struct ifnet *);
        mp = &top;
        while (len > 0) {
-               if (top == NULL)
+               if (top == NULL) {
                        MGETHDR(m, M_DONTWAIT, MT_DATA);
                        MGETHDR(m, M_DONTWAIT, MT_DATA);
-               else
+               } else {
                        MGET(m, M_DONTWAIT, MT_DATA);
                        MGET(m, M_DONTWAIT, MT_DATA);
+               }
                if ((*mp = m) == NULL) {
                        m_freem(top);
                        return (NULL);
                if ((*mp = m) == NULL) {
                        m_freem(top);
                        return (NULL);
@@ -399,7 +400,7 @@ sl_btom(sc, len, ifp)
                if (top == NULL) {
                        m->m_pkthdr.rcvif = ifp;
                        m->m_pkthdr.len = len;
                if (top == NULL) {
                        m->m_pkthdr.rcvif = ifp;
                        m->m_pkthdr.len = len;
-                       m->m_len = MPLEN;
+                       m->m_len = MHLEN;
                } else
                        m->m_len = MLEN;
                /*
                } else
                        m->m_len = MLEN;
                /*
@@ -517,14 +518,14 @@ slioctl(ifp, cmd, data)
        switch (cmd) {
 
        case SIOCSIFADDR:
        switch (cmd) {
 
        case SIOCSIFADDR:
-               if (ifa->ifa_addr.sa_family == AF_INET)
+               if (ifa->ifa_addr->sa_family == AF_INET)
                        ifp->if_flags |= IFF_UP;
                else
                        error = EAFNOSUPPORT;
                break;
 
        case SIOCSIFDSTADDR:
                        ifp->if_flags |= IFF_UP;
                else
                        error = EAFNOSUPPORT;
                break;
 
        case SIOCSIFDSTADDR:
-               if (ifa->ifa_addr.sa_family != AF_INET)
+               if (ifa->ifa_addr->sa_family != AF_INET)
                        error = EAFNOSUPPORT;
                break;
 
                        error = EAFNOSUPPORT;
                break;
 
index ca19510..1aeafb6 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 1980, 1986 Regents of the University of California.
+ * Copyright (c) 1980, 1986, 1989 Regents of the University of California.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted
@@ -14,7 +14,7 @@
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- *     @(#)netisr.h    7.4 (Berkeley) %G%
+ *     @(#)netisr.h    7.5 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -39,6 +39,7 @@
 #define        NETISR_IP       2               /* same as AF_INET */
 #define        NETISR_IMP      3               /* same as AF_IMPLINK */
 #define        NETISR_NS       6               /* same as AF_NS */
 #define        NETISR_IP       2               /* same as AF_INET */
 #define        NETISR_IMP      3               /* same as AF_IMPLINK */
 #define        NETISR_NS       6               /* same as AF_NS */
+#define        NETISR_ISO      7               /* same as AF_ISO */
 
 #define        schednetisr(anisr)      { netisr |= 1<<(anisr); setsoftnet(); }
 
 
 #define        schednetisr(anisr)      { netisr |= 1<<(anisr); setsoftnet(); }
 
index 05f9bb9..da7ad1e 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 1982, 1988 Regents of the University of California.
+ * Copyright (c) 1988, 1989  Regents of the University of California.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted
@@ -14,7 +14,7 @@
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- *     @(#)radix.c     7.2 (Berkeley) %G%
+ *     @(#)radix.c     7.3 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -73,6 +73,25 @@ rn_search(v, head)
        return x;
 };
 
        return x;
 };
 
+#ifdef notdef
+struct radix_node *
+rn_search_m(v, head, m)
+       struct radix_node *head;
+       register caddr_t v, m;
+{
+       register struct radix_node *x;
+
+       for (x = head; x->rn_b >= 0;) {
+               if ((x->rn_bmask & m[x->rn_off]) &&
+                   (x->rn_bmask & v[x->rn_off]))
+                       x = x->rn_r;
+               else
+                       x = x->rn_l;
+       }
+       return x;
+};
+#endif
+
 
 static int gotOddMasks;
 static char maskedKey[MAXKEYLEN];
 
 static int gotOddMasks;
 static char maskedKey[MAXKEYLEN];
@@ -105,6 +124,12 @@ rn_match(v, head)
        for (; cp < cplim; cp++, cp2++)
                if (*cp != *cp2)
                        goto on1;
        for (; cp < cplim; cp++, cp2++)
                if (*cp != *cp2)
                        goto on1;
+       /*
+        * This extra grot is in case we are explicitly asked
+        * to look up the default.  Ugh!
+        */
+       if ((t->rn_flags & RNF_ROOT) && t->rn_dupedkey)
+               t = t->rn_dupedkey;
        return t;
 on1:
        matched_off = cp - v;
        return t;
 on1:
        matched_off = cp - v;
@@ -130,6 +155,12 @@ on1:
                register struct radix_mask *m;
                t = t->rn_p;
                if (m = t->rn_mklist) {
                register struct radix_mask *m;
                t = t->rn_p;
                if (m = t->rn_mklist) {
+                       /*
+                        * After doing measurements here, it may
+                        * turn out to be faster to open code
+                        * rn_search_m here instead of always
+                        * copying and masking.
+                        */
                        off = min(t->rn_off, matched_off);
                        mstart = maskedKey + off;
                        do {
                        off = min(t->rn_off, matched_off);
                        mstart = maskedKey + off;
                        do {
@@ -310,7 +341,7 @@ rn_addroute(v, netmask, head, treenodes)
                        return (0);
                Bzero(x, MAXKEYLEN + 2 * sizeof (*x));
                cp = (caddr_t)(x + 2);
                        return (0);
                Bzero(x, MAXKEYLEN + 2 * sizeof (*x));
                cp = (caddr_t)(x + 2);
-               bcopy(netmask, cp, mlen);
+               Bcopy(netmask, cp, mlen);
                netmask = cp;
                x = rn_insert(netmask, rn_maskhead, &maskduplicated, x);
                /*
                netmask = cp;
                x = rn_insert(netmask, rn_maskhead, &maskduplicated, x);
                /*
index 42a1a2f..7f38e89 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 1988 Regents of the University of California.
+ * Copyright (c) 1988, 1989 Regents of the University of California.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted
@@ -14,7 +14,7 @@
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- *     @(#)radix.h     7.2 (Berkeley) %G%
+ *     @(#)radix.h     7.3 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -89,16 +89,14 @@ extern struct radix_node_head {
 
 
 #ifndef KERNEL
 
 
 #ifndef KERNEL
-char *malloc();
 #define Bcmp(a, b, n) bcmp(((char *)(a)), ((char *)(b)), (n))
 #define Bzero(p, n) bzero((char *)(p), (int)(n));
 #define R_Malloc(p, t, n) (p = (t) malloc((unsigned int)(n)))
 #define Free(p) free((char *)p);
 #define Bcmp(a, b, n) bcmp(((char *)(a)), ((char *)(b)), (n))
 #define Bzero(p, n) bzero((char *)(p), (int)(n));
 #define R_Malloc(p, t, n) (p = (t) malloc((unsigned int)(n)))
 #define Free(p) free((char *)p);
-#define min(a, b) ((a) < (b) ? (a) : (b))
 #else
 #else
-#define Bcmp(a, b, n) bcmp(((caddr_t)(a)), ((caddr_t)(b)), (n))
-#define Bcopy(a, b, n) bcopy(((caddr_t)(a)), ((caddr_t)(b)), (n))
-#define Bzero(p, n) bzero((caddr_t)(p), (int)(n));
-#define R_Malloc(p, t, n) (p = (t) malloc((n), M_RTABLE, M_DONTWAIT))
-#define Free(p) free((caddr_t)p);
-#endif KERNEL
+#define Bcmp(a, b, n) bcmp(((caddr_t)(a)), ((caddr_t)(b)), (unsigned)(n))
+#define Bcopy(a, b, n) bcopy(((caddr_t)(a)), ((caddr_t)(b)), (unsigned)(n))
+#define Bzero(p, n) bzero((caddr_t)(p), (unsigned)(n));
+#define R_Malloc(p, t, n) (p = (t) malloc((unsigned long)(n), M_RTABLE, M_DONTWAIT))
+#define Free(p) free((caddr_t)p, M_RTABLE);
+#endif /*KERNEL*/
index e1ad8ec..739120d 100644 (file)
@@ -14,7 +14,7 @@
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- *     @(#)raw_cb.c    7.7 (Berkeley) %G%
+ *     @(#)raw_cb.c    7.8 (Berkeley) %G%
  */
 
 #include "param.h"
  */
 
 #include "param.h"
@@ -53,20 +53,20 @@ raw_attach(so, proto)
        register struct socket *so;
        int proto;
 {
        register struct socket *so;
        int proto;
 {
-       struct mbuf *m;
-       register struct rawcb *rp;
+       register struct rawcb *rp = sotorawcb(so);
 
 
-       m = m_getclr(M_DONTWAIT, MT_PCB);
-       if (m == 0)
+       /*
+        * It is assumed that raw_attach is called
+        * after space has been allocated for the
+        * rawcb.
+        */
+       if (rp == 0)
                return (ENOBUFS);
        if (sbreserve(&so->so_snd, raw_sendspace) == 0)
                goto bad;
        if (sbreserve(&so->so_rcv, raw_recvspace) == 0)
                goto bad2;
                return (ENOBUFS);
        if (sbreserve(&so->so_snd, raw_sendspace) == 0)
                goto bad;
        if (sbreserve(&so->so_rcv, raw_recvspace) == 0)
                goto bad2;
-       rp = mtod(m, struct rawcb *);
        rp->rcb_socket = so;
        rp->rcb_socket = so;
-       so->so_pcb = (caddr_t)rp;
-       rp->rcb_pcb = 0;
        rp->rcb_proto.sp_family = so->so_proto->pr_domain->dom_family;
        rp->rcb_proto.sp_protocol = proto;
        insque(rp, &rawcb);
        rp->rcb_proto.sp_family = so->so_proto->pr_domain->dom_family;
        rp->rcb_proto.sp_protocol = proto;
        insque(rp, &rawcb);
@@ -74,7 +74,6 @@ raw_attach(so, proto)
 bad2:
        sbrelease(&so->so_snd);
 bad:
 bad2:
        sbrelease(&so->so_snd);
 bad:
-       (void) m_free(m);
        return (ENOBUFS);
 }
 
        return (ENOBUFS);
 }
 
@@ -87,14 +86,15 @@ raw_detach(rp)
 {
        struct socket *so = rp->rcb_socket;
 
 {
        struct socket *so = rp->rcb_socket;
 
-       if (rp->rcb_route.ro_rt)
-               rtfree(rp->rcb_route.ro_rt);
        so->so_pcb = 0;
        sofree(so);
        remque(rp);
        so->so_pcb = 0;
        sofree(so);
        remque(rp);
-       if (rp->rcb_options)
-               m_freem(rp->rcb_options);
-       m_freem(dtom(rp));
+#ifdef notdef
+       if (rp->rcb_laddr)
+               m_freem(dtom(rp->rcb_laddr));
+       rp->rcb_laddr = 0;
+#endif
+       free((caddr_t)(rp), M_PCB);
 }
 
 /*
 }
 
 /*
@@ -104,11 +104,16 @@ raw_disconnect(rp)
        struct rawcb *rp;
 {
 
        struct rawcb *rp;
 {
 
-       rp->rcb_flags &= ~RAW_FADDR;
+#ifdef notdef
+       if (rp->rcb_faddr)
+               m_freem(dtom(rp->rcb_faddr));
+       rp->rcb_faddr = 0;
+#endif
        if (rp->rcb_socket->so_state & SS_NOFDREF)
                raw_detach(rp);
 }
 
        if (rp->rcb_socket->so_state & SS_NOFDREF)
                raw_detach(rp);
 }
 
+#ifdef notdef
 raw_bind(so, nam)
        register struct socket *so;
        struct mbuf *nam;
 raw_bind(so, nam)
        register struct socket *so;
        struct mbuf *nam;
@@ -118,43 +123,9 @@ raw_bind(so, nam)
 
        if (ifnet == 0)
                return (EADDRNOTAVAIL);
 
        if (ifnet == 0)
                return (EADDRNOTAVAIL);
-/* BEGIN DUBIOUS */
-       /*
-        * Should we verify address not already in use?
-        * Some say yes, others no.
-        */
-       switch (addr->sa_family) {
-
-#ifdef INET
-       case AF_IMPLINK:
-       case AF_INET: {
-               if (((struct sockaddr_in *)addr)->sin_addr.s_addr &&
-                   ifa_ifwithaddr(addr) == 0)
-                       return (EADDRNOTAVAIL);
-               break;
-       }
-#endif
-
-       default:
-               return (EAFNOSUPPORT);
-       }
-/* END DUBIOUS */
        rp = sotorawcb(so);
        rp = sotorawcb(so);
-       bcopy((caddr_t)addr, (caddr_t)&rp->rcb_laddr, sizeof (*addr));
-       rp->rcb_flags |= RAW_LADDR;
+       nam = m_copym(nam, 0, M_COPYALL, M_WAITOK);
+       rp->rcb_laddr = mtod(nam, struct sockaddr *);
        return (0);
 }
        return (0);
 }
-
-/*
- * Associate a peer's address with a
- * raw connection block.
- */
-raw_connaddr(rp, nam)
-       struct rawcb *rp;
-       struct mbuf *nam;
-{
-       struct sockaddr *addr = mtod(nam, struct sockaddr *);
-
-       bcopy((caddr_t)addr, (caddr_t)&rp->rcb_faddr, sizeof(*addr));
-       rp->rcb_flags |= RAW_FADDR;
-}
+#endif
index 40ba198..5e0dfbc 100644 (file)
@@ -14,7 +14,7 @@
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- *     @(#)raw_cb.h    7.4 (Berkeley) %G%
+ *     @(#)raw_cb.h    7.5 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -25,23 +25,11 @@ struct rawcb {
        struct  rawcb *rcb_next;        /* doubly linked list */
        struct  rawcb *rcb_prev;
        struct  socket *rcb_socket;     /* back pointer to socket */
        struct  rawcb *rcb_next;        /* doubly linked list */
        struct  rawcb *rcb_prev;
        struct  socket *rcb_socket;     /* back pointer to socket */
-       struct  sockaddr rcb_faddr;     /* destination address */
-       struct  sockaddr rcb_laddr;     /* socket's address */
+       struct  sockaddr *rcb_faddr;    /* destination address */
+       struct  sockaddr *rcb_laddr;    /* socket's address */
        struct  sockproto rcb_proto;    /* protocol family, protocol */
        struct  sockproto rcb_proto;    /* protocol family, protocol */
-       caddr_t rcb_pcb;                /* protocol specific stuff */
-       struct  mbuf *rcb_options;      /* protocol specific options */
-       struct  route rcb_route;        /* routing information */
-       short   rcb_flags;
 };
 
 };
 
-/*
- * Since we can't interpret canonical addresses,
- * we mark an address present in the flags field.
- */
-#define        RAW_LADDR       01
-#define        RAW_FADDR       02
-#define        RAW_DONTROUTE   04              /* no routing, default */
-
 #define        sotorawcb(so)           ((struct rawcb *)(so)->so_pcb)
 
 /*
 #define        sotorawcb(so)           ((struct rawcb *)(so)->so_pcb)
 
 /*
@@ -50,17 +38,6 @@ struct rawcb {
 #define        RAWSNDQ         8192
 #define        RAWRCVQ         8192
 
 #define        RAWSNDQ         8192
 #define        RAWRCVQ         8192
 
-/*
- * Format of raw interface header prepended by
- * raw_input after call from protocol specific
- * input routine.
- */
-struct raw_header {
-       struct  sockproto raw_proto;    /* format of packet */
-       struct  sockaddr raw_dst;       /* dst address for rawintr */
-       struct  sockaddr raw_src;       /* src address for sbappendaddr */
-};
-
 #ifdef KERNEL
 struct rawcb rawcb;                    /* head of list */
 #endif
 #ifdef KERNEL
 struct rawcb rawcb;                    /* head of list */
 #endif
index c6a94e9..e01a9de 100644 (file)
@@ -14,7 +14,7 @@
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- *     @(#)raw_usrreq.c        7.4 (Berkeley) %G%
+ *     @(#)raw_usrreq.c        7.5 (Berkeley) %G%
  */
 
 #include "param.h"
  */
 
 #include "param.h"
@@ -42,6 +42,12 @@ raw_init()
        rawintrq.ifq_maxlen = IFQ_MAXLEN;
 }
 
        rawintrq.ifq_maxlen = IFQ_MAXLEN;
 }
 
+
+/*
+ * Raw protocol input routine.  Find the socket
+ * associated with the packet(s) and move them over.  If
+ * nothing exists for this packet, drop it.
+ */
 /*
  * Raw protocol interface.
  */
 /*
  * Raw protocol interface.
  */
@@ -50,85 +56,35 @@ raw_input(m0, proto, src, dst)
        struct sockproto *proto;
        struct sockaddr *src, *dst;
 {
        struct sockproto *proto;
        struct sockaddr *src, *dst;
 {
-       register struct mbuf *m;
-       struct raw_header *rh;
-       int s;
-
-       /*
-        * Rip off an mbuf for a generic header.
-        */
-       m = m_get(M_DONTWAIT, MT_HEADER);
-       if (m == 0) {
-               m_freem(m0);
-               return;
-       }
-       m->m_next = m0;
-       m->m_len = sizeof(struct raw_header);
-       rh = mtod(m, struct raw_header *);
-       rh->raw_dst = *dst;
-       rh->raw_src = *src;
-       rh->raw_proto = *proto;
-
-       /*
-        * Header now contains enough info to decide
-        * which socket to place packet in (if any).
-        * Queue it up for the raw protocol process
-        * running at software interrupt level.
-        */
-       s = splimp();
-       if (IF_QFULL(&rawintrq))
-               m_freem(m);
-       else
-               IF_ENQUEUE(&rawintrq, m);
-       splx(s);
-       schednetisr(NETISR_RAW);
-}
-
-/*
- * Raw protocol input routine.  Process packets entered
- * into the queue at interrupt time.  Find the socket
- * associated with the packet(s) and move them over.  If
- * nothing exists for this packet, drop it.
- */
-rawintr()
-{
-       int s;
-       struct mbuf *m;
        register struct rawcb *rp;
        register struct rawcb *rp;
-       register struct raw_header *rh;
+       register struct mbuf *m = m0;
        struct socket *last;
 
        struct socket *last;
 
-next:
-       s = splimp();
-       IF_DEQUEUE(&rawintrq, m);
-       splx(s);
-       if (m == 0)
-               return;
-       rh = mtod(m, struct raw_header *);
        last = 0;
        for (rp = rawcb.rcb_next; rp != &rawcb; rp = rp->rcb_next) {
        last = 0;
        for (rp = rawcb.rcb_next; rp != &rawcb; rp = rp->rcb_next) {
-               if (rp->rcb_proto.sp_family != rh->raw_proto.sp_family)
+               if (rp->rcb_proto.sp_family != proto->sp_family)
                        continue;
                if (rp->rcb_proto.sp_protocol  &&
                        continue;
                if (rp->rcb_proto.sp_protocol  &&
-                   rp->rcb_proto.sp_protocol != rh->raw_proto.sp_protocol)
+                   rp->rcb_proto.sp_protocol != proto->sp_protocol)
                        continue;
                /*
                 * We assume the lower level routines have
                 * placed the address in a canonical format
                 * suitable for a structure comparison.
                        continue;
                /*
                 * We assume the lower level routines have
                 * placed the address in a canonical format
                 * suitable for a structure comparison.
+                *
+                * Note that if the lengths are not the same
+                * the comparison will fail at the first byte.
                 */
                 */
-#define equal(a1, a2) \
-       (bcmp((caddr_t)&(a1), (caddr_t)&(a2), sizeof (struct sockaddr)) == 0)
-               if ((rp->rcb_flags & RAW_LADDR) &&
-                   !equal(rp->rcb_laddr, rh->raw_dst))
+#define        equal(a1, a2) \
+  (bcmp((caddr_t)(a1), (caddr_t)(a2), a1->sa_len) == 0)
+               if (rp->rcb_laddr && !equal(rp->rcb_laddr, dst))
                        continue;
                        continue;
-               if ((rp->rcb_flags & RAW_FADDR) &&
-                   !equal(rp->rcb_faddr, rh->raw_src))
+               if (rp->rcb_faddr && !equal(rp->rcb_faddr, src))
                        continue;
                if (last) {
                        struct mbuf *n;
                        continue;
                if (last) {
                        struct mbuf *n;
-                       if (n = m_copy(m->m_next, 0, (int)M_COPYALL)) {
-                               if (sbappendaddr(&last->so_rcv, &rh->raw_src,
+                       if (n = m_copy(m, 0, (int)M_COPYALL)) {
+                               if (sbappendaddr(&last->so_rcv, src,
                                    n, (struct mbuf *)0) == 0)
                                        /* should notify about lost packet */
                                        m_freem(n);
                                    n, (struct mbuf *)0) == 0)
                                        /* should notify about lost packet */
                                        m_freem(n);
@@ -139,15 +95,13 @@ next:
                last = rp->rcb_socket;
        }
        if (last) {
                last = rp->rcb_socket;
        }
        if (last) {
-               if (sbappendaddr(&last->so_rcv, &rh->raw_src,
-                   m->m_next, (struct mbuf *)0) == 0)
-                       m_freem(m->m_next);
+               if (sbappendaddr(&last->so_rcv, src,
+                   m, (struct mbuf *)0) == 0)
+                       m_freem(m);
                else
                        sorwakeup(last);
                else
                        sorwakeup(last);
-               (void) m_free(m);               /* header */
        } else
                m_freem(m);
        } else
                m_freem(m);
-       goto next;
 }
 
 /*ARGSUSED*/
 }
 
 /*ARGSUSED*/
@@ -162,13 +116,14 @@ raw_ctlinput(cmd, arg)
 }
 
 /*ARGSUSED*/
 }
 
 /*ARGSUSED*/
-raw_usrreq(so, req, m, nam, rights)
+raw_usrreq(so, req, m, nam, rights, control)
        struct socket *so;
        int req;
        struct socket *so;
        int req;
-       struct mbuf *m, *nam, *rights;
+       struct mbuf *m, *nam, *rights, *control;
 {
        register struct rawcb *rp = sotorawcb(so);
        register int error = 0;
 {
        register struct rawcb *rp = sotorawcb(so);
        register int error = 0;
+       int len;
 
        if (req == PRU_CONTROL)
                return (EOPNOTSUPP);
 
        if (req == PRU_CONTROL)
                return (EOPNOTSUPP);
@@ -176,7 +131,7 @@ raw_usrreq(so, req, m, nam, rights)
                error = EOPNOTSUPP;
                goto release;
        }
                error = EOPNOTSUPP;
                goto release;
        }
-       if (rp == 0 && req != PRU_ATTACH) {
+       if (rp == 0) {
                error = EINVAL;
                goto release;
        }
                error = EINVAL;
                goto release;
        }
@@ -192,10 +147,6 @@ raw_usrreq(so, req, m, nam, rights)
                        error = EACCES;
                        break;
                }
                        error = EACCES;
                        break;
                }
-               if (rp) {
-                       error = EINVAL;
-                       break;
-               }
                error = raw_attach(so, (int)nam);
                break;
 
                error = raw_attach(so, (int)nam);
                break;
 
@@ -211,6 +162,7 @@ raw_usrreq(so, req, m, nam, rights)
                raw_detach(rp);
                break;
 
                raw_detach(rp);
                break;
 
+#ifdef notdef
        /*
         * If a socket isn't bound to a single address,
         * the raw input routine will hand it anything
        /*
         * If a socket isn't bound to a single address,
         * the raw input routine will hand it anything
@@ -218,28 +170,30 @@ raw_usrreq(so, req, m, nam, rights)
         * nothing else around it should go to). 
         */
        case PRU_CONNECT:
         * nothing else around it should go to). 
         */
        case PRU_CONNECT:
-               if (rp->rcb_flags & RAW_FADDR) {
+               if (rp->rcb_faddr) {
                        error = EISCONN;
                        break;
                }
                        error = EISCONN;
                        break;
                }
-               raw_connaddr(rp, nam);
+               nam = m_copym(nam, 0, M_COPYALL, M_WAIT);
+               rp->rcb_faddr = mtod(nam, struct sockaddr *);
                soisconnected(so);
                break;
 
                soisconnected(so);
                break;
 
-       case PRU_CONNECT2:
-               error = EOPNOTSUPP;
-               goto release;
-
        case PRU_BIND:
        case PRU_BIND:
-               if (rp->rcb_flags & RAW_LADDR) {
+               if (rp->rcb_laddr) {
                        error = EINVAL;                 /* XXX */
                        break;
                }
                error = raw_bind(so, nam);
                break;
                        error = EINVAL;                 /* XXX */
                        break;
                }
                error = raw_bind(so, nam);
                break;
+#endif
+
+       case PRU_CONNECT2:
+               error = EOPNOTSUPP;
+               goto release;
 
        case PRU_DISCONNECT:
 
        case PRU_DISCONNECT:
-               if ((rp->rcb_flags & RAW_FADDR) == 0) {
+               if (rp->rcb_faddr == 0) {
                        error = ENOTCONN;
                        break;
                }
                        error = ENOTCONN;
                        break;
                }
@@ -260,19 +214,19 @@ raw_usrreq(so, req, m, nam, rights)
         */
        case PRU_SEND:
                if (nam) {
         */
        case PRU_SEND:
                if (nam) {
-                       if (rp->rcb_flags & RAW_FADDR) {
+                       if (rp->rcb_faddr) {
                                error = EISCONN;
                                break;
                        }
                                error = EISCONN;
                                break;
                        }
-                       raw_connaddr(rp, nam);
-               } else if ((rp->rcb_flags & RAW_FADDR) == 0) {
+                       rp->rcb_faddr = mtod(nam, struct sockaddr *);
+               } else if (rp->rcb_faddr == 0) {
                        error = ENOTCONN;
                        break;
                }
                error = (*so->so_proto->pr_output)(m, so);
                m = NULL;
                if (nam)
                        error = ENOTCONN;
                        break;
                }
                error = (*so->so_proto->pr_output)(m, so);
                m = NULL;
                if (nam)
-                       rp->rcb_flags &= ~RAW_FADDR;
+                       rp->rcb_faddr = 0;
                break;
 
        case PRU_ABORT:
                break;
 
        case PRU_ABORT:
@@ -301,15 +255,23 @@ raw_usrreq(so, req, m, nam, rights)
                break;
 
        case PRU_SOCKADDR:
                break;
 
        case PRU_SOCKADDR:
-               bcopy((caddr_t)&rp->rcb_laddr, mtod(nam, caddr_t),
-                   sizeof (struct sockaddr));
-               nam->m_len = sizeof (struct sockaddr);
+               if (rp->rcb_laddr == 0) {
+                       error = EINVAL;
+                       break;
+               }
+               len = rp->rcb_laddr->sa_len;
+               bcopy((caddr_t)rp->rcb_laddr, mtod(nam, caddr_t), (unsigned)len);
+               nam->m_len = len;
                break;
 
        case PRU_PEERADDR:
                break;
 
        case PRU_PEERADDR:
-               bcopy((caddr_t)&rp->rcb_faddr, mtod(nam, caddr_t),
-                   sizeof (struct sockaddr));
-               nam->m_len = sizeof (struct sockaddr);
+               if (rp->rcb_faddr == 0) {
+                       error = ENOTCONN;
+                       break;
+               }
+               len = rp->rcb_faddr->sa_len;
+               bcopy((caddr_t)rp->rcb_faddr, mtod(nam, caddr_t), (unsigned)len);
+               nam->m_len = len;
                break;
 
        default:
                break;
 
        default:
@@ -320,3 +282,5 @@ release:
                m_freem(m);
        return (error);
 }
                m_freem(m);
        return (error);
 }
+
+rawintr() {} /* XXX - referenced by locore.  will soon go away */
index 5896b05..cdf272c 100644 (file)
@@ -14,7 +14,7 @@
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- *     @(#)route.c     7.8 (Berkeley) %G%
+ *     @(#)route.c     7.9 (Berkeley) %G%
  */
 #include "../machine/reg.h"
  
  */
 #include "../machine/reg.h"
  
@@ -39,6 +39,7 @@
 #include "../netinet/in.h"
 #include "../netinet/in_var.h"
 
 #include "../netinet/in.h"
 #include "../netinet/in_var.h"
 
+#include "../netns/ns.h"
 #include "../machine/mtpr.h"
 #include "netisr.h"
 
 #include "../machine/mtpr.h"
 #include "netisr.h"
 
@@ -90,9 +91,9 @@ rtalloc1(dst, report)
                rt->rt_refcnt++;
        } else {
                rtstat.rts_unreach++;
                rt->rt_refcnt++;
        } else {
                rtstat.rts_unreach++;
-               if (report && route_cb.any_count)
+               if (report)
                        rt_missmsg(RTM_MISS, dst, (struct sockaddr *)0,
                        rt_missmsg(RTM_MISS, dst, (struct sockaddr *)0,
-                              (struct sockaddr *)0, (struct sockaddr *)0, 0);
+                          (struct sockaddr *)0, (struct sockaddr *)0, 0, 0);
        }
        splx(s);
        return (rt);
        }
        splx(s);
        return (rt);
@@ -101,7 +102,6 @@ rtalloc1(dst, report)
 rtfree(rt)
        register struct rtentry *rt;
 {
 rtfree(rt)
        register struct rtentry *rt;
 {
-       u_char *af;
        if (rt == 0)
                panic("rtfree");
        rt->rt_refcnt--;
        if (rt == 0)
                panic("rtfree");
        rt->rt_refcnt--;
@@ -122,61 +122,42 @@ rtfree(rt)
  * N.B.: must be called at splnet
  *
  */
  * N.B.: must be called at splnet
  *
  */
-rtredirect(dst, gateway, netmask, flags, src)
-       struct sockaddr *dst, *gateway, *src;
+rtredirect(dst, gateway, netmask, flags, src, rtp)
+       struct sockaddr *dst, *gateway, *netmask, *src;
        int flags;
        int flags;
+       struct rtentry **rtp;
 {
        register struct rtentry *rt;
 {
        register struct rtentry *rt;
+       int error = 0;
+       short *stat = 0;
 
        /* verify the gateway is directly reachable */
        if (ifa_ifwithnet(gateway) == 0) {
 
        /* verify the gateway is directly reachable */
        if (ifa_ifwithnet(gateway) == 0) {
-               rtstat.rts_badredirect++;
-               return;
+               error = ENETUNREACH;
+               goto done;
        }
        }
-       rt = rtalloc1(dst, 1);
-#define        equal(a1, a2) \
-  (bcmp((caddr_t)(a1), (caddr_t)(a2), ((struct sockaddr *)(a1))->sa_len) == 0)
+       rt = rtalloc1(dst, 0);
        /*
         * If the redirect isn't from our current router for this dst,
         * it's either old or wrong.  If it redirects us to ourselves,
         * we have a routing loop, perhaps as a result of an interface
         * going down recently.
         */
        /*
         * If the redirect isn't from our current router for this dst,
         * it's either old or wrong.  If it redirects us to ourselves,
         * we have a routing loop, perhaps as a result of an interface
         * going down recently.
         */
-       if ((rt && !equal(src, &rt->rt_gateway)) || ifa_ifwithaddr(gateway)) {
-               rtstat.rts_badredirect++;
-               if (rt)
-                       rtfree(rt);
-               return;
-       }
+#define        equal(a1, a2) (bcmp((caddr_t)(a1), (caddr_t)(a2), (a1)->sa_len) == 0)
+       if (!(flags & RTF_DONE) && rt && !equal(src, rt->rt_gateway))
+               error = EINVAL;
+       else if (ifa_ifwithaddr(gateway))
+               error = EHOSTUNREACH;
+       if (error)
+               goto done;
        /*
        /*
-        * Old comment:
         * Create a new entry if we just got back a wildcard entry
         * or the the lookup failed.  This is necessary for hosts
         * which use routing redirects generated by smart gateways
         * to dynamically build the routing tables.
         * Create a new entry if we just got back a wildcard entry
         * or the the lookup failed.  This is necessary for hosts
         * which use routing redirects generated by smart gateways
         * to dynamically build the routing tables.
-        *
-        * New comment:
-        * If we survived the previous tests, it doesn't matter
-        * what sort of entry we got when we looked it up;
-        * we should just go ahead and free the reference to
-        * the route we created.  rtalloc will not give a
-        * pointer to the root node.  And if we got a pointer
-        * to a default gateway, we should free the reference
-        * in any case.
-       if (rt) {
-               rtfree(rt);
-               rt = 0;
-       }
-       if (route_cb.any_count)
-               rt_missmsg(RTM_REDIRECT, dst, gateway, netmask, src,
-                               (flags & RTF_HOST) | RTF_GATEWAY | RTF_DYNAMIC);
         */
         */
-       if (rt == 0) {
-               rtrequest((int)RTM_ADD, dst, gateway, 0,
-                   (flags & RTF_HOST) | RTF_GATEWAY | RTF_DYNAMIC, 0);
-               rtstat.rts_dynamic++;
-               return;
-       }
+       if ((rt == 0) || (rt_mask(rt) && rt_mask(rt)->sa_len < 2))
+               goto create;
        /*
         * Don't listen to the redirect if it's
         * for a route to an interface. 
        /*
         * Don't listen to the redirect if it's
         * for a route to an interface. 
@@ -187,29 +168,44 @@ rtredirect(dst, gateway, netmask, flags, src)
                         * Changing from route to net => route to host.
                         * Create new route, rather than smashing route to net.
                         */
                         * Changing from route to net => route to host.
                         * Create new route, rather than smashing route to net.
                         */
-                       rtrequest((int)RTM_ADD, dst, gateway, 0,
-                           (flags & RTF_HOST) | RTF_GATEWAY | RTF_DYNAMIC, 0);
-                       rtstat.rts_dynamic++;
+               create:
+                       flags |=  RTF_GATEWAY | RTF_DYNAMIC;
+                       error = rtrequest((int)RTM_ADD, dst, gateway,
+                                   (struct sockaddr *)0, flags,
+                                   (struct rtentry **)0);
+                       stat = &rtstat.rts_dynamic;
                } else {
                        /*
                         * Smash the current notion of the gateway to
                } else {
                        /*
                         * Smash the current notion of the gateway to
-                        * this destination.
+                        * this destination.  Should check about netmask!!!
                         */
                        if (gateway->sa_len <= rt->rt_gateway->sa_len) {
                                Bcopy(gateway, rt->rt_gateway, gateway->sa_len);
                                rt->rt_flags |= RTF_MODIFIED;
                         */
                        if (gateway->sa_len <= rt->rt_gateway->sa_len) {
                                Bcopy(gateway, rt->rt_gateway, gateway->sa_len);
                                rt->rt_flags |= RTF_MODIFIED;
-                               rtstat.rts_newgateway++;
+                               flags |= RTF_MODIFIED;
+                               stat = &rtstat.rts_newgateway;
                        } else
                        } else
-                               rtstat.rts_badredirect++;
+                               error = ENOSPC;
                }
        } else
                }
        } else
+               error = EHOSTUNREACH;
+done:
+       if (rt) {
+               if (rtp && !error)
+                       *rtp = rt;
+               else
+                       rtfree(rt);
+       }
+       if (error)
                rtstat.rts_badredirect++;
                rtstat.rts_badredirect++;
-       rtfree(rt);
+       else
+               (stat && (*stat)++);
+       rt_missmsg(RTM_REDIRECT, dst, gateway, netmask, src, flags, error);
 }
 
 /*
 }
 
 /*
- * Routing table ioctl interface.
- */
+* Routing table ioctl interface.
+*/
 rtioctl(req, data)
        int req;
        caddr_t data;
 rtioctl(req, data)
        int req;
        caddr_t data;
@@ -251,12 +247,10 @@ rtioctl(req, data)
                case AF_INET:
                        {
                                extern struct sockaddr_in icmpmask;
                case AF_INET:
                        {
                                extern struct sockaddr_in icmpmask;
-                               u_long in_maskof();
                                struct sockaddr_in *dst_in = 
                                        (struct sockaddr_in *)&entry->rt_dst;
                                struct sockaddr_in *dst_in = 
                                        (struct sockaddr_in *)&entry->rt_dst;
-                               u_long i = ntohl(dst_in->sin_addr.s_addr);
 
 
-                               icmpmask.sin_addr.s_addr = ntohl(in_maskof(i));
+                               in_sockmaskof(dst_in->sin_addr, &icmpmask);
                                netmask = (struct sockaddr *)&icmpmask;
                        }
                        break;
                                netmask = (struct sockaddr *)&icmpmask;
                        }
                        break;
@@ -270,10 +264,10 @@ rtioctl(req, data)
 #endif
                }
        error =  rtrequest(req, &(entry->rt_dst), &(entry->rt_gateway), netmask,
 #endif
                }
        error =  rtrequest(req, &(entry->rt_dst), &(entry->rt_gateway), netmask,
-                                       entry->rt_flags, 0);
+                               entry->rt_flags, (struct rtentry **)0);
        rt_missmsg((req == RTM_ADD ? RTM_OLDADD : RTM_OLDDEL),
                   &(entry->rt_dst), &(entry->rt_gateway),
        rt_missmsg((req == RTM_ADD ? RTM_OLDADD : RTM_OLDDEL),
                   &(entry->rt_dst), &(entry->rt_gateway),
-                  netmask, (struct sockaddr *)error, entry->rt_flags);
+                  netmask, (struct sockaddr *)0, entry->rt_flags, error);
        return (error);
 #endif
 }
        return (error);
 #endif
 }
@@ -362,6 +356,7 @@ rtrequest(req, dst, gateway, netmask, flags, ret_nrt)
                if (ret_nrt)
                        *ret_nrt = rt; /* == (struct rtentry *)rn */
                rt->rt_ifp = ifa->ifa_ifp;
                if (ret_nrt)
                        *ret_nrt = rt; /* == (struct rtentry *)rn */
                rt->rt_ifp = ifa->ifa_ifp;
+               rt->rt_ifa = ifa;
                rt->rt_use = 0;
                rt->rt_refcnt = 0;
                rt->rt_flags = RTF_UP |
                rt->rt_use = 0;
                rt->rt_refcnt = 0;
                rt->rt_flags = RTF_UP |
@@ -385,33 +380,35 @@ rtinit(ifa, cmd, flags)
        register struct ifaddr *ifa;
        int cmd, flags;
 {
        register struct ifaddr *ifa;
        int cmd, flags;
 {
-       struct sockaddr net, *netp;
+       struct sockaddr net, *netp = &net;
        register caddr_t cp, cp2, cp3;
        caddr_t cplim, freeit = 0;
        int len;
 
        if (flags & RTF_HOST || ifa->ifa_netmask == 0) {
                (void) rtrequest(cmd, ifa->ifa_dstaddr, ifa->ifa_addr,
        register caddr_t cp, cp2, cp3;
        caddr_t cplim, freeit = 0;
        int len;
 
        if (flags & RTF_HOST || ifa->ifa_netmask == 0) {
                (void) rtrequest(cmd, ifa->ifa_dstaddr, ifa->ifa_addr,
-                                                               0, flags, 0);
+                           (struct sockaddr *)0, flags, (struct rtentry **)0);
        } else {
        } else {
-               if ((len = ifa->ifa_addr->sa_len) >= sizeof (net)) {
+               if ((len = ifa->ifa_addr->sa_len) >= sizeof (*netp)) {
                        R_Malloc(freeit, caddr_t, len);
                        if (freeit == 0)
                                return;
                        netp = (struct sockaddr *)freeit;
                }
                        R_Malloc(freeit, caddr_t, len);
                        if (freeit == 0)
                                return;
                        netp = (struct sockaddr *)freeit;
                }
-               netp->sa_len = len;
+               bzero((caddr_t)netp, len);
+               cp = (caddr_t) netp->sa_data;
+               cp3 = (caddr_t) ifa->ifa_netmask->sa_data;
+               cplim = ifa->ifa_netmask->sa_len +
+                                        (caddr_t) ifa->ifa_netmask;
                cp2 = 1 + (caddr_t)ifa->ifa_addr;
                netp->sa_family = *cp2++;
                cp2 = 1 + (caddr_t)ifa->ifa_addr;
                netp->sa_family = *cp2++;
-               cp3 = (caddr_t) ifa->ifa_netmask->sa_data;
-               cp = (caddr_t) netp->sa_data;
-               cplim = cp + len - 2;
-               while (cp < cplim)
+               netp->sa_len = len;
+               while (cp3 < cplim)
                        *cp++ = *cp2++ & *cp3++;
                (void) rtrequest(cmd, netp, ifa->ifa_addr, ifa->ifa_netmask,
                        *cp++ = *cp2++ & *cp3++;
                (void) rtrequest(cmd, netp, ifa->ifa_addr, ifa->ifa_netmask,
-                                       flags, 0);
+                                   flags, (struct rtentry **)0);
                if (freeit)
                if (freeit)
-                       Free(freeit);
+                       free((caddr_t)freeit, M_RTABLE);
        }
 }
 #include "radix.c"
        }
 }
 #include "radix.c"
index dcd481c..941de58 100644 (file)
@@ -52,6 +52,7 @@ struct rtentry {
        short   rt_refcnt;              /* # held references */
        u_long  rt_use;                 /* raw # packets forwarded */
        struct  ifnet *rt_ifp;          /* the answer: interface to use */
        short   rt_refcnt;              /* # held references */
        u_long  rt_use;                 /* raw # packets forwarded */
        struct  ifnet *rt_ifp;          /* the answer: interface to use */
+       struct  ifaddr *rt_ifa;         /* the answer: interface to use */
 };
 
 /*
 };
 
 /*
index 68f0352..288837d 100644 (file)
@@ -14,7 +14,7 @@
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- *     @(#)rtsock.c    7.1 (Berkeley) %G%
+ *     @(#)rtsock.c    7.2 (Berkeley) %G%
  */
 
 #ifndef RTF_UP
  */
 
 #ifndef RTF_UP
 #include "../machine/mtpr.h"
 #endif
 
 #include "../machine/mtpr.h"
 #endif
 
+struct sockaddr route_dst = { 0, PF_ROUTE, };
+struct sockaddr route_src = { 0, PF_ROUTE, };
+struct sockproto route_proto = { PF_ROUTE, };
+
 /*ARGSUSED*/
 route_usrreq(so, req, m, nam, rights, control)
        register struct socket *so;
 /*ARGSUSED*/
 route_usrreq(so, req, m, nam, rights, control)
        register struct socket *so;
@@ -44,31 +48,37 @@ route_usrreq(so, req, m, nam, rights, control)
 {
        register int error = 0;
        register struct rawcb *rp = sotorawcb(so);
 {
        register int error = 0;
        register struct rawcb *rp = sotorawcb(so);
+       if (req == PRU_ATTACH) {
+               MALLOC(rp, struct rawcb *, sizeof(*rp), M_PCB, M_WAITOK);
+               if (so->so_pcb = (caddr_t)rp)
+                       bzero(so->so_pcb, sizeof(*rp));
+
+       }
        if (req == PRU_DETACH && rp) {
                int af = rp->rcb_proto.sp_protocol;
                if (af == AF_INET)
                        route_cb.ip_count--;
                else if (af == AF_NS)
                        route_cb.ns_count--;
        if (req == PRU_DETACH && rp) {
                int af = rp->rcb_proto.sp_protocol;
                if (af == AF_INET)
                        route_cb.ip_count--;
                else if (af == AF_NS)
                        route_cb.ns_count--;
-#ifdef ISO
                else if (af == AF_ISO)
                        route_cb.iso_count--;
                else if (af == AF_ISO)
                        route_cb.iso_count--;
-#endif
                route_cb.any_count--;
        }
        error = raw_usrreq(so, req, m, nam, rights, control);
        rp = sotorawcb(so);
                route_cb.any_count--;
        }
        error = raw_usrreq(so, req, m, nam, rights, control);
        rp = sotorawcb(so);
-       if (error == 0 && req == PRU_ATTACH && rp) {
+       if (req == PRU_ATTACH && rp) {
                int af = rp->rcb_proto.sp_protocol;
                int af = rp->rcb_proto.sp_protocol;
+               if (error) {
+                       free((caddr_t)rp, M_PCB);
+                       return (error);
+               }
                if (af == AF_INET)
                        route_cb.ip_count++;
                else if (af == AF_NS)
                        route_cb.ns_count++;
                if (af == AF_INET)
                        route_cb.ip_count++;
                else if (af == AF_NS)
                        route_cb.ns_count++;
-#ifdef ISO
                else if (af == AF_ISO)
                        route_cb.iso_count++;
                else if (af == AF_ISO)
                        route_cb.iso_count++;
-#endif
-               rp->rcb_flags |= RAW_FADDR;
+               rp->rcb_faddr = &route_src;
                route_cb.any_count++;
                soisconnected(so);
        }
                route_cb.any_count++;
                soisconnected(so);
        }
@@ -76,10 +86,7 @@ route_usrreq(so, req, m, nam, rights, control)
 }
 #define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(long) - 1)))
 
 }
 #define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(long) - 1)))
 
-struct sockaddr route_dst = { 0, PF_ROUTE, };
-struct sockaddr route_src = { 0, PF_ROUTE, };
-struct sockproto route_proto = { PF_ROUTE, };
-
+/*ARGSUSED*/
 route_output(m, so)
        register struct mbuf *m;
        struct socket *so;
 route_output(m, so)
        register struct mbuf *m;
        struct socket *so;
@@ -90,10 +97,8 @@ route_output(m, so)
        struct rtentry *saved_nrt;
        struct sockaddr *dst = 0, *gate = 0, *netmask = 0, *author;
        struct rt_metrics *rmm = 0;
        struct rtentry *saved_nrt;
        struct sockaddr *dst = 0, *gate = 0, *netmask = 0, *author;
        struct rt_metrics *rmm = 0;
-       struct radix_node_head *rnh;
-       struct radix_node *rn;
        caddr_t cp = 0;
        caddr_t cp = 0;
-       int len, error = 0, s;
+       int len, error = 0;
 
 #define FLUSH(e) { error = e; goto flush;}
        if (m == 0 || (m = m_pullup(m, sizeof(long))) == 0)
 
 #define FLUSH(e) { error = e; goto flush;}
        if (m == 0 || (m = m_pullup(m, sizeof(long))) == 0)
@@ -130,7 +135,11 @@ route_output(m, so)
        }
        if (rtm->rtm_count > 2)  {
                netmask = (struct sockaddr *)cp;
        }
        if (rtm->rtm_count > 2)  {
                netmask = (struct sockaddr *)cp;
-               cp += ROUNDUP(netmask->sa_len);
+               if (*cp)
+                       cp += ROUNDUP(netmask->sa_len);
+               else
+                       cp += sizeof(long);
+
        }
        if (rtm->rtm_count > 3)  {
                author = (struct sockaddr *)cp;
        }
        if (rtm->rtm_count > 3)  {
                author = (struct sockaddr *)cp;
@@ -144,7 +153,7 @@ route_output(m, so)
 
        case RTM_DELETE:
                error = rtrequest(RTM_DELETE, dst, gate, netmask,
 
        case RTM_DELETE:
                error = rtrequest(RTM_DELETE, dst, gate, netmask,
-                                       rtm->rtm_flags, 0);
+                               rtm->rtm_flags, (struct rtentry **)0);
                break;
 
        case RTM_GET:
                break;
 
        case RTM_GET:
@@ -161,7 +170,7 @@ route_output(m, so)
                        len = sizeof(*rtm) + ROUNDUP(rt_key(rt)->sa_len)
                                        + ROUNDUP(rt->rt_gateway->sa_len);
                        if (netmask)
                        len = sizeof(*rtm) + ROUNDUP(rt_key(rt)->sa_len)
                                        + ROUNDUP(rt->rt_gateway->sa_len);
                        if (netmask)
-                               len + netmask->sa_len;
+                               len += netmask->sa_len;
                        if (len > rtm->rtm_msglen) {
                                struct rt_msghdr *new_rtm;
                                R_Malloc(new_rtm, struct rt_msghdr *, len);
                        if (len > rtm->rtm_msglen) {
                                struct rt_msghdr *new_rtm;
                                R_Malloc(new_rtm, struct rt_msghdr *, len);
@@ -270,7 +279,7 @@ m_copyback(m0, off, len, cp)
        }
        while (len > 0) {
                mlen = min (m->m_len - off, len);
        }
        while (len > 0) {
                mlen = min (m->m_len - off, len);
-               bcopy(cp, off + mtod(m, caddr_t), mlen);
+               bcopy(cp, off + mtod(m, caddr_t), (unsigned)mlen);
                cp += mlen;
                len -= mlen;
                mlen += off;
                cp += mlen;
                len -= mlen;
                mlen += off;
@@ -295,7 +304,7 @@ out:        if (((m = m0)->m_flags & M_PKTHDR) && (m->m_pkthdr.len < totlen))
  * The miss message and losing message are very similar.
  */
 
  * The miss message and losing message are very similar.
  */
 
-rt_missmsg(type, dst, gate, mask, src, flags)
+rt_missmsg(type, dst, gate, mask, src, flags, error)
 register struct sockaddr *dst;
 struct sockaddr *gate, *mask, *src;
 {
 register struct sockaddr *dst;
 struct sockaddr *gate, *mask, *src;
 {
@@ -303,7 +312,6 @@ struct sockaddr *gate, *mask, *src;
        register struct mbuf *m;
        int dlen = ROUNDUP(dst->sa_len);
        int len = dlen + sizeof(*rtm);
        register struct mbuf *m;
        int dlen = ROUNDUP(dst->sa_len);
        int len = dlen + sizeof(*rtm);
-       caddr_t cp = (caddr_t)dst;
 
        if (route_cb.any_count == 0)
                return;
 
        if (route_cb.any_count == 0)
                return;
@@ -320,12 +328,7 @@ struct sockaddr *gate, *mask, *src;
        rtm->rtm_type = type;
        rtm->rtm_count = 1;
        if (type == RTM_OLDADD || type == RTM_OLDDEL) {
        rtm->rtm_type = type;
        rtm->rtm_count = 1;
        if (type == RTM_OLDADD || type == RTM_OLDDEL) {
-               int error = (int) src;
-               src = (struct sockaddr *)0; /* XXXXXXX -- I admit. (KLS) */
                rtm->rtm_pid = u.u_procp->p_pid;
                rtm->rtm_pid = u.u_procp->p_pid;
-               rtm->rtm_errno = error;
-               if (error)
-                       rtm->rtm_flags &= ~RTF_DONE;
        }
        m_copyback(m, sizeof (*rtm), dlen, (caddr_t)dst);
        if (gate) {
        }
        m_copyback(m, sizeof (*rtm), dlen, (caddr_t)dst);
        if (gate) {
@@ -335,7 +338,10 @@ struct sockaddr *gate, *mask, *src;
                rtm->rtm_count++;
        }
        if (mask) {
                rtm->rtm_count++;
        }
        if (mask) {
-               dlen = ROUNDUP(mask->sa_len);
+               if (mask->sa_len)
+                       dlen = ROUNDUP(mask->sa_len);
+               else
+                       dlen = sizeof(long);
                m_copyback(m, len ,  dlen, (caddr_t)mask);
                len += dlen;
                rtm->rtm_count++;
                m_copyback(m, len ,  dlen, (caddr_t)mask);
                len += dlen;
                rtm->rtm_count++;
@@ -350,6 +356,7 @@ struct sockaddr *gate, *mask, *src;
                m_freem(m);
                return;
        }
                m_freem(m);
                return;
        }
+       rtm->rtm_errno = error;
        rtm->rtm_msglen = len;
        route_proto.sp_protocol = dst->sa_family;
        raw_input(m, &route_proto, &route_src, &route_dst);
        rtm->rtm_msglen = len;
        route_proto.sp_protocol = dst->sa_family;
        raw_input(m, &route_proto, &route_src, &route_dst);