update to 2.3 based on netbsd stuff
authorPaul Mackerras <paulus@samba.org>
Mon, 1 Jul 1996 01:24:29 +0000 (01:24 +0000)
committerPaul Mackerras <paulus@samba.org>
Mon, 1 Jul 1996 01:24:29 +0000 (01:24 +0000)
ultrix/bsd-comp.c
ultrix/if_ppp.c
ultrix/if_pppvar.h
ultrix/patches
ultrix/ppp-deflate.c [new file with mode: 0644]
ultrix/ppp_tty.c
ultrix/upgrade

index 12bca928f04c3b5220b8e16c41cf82396ea9382c..8246343ee37be9b046928153746f2ab93704a9e5 100644 (file)
@@ -40,7 +40,7 @@
 /*
  * This version is for use with mbufs on Ultrix systems.
  *
- * $Id: bsd-comp.c,v 1.6 1996/01/18 03:13:09 paulus Exp $
+ * $Id: bsd-comp.c,v 1.7 1996/07/01 01:24:24 paulus Exp $
  */
 
 #include "../h/param.h"
@@ -197,6 +197,12 @@ struct compressor ppp_bsd_compress = {
 #define RATIO_SCALE    (1<<RATIO_SCALE_LOG)
 #define RATIO_MAX      (0x7fffffff>>RATIO_SCALE_LOG)
 
+static void bsd_clear __P((struct bsd_db *));
+static int bsd_check __P((struct bsd_db *));
+static void *bsd_alloc __P((u_char *, int, int));
+static int bsd_init __P((struct bsd_db *, u_char *, int, int, int, int,
+                        int, int));
+
 /*
  * clear the dictionary
  */
@@ -318,7 +324,7 @@ bsd_alloc(options, opt_len, decomp)
     u_int newlen, hsize, hshift, maxmaxcode;
     struct bsd_db *db;
 
-    if (opt_len != CILEN_BSD_COMPRESS || options[0] != CI_BSD_COMPRESS
+    if (opt_len < CILEN_BSD_COMPRESS || options[0] != CI_BSD_COMPRESS
        || options[1] != CILEN_BSD_COMPRESS
        || BSD_VERSION(options[2]) != BSD_CURRENT_VERSION)
        return NULL;
@@ -494,7 +500,7 @@ bsd_compress(state, mret, mp, slen, maxolen)
     u_char *rptr, *wptr;
     u_char *cp_end;
     int olen;
-    struct mbuf *m, **mnp, *clp;
+    struct mbuf *m, *clp;
        
 #define PUTBYTE(v) {                                   \
     ++olen;                                            \
@@ -721,7 +727,6 @@ bsd_incomp(state, dmsg)
     if (ent < 0x21 || ent > 0xf9)
        return;
 
-    db->incomp_count++;
     db->seqno++;
     ilen = 1;          /* count the protocol as 1 byte */
     rptr += PPP_HDRLEN;
@@ -842,7 +847,7 @@ bsd_decompress(state, cmp, dmpp)
     struct mbuf *m, *dmp, *mret;
     int adrs, ctrl, ilen;
     int space, codelen, extra;
-    struct mbuf *last, *clp;
+    struct mbuf *clp;
 
     /*
      * Save the address/control from the PPP header
index 76725fea0d3e6e003218d602da3cb82ae708c60b..1aaf5cd59313a0b137a74f401d1057fde10122d5 100644 (file)
@@ -72,8 +72,9 @@
  * Robert Olsson <robert@robur.slu.se> and Paul Mackerras.
  */
 
-/* $Id: if_ppp.c,v 1.9 1995/10/27 03:59:42 paulus Exp $ */
+/* $Id: if_ppp.c,v 1.10 1996/07/01 01:24:25 paulus Exp $ */
 /* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */
+/* from NetBSD: if_ppp.c,v 1.15.2.2 1994/07/28 05:17:58 cgd Exp */
 
 #include "ppp.h"
 #if NPPP > 0
@@ -89,6 +90,7 @@
 #include "../h/socket.h"
 #include "../h/ioctl.h"
 #include "../h/systm.h"
+#include "../h/time.h"
 
 #include "../net/net/if.h"
 #include "../net/net/netisr.h"
 #include "../machine/mtpr.h"
 #endif
 
-#include "ppp_defs.h"
-#include "if_ppp.h"
-
 #ifdef VJC
 #include "slcompress.h"
 #endif
 
+#include "ppp_defs.h"
+#include "if_ppp.h"
 #include "if_pppvar.h"
 
 #ifdef PPP_COMPRESS
 #include "ppp-comp.h"
 #endif
 
-void   pppattach __P((void));
-int    pppioctl __P((struct ppp_softc *sc, int cmd, caddr_t data, int flag));
-int    pppoutput __P((struct ifnet *ifp, struct mbuf *m0,
-                      struct sockaddr *dst));
-int    pppsioctl __P((struct ifnet *ifp, int cmd, caddr_t data));
-void   pppintr __P((void));
-
 static void    ppp_requeue __P((struct ppp_softc *));
 static void    ppp_outpkt __P((struct ppp_softc *));
-static int     ppp_ccp __P((struct ppp_softc *, struct mbuf *m, int rcvd));
+static void    ppp_ccp __P((struct ppp_softc *, struct mbuf *m, int rcvd));
 static void    ppp_ccp_closed __P((struct ppp_softc *));
 static void    ppp_inproc __P((struct ppp_softc *, struct mbuf *));
 static void    pppdumpm __P((struct mbuf *m0));
@@ -166,15 +160,20 @@ static u_short interactive_ports[8] = {
  */
 
 extern struct compressor ppp_bsd_compress;
+extern struct compressor ppp_deflate;
 
 struct compressor *ppp_compressors[] = {
 #if DO_BSD_COMPRESS
     &ppp_bsd_compress,
+#endif
+#if DO_DEFLATE
+    &ppp_deflate,
 #endif
     NULL
 };
 #endif /* PPP_COMPRESS */
 
+
 /*
  * Called from boot code to establish ppp interfaces.
  */
@@ -190,6 +189,7 @@ pppattach()
        sc->sc_if.if_mtu = PPP_MTU;
        sc->sc_if.if_flags = IFF_POINTOPOINT;
        sc->sc_if.if_type = IFT_PPP;
+       sc->sc_if.if_hdrlen = PPP_HDRLEN;
        sc->sc_if.if_ioctl = pppsioctl;
        sc->sc_if.if_output = pppoutput;
        sc->sc_if.if_snd.ifq_maxlen = IFQ_MAXLEN;
@@ -227,8 +227,12 @@ pppalloc(pid)
     sc->sc_flags = 0;
     sc->sc_mru = PPP_MRU;
     sc->sc_relinq = NULL;
+    bzero((char *)&sc->sc_stats, sizeof(sc->sc_stats));
 #ifdef VJC
-    sl_compress_init(&sc->sc_comp);
+    KM_ALLOC(sc->sc_comp, struct slcompress *, sizeof(struct slcompress),
+          KM_DEVBUF, KM_NOARG);
+    if (sc->sc_comp)
+       sl_compress_init(sc->sc_comp, -1);
 #endif
 #ifdef PPP_COMPRESS
     sc->sc_xc_state = NULL;
@@ -287,6 +291,12 @@ pppdealloc(sc)
     sc->sc_xc_state = NULL;
     sc->sc_rc_state = NULL;
 #endif /* PPP_COMPRESS */
+#ifdef VJC
+    if (sc->sc_comp != 0) {
+       KM_FREE(sc->sc_comp, KM_DEVBUF);
+       sc->sc_comp = 0;
+    }
+#endif
 }
 
 /*
@@ -372,9 +382,11 @@ pppioctl(sc, cmd, data, flag)
     case PPPIOCSMAXCID:
        if (!suser())
            return EPERM;
-       s = splnet();
-       sl_compress_setup(&sc->sc_comp, *(int *)data);
-       splx(s);
+       if (sc->sc_comp) {
+           s = splnet();
+           sl_compress_init(sc->sc_comp, *(int *)data);
+           splx(s);
+       }
        break;
 #endif
 
@@ -392,7 +404,7 @@ pppioctl(sc, cmd, data, flag)
        nb = odp->length;
        if (nb > sizeof(ccp_option))
            nb = sizeof(ccp_option);
-       if (error = copyin(odp->ptr, ccp_option, nb))
+       if ((error = copyin(odp->ptr, ccp_option, nb)) != 0)
            return (error);
        if (ccp_option[1] < 2)  /* preliminary check on the length byte */
            return (EINVAL);
@@ -539,21 +551,18 @@ pppsioctl(ifp, cmd, data)
     case SIOCGPPPSTATS:
        psp = &((struct ifpppstatsreq *) data)->stats;
        bzero(psp, sizeof(*psp));
-       psp->p.ppp_ibytes = sc->sc_bytesrcvd;
-       psp->p.ppp_ipackets = ifp->if_ipackets;
-       psp->p.ppp_ierrors = ifp->if_ierrors;
-       psp->p.ppp_obytes = sc->sc_bytessent;
-       psp->p.ppp_opackets = ifp->if_opackets;
-       psp->p.ppp_oerrors = ifp->if_oerrors;
-#ifdef VJC
-       psp->vj.vjs_packets = sc->sc_comp.sls_packets;
-       psp->vj.vjs_compressed = sc->sc_comp.sls_compressed;
-       psp->vj.vjs_searches = sc->sc_comp.sls_searches;
-       psp->vj.vjs_misses = sc->sc_comp.sls_misses;
-       psp->vj.vjs_uncompressedin = sc->sc_comp.sls_uncompressedin;
-       psp->vj.vjs_compressedin = sc->sc_comp.sls_compressedin;
-       psp->vj.vjs_errorin = sc->sc_comp.sls_errorin;
-       psp->vj.vjs_tossed = sc->sc_comp.sls_tossed;
+       psp->p = sc->sc_stats;
+#if defined(VJC) && !defined(SL_NO_STATS)
+       if (sc->sc_comp) {
+           psp->vj.vjs_packets = sc->sc_comp->sls_packets;
+           psp->vj.vjs_compressed = sc->sc_comp->sls_compressed;
+           psp->vj.vjs_searches = sc->sc_comp->sls_searches;
+           psp->vj.vjs_misses = sc->sc_comp->sls_misses;
+           psp->vj.vjs_uncompressedin = sc->sc_comp->sls_uncompressedin;
+           psp->vj.vjs_compressedin = sc->sc_comp->sls_compressedin;
+           psp->vj.vjs_errorin = sc->sc_comp->sls_errorin;
+           psp->vj.vjs_tossed = sc->sc_comp->sls_tossed;
+       }
 #endif /* VJC */
        break;
 
@@ -586,7 +595,6 @@ pppoutput(ifp, m0, dst)
     struct sockaddr *dst;
 {
     register struct ppp_softc *sc = &ppp_softc[ifp->if_unit];
-    struct ppp_header *ph;
     int protocol, address, control;
     u_char *cp;
     int s, error;
@@ -595,7 +603,7 @@ pppoutput(ifp, m0, dst)
     enum NPmode mode;
 
     if (sc->sc_devp == NULL || (ifp->if_flags & IFF_RUNNING) == 0
-       || (ifp->if_flags & IFF_UP) == 0 && dst->sa_family != AF_UNSPEC) {
+       || ((ifp->if_flags & IFF_UP) == 0 && dst->sa_family != AF_UNSPEC)) {
        error = ENETDOWN;       /* sort of */
        goto bad;
     }
@@ -678,6 +686,13 @@ pppoutput(ifp, m0, dst)
        pppdumpm(m0);
     }
 
+    if ((protocol & 0x8000) == 0) {
+       /*
+        * Update the time we sent the most recent data packet.
+        */
+       sc->sc_last_sent = time.tv_sec;
+    }
+
 #if NBPFILTER > 0
     /*
      * See if bpf wants to look at the packet.
@@ -701,12 +716,15 @@ pppoutput(ifp, m0, dst)
            IF_DROP(ifq);
            splx(s);
            sc->sc_if.if_oerrors++;
+           sc->sc_stats.ppp_oerrors++;
            error = ENOBUFS;
            goto bad;
        }
        IF_ENQUEUE(ifq, m0);
        (*sc->sc_start)(sc);
     }
+    ifp->if_opackets++;
+    ifp->if_obytes += len;
 
     splx(s);
     return (0);
@@ -749,6 +767,7 @@ ppp_requeue(sc)
            if (IF_QFULL(ifq)) {
                IF_DROP(ifq);
                sc->sc_if.if_oerrors++;
+               sc->sc_stats.ppp_oerrors++;
            } else
                IF_ENQUEUE(ifq, m);
            break;
@@ -768,80 +787,34 @@ ppp_requeue(sc)
 }
 
 /*
- * Get a packet to send.  This procedure is intended to be called at
- * spltty or splimp, so it takes little time.  If there isn't a packet
- * waiting to go out, it schedules a software interrupt to prepare a
- * new packet; the device start routine gets called again when a
- * packet is ready.
+ * Transmitter has finished outputting some stuff;
+ * remember to call sc->sc_start later at splsoftnet.
  */
-struct mbuf *
-ppp_dequeue(sc)
+void
+ppp_restart(sc)
     struct ppp_softc *sc;
 {
-    struct mbuf *m;
     int s = splimp();
 
-    m = sc->sc_togo;
-    if (m) {
-       /*
-        * Had a packet waiting - send it.
-        */
-       sc->sc_togo = NULL;
-       sc->sc_flags |= SC_TBUSY;
-       splx(s);
-       return m;
-    }
-    /*
-     * Remember we wanted a packet and schedule a software interrupt.
-     */
     sc->sc_flags &= ~SC_TBUSY;
     schednetisr(NETISR_PPP);
     splx(s);
-    return NULL;
-}
-
-/*
- * Software interrupt routine, called at splnet.
- */
-void
-pppintr()
-{
-    struct ppp_softc *sc;
-    int i, s;
-    struct mbuf *m;
-
-    s = splnet();
-    sc = ppp_softc;
-    for (i = 0; i < NPPP; ++i, ++sc) {
-       if (!(sc->sc_flags & SC_TBUSY) && sc->sc_togo == NULL
-           && (sc->sc_if.if_snd.ifq_head || sc->sc_fastq.ifq_head))
-           ppp_outpkt(sc);
-       for (;;) {
-           s = splimp();
-           IF_DEQUEUE(&sc->sc_rawq, m);
-           splx(s);
-           if (m == NULL)
-               break;
-           ppp_inproc(sc, m);
-       }
-    }
-    splx(s);
 }
 
 /*
- * Grab another packet off a queue and apply VJ compression,
- * packet compression, address/control and/or protocol compression
- * if enabled.  Should be called at splnet.
+ * Get a packet to send.  This procedure is intended to be called at
+ * splsoftnet, since it may involve time-consuming operations such as
+ * applying VJ compression, packet compression, address/control and/or
+ * protocol field compression to the packet.
  */
-static void
-ppp_outpkt(sc)
+struct mbuf *
+ppp_dequeue(sc)
     struct ppp_softc *sc;
 {
-    int s;
     struct mbuf *m, *mp;
     u_char *cp;
     int address, control, protocol;
-    enum NPmode mode;
+    int s;
 
     /*
      * Grab a packet to send: first try the fast queue, then the
@@ -851,7 +824,9 @@ ppp_outpkt(sc)
     if (m == NULL)
        IF_DEQUEUE(&sc->sc_if.if_snd, m);
     if (m == NULL)
-       return;
+       return NULL;
+
+    ++sc->sc_stats.ppp_opackets;
 
     /*
      * Extract the ppp header of the new packet.
@@ -864,16 +839,11 @@ ppp_outpkt(sc)
 
     switch (protocol) {
     case PPP_IP:
-       /*
-        * Update the time we sent the most recent packet.
-        */
-       sc->sc_last_sent = time.tv_sec;
-
 #ifdef VJC
        /*
         * If the packet is a TCP/IP packet, see if we can compress it.
         */
-       if (sc->sc_flags & SC_COMP_TCP) {
+       if ((sc->sc_flags & SC_COMP_TCP) && sc->sc_comp != NULL) {
            struct ip *ip;
            int type;
 
@@ -887,7 +857,7 @@ ppp_outpkt(sc)
            }
            /* this code assumes the IP/TCP header is in one non-shared mbuf */
            if (ip->ip_p == IPPROTO_TCP) {
-               type = sl_compress_tcp(mp, ip, &sc->sc_comp,
+               type = sl_compress_tcp(mp, ip, sc->sc_comp,
                                       !(sc->sc_flags & SC_NO_TCP_CCID));
                switch (type) {
                case TYPE_UNCOMPRESSED_TCP:
@@ -917,7 +887,7 @@ ppp_outpkt(sc)
 #ifdef PPP_COMPRESS
     if (protocol != PPP_LCP && protocol != PPP_CCP
        && sc->sc_xc_state && (sc->sc_flags & SC_COMP_RUN)) {
-       struct mbuf *mcomp;
+       struct mbuf *mcomp = NULL;
        int slen, clen;
 
        slen = 0;
@@ -955,8 +925,39 @@ ppp_outpkt(sc)
        --m->m_len;
     }
 
-    sc->sc_togo = m;
-    (*sc->sc_start)(sc);
+    return m;
+}
+
+/*
+ * Software interrupt routine, called at splsoftnet.
+ */
+void
+pppintr()
+{
+    struct ppp_softc *sc;
+    int i, s, s2;
+    struct mbuf *m;
+
+    sc = ppp_softc;
+    s = splsoftnet();
+    for (i = 0; i < NPPP; ++i, ++sc) {
+       if (!(sc->sc_flags & SC_TBUSY)
+           && (sc->sc_if.if_snd.ifq_head || sc->sc_fastq.ifq_head)) {
+           s2 = splimp();
+           sc->sc_flags |= SC_TBUSY;
+           splx(s2);
+           (*sc->sc_start)(sc);
+       }
+       for (;;) {
+           s2 = splimp();
+           IF_DEQUEUE(&sc->sc_rawq, m);
+           splx(s2);
+           if (m == NULL)
+               break;
+           ppp_inproc(sc, m);
+       }
+    }
+    splx(s);
 }
 
 #ifdef PPP_COMPRESS
@@ -964,7 +965,7 @@ ppp_outpkt(sc)
  * Handle a CCP packet.  `rcvd' is 1 if the packet was received,
  * 0 if it is about to be transmitted.
  */
-static int
+static void
 ppp_ccp(sc, m, rcvd)
     struct ppp_softc *sc;
     struct mbuf *m;
@@ -1108,20 +1109,21 @@ ppp_inproc(sc, m)
     struct ppp_softc *sc;
     struct mbuf *m;
 {
+    struct ifnet *ifp = &sc->sc_if;
     struct ifqueue *inq, *lock;
     int s, ilen, xlen, proto, rv;
     u_char *cp, adrs, ctrl;
-    struct mbuf *mp, *dmp, *pc;
+    struct mbuf *mp, *dmp = NULL, *pc;
     u_char *iphdr;
     u_int hlen;
 
-    sc->sc_if.if_ipackets++;
+    sc->sc_stats.ppp_ipackets++;
 
     if (sc->sc_flags & SC_LOG_INPKT) {
        ilen = 0;
        for (mp = m; mp != NULL; mp = mp->m_next)
            ilen += mp->m_len;
-       printf("ppp%d: got %d bytes\n", sc->sc_if.if_unit, ilen);
+       printf("ppp%d: got %d bytes\n", ifp->if_unit, ilen);
        pppdumpm(m);
     }
 
@@ -1162,8 +1164,8 @@ ppp_inproc(sc, m)
             * CCP down or issue a Reset-Req.
             */
            if (sc->sc_flags & SC_DEBUG)
-               printf("ppp%d: decompress failed %d\n", sc->sc_if.if_unit, rv);
-           s = splhigh();
+               printf("ppp%d: decompress failed %d\n", ifp->if_unit, rv);
+           s = splimp();
            sc->sc_flags |= SC_VJ_RESET;
            if (rv == DECOMP_ERROR)
                sc->sc_flags |= SC_DC_ERROR;
@@ -1192,7 +1194,8 @@ ppp_inproc(sc, m)
         * If we've missed a packet, we must toss subsequent compressed
         * packets which don't have an explicit connection ID.
         */
-       sl_uncompress_tcp(NULL, 0, TYPE_ERROR, &sc->sc_comp);
+       if (sc->sc_comp)
+           sl_uncompress_tcp(NULL, 0, TYPE_ERROR, sc->sc_comp);
        s = splimp();
        sc->sc_flags &= ~SC_VJ_RESET;
        splx(s);
@@ -1202,17 +1205,17 @@ ppp_inproc(sc, m)
      * See if we have a VJ-compressed packet to uncompress.
      */
     if (proto == PPP_VJC_COMP) {
-       if (sc->sc_flags & SC_REJ_COMP_TCP)
+       if ((sc->sc_flags & SC_REJ_COMP_TCP) || sc->sc_comp == 0)
            goto bad;
 
        xlen = sl_uncompress_tcp_core(cp + PPP_HDRLEN, m->m_len - PPP_HDRLEN,
                                      ilen - PPP_HDRLEN, TYPE_COMPRESSED_TCP,
-                                     &sc->sc_comp, &iphdr, &hlen);
+                                     sc->sc_comp, &iphdr, &hlen);
 
        if (xlen <= 0) {
            if (sc->sc_flags & SC_DEBUG)
                printf("ppp%d: VJ uncompress failed on type comp\n",
-                       sc->sc_if.if_unit);
+                       ifp->if_unit);
            goto bad;
        }
 
@@ -1254,17 +1257,17 @@ ppp_inproc(sc, m)
        ilen += hlen - xlen;
 
     } else if (proto == PPP_VJC_UNCOMP) {
-       if (sc->sc_flags & SC_REJ_COMP_TCP)
+       if ((sc->sc_flags & SC_REJ_COMP_TCP) || sc->sc_comp == 0)
            goto bad;
 
        xlen = sl_uncompress_tcp_core(cp + PPP_HDRLEN, m->m_len - PPP_HDRLEN,
                                      ilen - PPP_HDRLEN, TYPE_UNCOMPRESSED_TCP,
-                                     &sc->sc_comp, &iphdr, &hlen);
+                                     sc->sc_comp, &iphdr, &hlen);
 
        if (xlen < 0) {
            if (sc->sc_flags & SC_DEBUG)
                printf("ppp%d: VJ uncompress failed on type uncomp\n",
-                       sc->sc_if.if_unit);
+                       ifp->if_unit);
            goto bad;
        }
 
@@ -1287,6 +1290,13 @@ ppp_inproc(sc, m)
        }
     }
 
+    /*
+     * Record the time that we received this packet.
+     */
+    if ((proto & 0x8000) == 0) {
+       sc->sc_last_recv = time.tv_sec;
+    }
+
 #if NBPFILTER > 0
     /* See if bpf wants to look at the packet. */
     if (sc->sc_bpf)
@@ -1300,7 +1310,7 @@ ppp_inproc(sc, m)
        /*
         * IP packet - take off the ppp header and pass it up to IP.
         */
-       if ((sc->sc_if.if_flags & IFF_UP) == 0
+       if ((ifp->if_flags & IFF_UP) == 0
            || sc->sc_npmode[NP_IP] != NPMODE_PASS) {
            /* interface is down - drop the packet. */
            m_freem(m);
@@ -1310,7 +1320,6 @@ ppp_inproc(sc, m)
        m->m_len -= PPP_HDRLEN;
        schednetisr(NETISR_IP);
        inq = &ipintrq;
-       sc->sc_last_recv = time.tv_sec; /* update time of last pkt rcvd */
        break;
 #endif
 
@@ -1334,12 +1343,14 @@ ppp_inproc(sc, m)
        smp_unlock(&lock->lk_ifqueue);
        splx(s);
        if (sc->sc_flags & SC_DEBUG)
-           printf("ppp%d: input queue full\n", sc->sc_if.if_unit);
+           printf("ppp%d: input queue full\n", ifp->if_unit);
        goto bad;
     }
     IF_ENQUEUEIF(inq, m, &sc->sc_if);
     smp_unlock(&lock->lk_ifqueue);
     splx(s);
+    ifp->if_ipackets++;
+    ifp->if_ibytes += ilen;
 
     if (rv)
        (*sc->sc_ctlp)(sc);
@@ -1349,6 +1360,7 @@ ppp_inproc(sc, m)
  bad:
     m_freem(m);
     sc->sc_if.if_ierrors++;
+    sc->sc_stats.ppp_ierrors++;
 }
 
 #define MAX_DUMP_BYTES 128
index 419311159a6df62d9c26d037df23816f22a060da..25b14544c1e4581ab18b9be684cc0a37ae7217b4 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: if_pppvar.h,v 1.3 1994/12/13 03:26:08 paulus Exp $ */
+/*     $Id: if_pppvar.h,v 1.4 1996/07/01 01:24:26 paulus Exp $ */
 /*
  * if_pppvar.h - private structures and declarations for PPP.
  *
@@ -66,20 +66,19 @@ struct ppp_softc {
        struct  mbuf *sc_togo;          /* output packet ready to go */
        struct  mbuf *sc_npqueue;       /* output packets not to be sent yet */
        struct  mbuf **sc_npqtail;      /* ptr to last next ptr in npqueue */
-#ifdef VJC
-       struct  slcompress sc_comp;     /* vjc control buffer */
-#endif
-       u_int   sc_bytessent;           /* count of octets sent */
-       u_int   sc_bytesrcvd;           /* count of octets received */
+       struct  pppstat sc_stats;       /* count of bytes/pkts sent/rcvd */
        caddr_t sc_bpf;                 /* hook for BPF */
        enum    NPmode sc_npmode[NUM_NP]; /* what to do with each NP */
        struct  compressor *sc_xcomp;   /* transmit compressor */
        void    *sc_xc_state;           /* transmit compressor state */
        struct  compressor *sc_rcomp;   /* receive decompressor */
        void    *sc_rc_state;           /* receive decompressor state */
-       int     sc_last_sent;           /* time (secs) last NP pkt sent */
-       int     sc_last_recv;           /* time (secs) last NP pkt rcvd */
-       
+       time_t  sc_last_sent;           /* time (secs) last NP pkt sent */
+       time_t  sc_last_recv;           /* time (secs) last NP pkt rcvd */
+#ifdef VJC
+       struct  slcompress *sc_comp;    /* vjc control buffer */
+#endif
+
        /* Device-dependent part for async lines. */
        ext_accm sc_asyncmap;           /* async control character map */
        u_long  sc_rasyncmap;           /* receive async control char map */
@@ -100,5 +99,6 @@ struct       ppp_softc *pppalloc __P((pid_t pid));
 void   pppdealloc __P((struct ppp_softc *sc));
 int    pppioctl __P((struct ppp_softc *sc, int cmd, caddr_t data,
                      int flag, struct proc *p));
+void   ppp_restart __P((struct ppp_softc *sc));
 void   ppppktin __P((struct ppp_softc *sc, struct mbuf *m, int lost));
 struct mbuf *ppp_dequeue __P((struct ppp_softc *sc));
index 53e5ddfaa21388f7ea8f634f2b9cb7edf60b78bd..d445ca9cbbe32c71bcc3b29cf197d5c207aedd8c 100644 (file)
   io/netif/if_qe.c             optional qe device-driver Binary
   io/netif/if_uba.c            optional inet device-driver Binary
   io/netif/if_ni.c             optional bvpni device-driver Binary
---- 114,123 ----
+--- 114,125 ----
   io/netif/if_ln_copy.s                optional ln Binary 
   io/netif/if_ne.c             optional ne device-driver Binary
   io/netif/if_sl.c             optional sl device-driver Binary Unsupported
 ! io/netif/if_ppp.c            optional ppp device-driver Notbinary
 ! io/netif/ppp_tty.c           optional ppp device-driver Notbinary
 ! io/netif/bsd-comp.c          optional ppp device-driver Notbinary
+! io/netif/ppp-deflate.c               optional ppp device-driver Notbinary
+! io/netif/zlib.c                      optional ppp device-driver Notbinary
 ! io/netif/slcompress.c                optional sl or ppp device-driver Notbinary
   io/netif/if_qe.c             optional qe device-driver Binary
   io/netif/if_uba.c            optional inet device-driver Binary
diff --git a/ultrix/ppp-deflate.c b/ultrix/ppp-deflate.c
new file mode 100644 (file)
index 0000000..c6e6299
--- /dev/null
@@ -0,0 +1,654 @@
+/*     $Id: ppp-deflate.c,v 1.1 1996/07/01 01:24:27 paulus Exp $       */
+
+/*
+ * ppp_deflate.c - interface the zlib procedures for Deflate compression
+ * and decompression (as used by gzip) to the PPP code.
+ * This version is for use with mbufs on BSD-derived systems.
+ *
+ * Copyright (c) 1994 The Australian National University.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation is hereby granted, provided that the above copyright
+ * notice appears in all copies.  This software is provided without any
+ * warranty, express or implied. The Australian National University
+ * makes no representations about the suitability of this software for
+ * any purpose.
+ *
+ * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY
+ * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
+ * THE AUSTRALIAN NATIONAL UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
+ * OR MODIFICATIONS.
+ */
+
+#include "../h/param.h"
+#include "../h/types.h"
+#include "../h/mbuf.h"
+#include "../h/socket.h"
+#include "../net/net/if.h"
+#include "ppp_defs.h"
+#include "zlib.h"
+
+#define PACKETPTR      struct mbuf *
+#include "ppp-comp.h"
+
+#if DO_DEFLATE
+
+/*
+ * State for a Deflate (de)compressor.
+ */
+struct deflate_state {
+    int                seqno;
+    int                w_size;
+    int                unit;
+    int                hdrlen;
+    int                mru;
+    int                debug;
+    z_stream   strm;
+    struct compstat stats;
+};
+
+#define DEFLATE_OVHD   2               /* Deflate overhead/packet */
+
+static void    *zalloc __P((void *, u_int items, u_int size));
+static void    zfree __P((void *, void *ptr, u_int nb));
+static void    *z_comp_alloc __P((u_char *options, int opt_len));
+static void    *z_decomp_alloc __P((u_char *options, int opt_len));
+static void    z_comp_free __P((void *state));
+static void    z_decomp_free __P((void *state));
+static int     z_comp_init __P((void *state, u_char *options, int opt_len,
+                                int unit, int hdrlen, int debug));
+static int     z_decomp_init __P((void *state, u_char *options, int opt_len,
+                                    int unit, int hdrlen, int mru, int debug));
+static int     z_compress __P((void *state, struct mbuf **mret,
+                                 struct mbuf *mp, int slen, int maxolen));
+static void    z_incomp __P((void *state, struct mbuf *dmsg));
+static int     z_decompress __P((void *state, struct mbuf *cmp,
+                                   struct mbuf **dmpp));
+static void    z_comp_reset __P((void *state));
+static void    z_decomp_reset __P((void *state));
+static void    z_comp_stats __P((void *state, struct compstat *stats));
+
+/*
+ * Procedures exported to if_ppp.c.
+ */
+struct compressor ppp_deflate = {
+    CI_DEFLATE,                        /* compress_proto */
+    z_comp_alloc,              /* comp_alloc */
+    z_comp_free,               /* comp_free */
+    z_comp_init,               /* comp_init */
+    z_comp_reset,              /* comp_reset */
+    z_compress,                        /* compress */
+    z_comp_stats,              /* comp_stat */
+    z_decomp_alloc,            /* decomp_alloc */
+    z_decomp_free,             /* decomp_free */
+    z_decomp_init,             /* decomp_init */
+    z_decomp_reset,            /* decomp_reset */
+    z_decompress,              /* decompress */
+    z_incomp,                  /* incomp */
+    z_comp_stats,              /* decomp_stat */
+};
+
+/*
+ * Space allocation and freeing routines for use by zlib routines.
+ */
+void *
+zalloc(notused, items, size)
+    void *notused;
+    u_int items, size;
+{
+    void *ptr;
+
+    KM_ALLOC(ptr, void *, items * size, KM_DEVBUF, KM_NOARG);
+    return ptr;
+}
+
+void
+zfree(notused, ptr, nbytes)
+    void *notused;
+    void *ptr;
+    u_int nbytes;
+{
+    KM_FREE(ptr, KM_DEVBUF);
+}
+
+/*
+ * Allocate space for a compressor.
+ */
+static void *
+z_comp_alloc(options, opt_len)
+    u_char *options;
+    int opt_len;
+{
+    struct deflate_state *state;
+    int w_size;
+
+    if (opt_len != CILEN_DEFLATE || options[0] != CI_DEFLATE
+       || options[1] != CILEN_DEFLATE
+       || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
+       || options[3] != DEFLATE_CHK_SEQUENCE)
+       return NULL;
+    w_size = DEFLATE_SIZE(options[2]);
+    if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
+       return NULL;
+
+    MALLOC(state, struct deflate_state *, sizeof(struct deflate_state),
+          M_DEVBUF, M_NOWAIT);
+    if (state == NULL)
+       return NULL;
+
+    state->strm.next_in = NULL;
+    state->strm.zalloc = zalloc;
+    state->strm.zfree = zfree;
+    if (deflateInit2(&state->strm, Z_DEFAULT_COMPRESSION, DEFLATE_METHOD_VAL,
+                    -w_size, 8, Z_DEFAULT_STRATEGY, DEFLATE_OVHD+2) != Z_OK) {
+       FREE(state, M_DEVBUF);
+       return NULL;
+    }
+
+    state->w_size = w_size;
+    bzero(&state->stats, sizeof(state->stats));
+    return (void *) state;
+}
+
+static void
+z_comp_free(arg)
+    void *arg;
+{
+    struct deflate_state *state = (struct deflate_state *) arg;
+
+    deflateEnd(&state->strm);
+    FREE(state, M_DEVBUF);
+}
+
+static int
+z_comp_init(arg, options, opt_len, unit, hdrlen, debug)
+    void *arg;
+    u_char *options;
+    int opt_len, unit, hdrlen, debug;
+{
+    struct deflate_state *state = (struct deflate_state *) arg;
+
+    if (opt_len < CILEN_DEFLATE || options[0] != CI_DEFLATE
+       || options[1] != CILEN_DEFLATE
+       || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
+       || DEFLATE_SIZE(options[2]) != state->w_size
+       || options[3] != DEFLATE_CHK_SEQUENCE)
+       return 0;
+
+    state->seqno = 0;
+    state->unit = unit;
+    state->hdrlen = hdrlen;
+    state->debug = debug;
+
+    deflateReset(&state->strm);
+
+    return 1;
+}
+
+static void
+z_comp_reset(arg)
+    void *arg;
+{
+    struct deflate_state *state = (struct deflate_state *) arg;
+
+    state->seqno = 0;
+    deflateReset(&state->strm);
+}
+
+int
+z_compress(arg, mret, mp, orig_len, maxolen)
+    void *arg;
+    struct mbuf **mret;                /* compressed packet (out) */
+    struct mbuf *mp;           /* uncompressed packet (in) */
+    int orig_len, maxolen;
+{
+    struct deflate_state *state = (struct deflate_state *) arg;
+    u_char *rptr, *wptr;
+    int proto, olen, wspace, r, flush;
+    struct mbuf *m;
+
+    /*
+     * Check that the protocol is in the range we handle.
+     */
+    rptr = mtod(mp, u_char *);
+    proto = PPP_PROTOCOL(rptr);
+    if (proto > 0x3fff || proto == 0xfd || proto == 0xfb) {
+       *mret = NULL;
+       return orig_len;
+    }
+
+    /* Allocate one mbuf initially. */
+    if (maxolen > orig_len)
+       maxolen = orig_len;
+    MGET(m, M_DONTWAIT, MT_DATA);
+    *mret = m;
+    if (m != NULL) {
+       m->m_len = 0;
+       if (maxolen + state->hdrlen > MLEN)
+           MCLGET(m, M_DONTWAIT);
+       wspace = M_TRAILINGSPACE(m);
+       if (state->hdrlen + PPP_HDRLEN + 2 < wspace) {
+           m->m_data += state->hdrlen;
+           wspace -= state->hdrlen;
+       }
+       wptr = mtod(m, u_char *);
+
+       /*
+        * Copy over the PPP header and store the 2-byte sequence number.
+        */
+       wptr[0] = PPP_ADDRESS(rptr);
+       wptr[1] = PPP_CONTROL(rptr);
+       wptr[2] = PPP_COMP >> 8;
+       wptr[3] = PPP_COMP;
+       wptr += PPP_HDRLEN;
+       wptr[0] = state->seqno >> 8;
+       wptr[1] = state->seqno;
+       wptr += 2;
+       state->strm.next_out = wptr;
+       state->strm.avail_out = wspace - (PPP_HDRLEN + 2);
+    } else {
+       state->strm.next_out = NULL;
+       state->strm.avail_out = 1000000;
+       wptr = NULL;
+       wspace = 0;
+    }
+    ++state->seqno;
+
+    rptr += (proto > 0xff)? 2: 3;      /* skip 1st proto byte if 0 */
+    state->strm.next_in = rptr;
+    state->strm.avail_in = mtod(mp, u_char *) + mp->m_len - rptr;
+    mp = mp->m_next;
+    flush = (mp == NULL)? Z_PACKET_FLUSH: Z_NO_FLUSH;
+    olen = 0;
+    for (;;) {
+       r = deflate(&state->strm, flush);
+       if (r != Z_OK) {
+           printf("z_compress: deflate returned %d (%s)\n",
+                  r, (state->strm.msg? state->strm.msg: ""));
+           break;
+       }
+       if (flush != Z_NO_FLUSH && state->strm.avail_out != 0)
+           break;              /* all done */
+       if (state->strm.avail_in == 0 && mp != NULL) {
+           state->strm.next_in = mtod(mp, u_char *);
+           state->strm.avail_in = mp->m_len;
+           mp = mp->m_next;
+           if (mp == NULL)
+               flush = Z_PACKET_FLUSH;
+       }
+       if (state->strm.avail_out == 0) {
+           if (m != NULL) {
+               m->m_len = wspace;
+               olen += wspace;
+               MGET(m->m_next, M_DONTWAIT, MT_DATA);
+               m = m->m_next;
+               if (m != NULL) {
+                   m->m_len = 0;
+                   if (maxolen - olen > MLEN)
+                       MCLGET(m, M_DONTWAIT);
+                   state->strm.next_out = mtod(m, u_char *);
+                   state->strm.avail_out = wspace = M_TRAILINGSPACE(m);
+               }
+           }
+           if (m == NULL) {
+               state->strm.next_out = NULL;
+               state->strm.avail_out = 1000000;
+           }
+       }
+    }
+    if (m != NULL)
+       olen += (m->m_len = wspace - state->strm.avail_out);
+
+    /*
+     * See if we managed to reduce the size of the packet.
+     * If the compressor just gave us a single zero byte, it means
+     * the packet was incompressible.
+     */
+    if (m != NULL && olen < orig_len
+       && !(olen == PPP_HDRLEN + 3 && *wptr == 0)) {
+       state->stats.comp_bytes += olen;
+       state->stats.comp_packets++;
+    } else {
+       if (*mret != NULL) {
+           m_freem(*mret);
+           *mret = NULL;
+       }
+       state->stats.inc_bytes += orig_len;
+       state->stats.inc_packets++;
+       olen = orig_len;
+    }
+    state->stats.unc_bytes += orig_len;
+    state->stats.unc_packets++;
+
+    return olen;
+}
+
+static void
+z_comp_stats(arg, stats)
+    void *arg;
+    struct compstat *stats;
+{
+    struct deflate_state *state = (struct deflate_state *) arg;
+    u_int out;
+
+    *stats = state->stats;
+    stats->ratio = stats->unc_bytes;
+    out = stats->comp_bytes + stats->inc_bytes;
+    if (stats->ratio <= 0x7ffffff)
+       stats->ratio <<= 8;
+    else
+       out >>= 8;
+    if (out != 0)
+       stats->ratio /= out;
+}
+
+/*
+ * Allocate space for a decompressor.
+ */
+static void *
+z_decomp_alloc(options, opt_len)
+    u_char *options;
+    int opt_len;
+{
+    struct deflate_state *state;
+    int w_size;
+
+    if (opt_len != CILEN_DEFLATE || options[0] != CI_DEFLATE
+       || options[1] != CILEN_DEFLATE
+       || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
+       || options[3] != DEFLATE_CHK_SEQUENCE)
+       return NULL;
+    w_size = DEFLATE_SIZE(options[2]);
+    if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
+       return NULL;
+
+    MALLOC(state, struct deflate_state *, sizeof(struct deflate_state),
+          M_DEVBUF, M_NOWAIT);
+    if (state == NULL)
+       return NULL;
+
+    state->strm.next_out = NULL;
+    state->strm.zalloc = zalloc;
+    state->strm.zfree = zfree;
+    if (inflateInit2(&state->strm, -w_size) != Z_OK) {
+       FREE(state, M_DEVBUF);
+       return NULL;
+    }
+
+    state->w_size = w_size;
+    bzero(&state->stats, sizeof(state->stats));
+    return (void *) state;
+}
+
+static void
+z_decomp_free(arg)
+    void *arg;
+{
+    struct deflate_state *state = (struct deflate_state *) arg;
+
+    inflateEnd(&state->strm);
+    FREE(state, M_DEVBUF);
+}
+
+static int
+z_decomp_init(arg, options, opt_len, unit, hdrlen, mru, debug)
+    void *arg;
+    u_char *options;
+    int opt_len, unit, hdrlen, mru, debug;
+{
+    struct deflate_state *state = (struct deflate_state *) arg;
+
+    if (opt_len < CILEN_DEFLATE || options[0] != CI_DEFLATE
+       || options[1] != CILEN_DEFLATE
+       || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
+       || DEFLATE_SIZE(options[2]) != state->w_size
+       || options[3] != DEFLATE_CHK_SEQUENCE)
+       return 0;
+
+    state->seqno = 0;
+    state->unit = unit;
+    state->hdrlen = hdrlen;
+    state->debug = debug;
+    state->mru = mru;
+
+    inflateReset(&state->strm);
+
+    return 1;
+}
+
+static void
+z_decomp_reset(arg)
+    void *arg;
+{
+    struct deflate_state *state = (struct deflate_state *) arg;
+
+    state->seqno = 0;
+    inflateReset(&state->strm);
+}
+
+/*
+ * Decompress a Deflate-compressed packet.
+ *
+ * Because of patent problems, we return DECOMP_ERROR for errors
+ * found by inspecting the input data and for system problems, but
+ * DECOMP_FATALERROR for any errors which could possibly be said to
+ * be being detected "after" decompression.  For DECOMP_ERROR,
+ * we can issue a CCP reset-request; for DECOMP_FATALERROR, we may be
+ * infringing a patent of Motorola's if we do, so we take CCP down
+ * instead.
+ *
+ * Given that the frame has the correct sequence number and a good FCS,
+ * errors such as invalid codes in the input most likely indicate a
+ * bug, so we return DECOMP_FATALERROR for them in order to turn off
+ * compression, even though they are detected by inspecting the input.
+ */
+int
+z_decompress(arg, mi, mop)
+    void *arg;
+    struct mbuf *mi, **mop;
+{
+    struct deflate_state *state = (struct deflate_state *) arg;
+    struct mbuf *mo, *mo_head;
+    u_char *rptr, *wptr;
+    int rlen, olen, ospace;
+    int seq, i, flush, r, decode_proto;
+    u_char hdr[PPP_HDRLEN + DEFLATE_OVHD];
+
+    *mop = NULL;
+    rptr = mtod(mi, u_char *);
+    rlen = mi->m_len;
+    for (i = 0; i < PPP_HDRLEN + DEFLATE_OVHD; ++i) {
+       while (rlen <= 0) {
+           mi = mi->m_next;
+           if (mi == NULL)
+               return DECOMP_ERROR;
+           rptr = mtod(mi, u_char *);
+           rlen = mi->m_len;
+       }
+       hdr[i] = *rptr++;
+       --rlen;
+    }
+
+    /* Check the sequence number. */
+    seq = (hdr[PPP_HDRLEN] << 8) + hdr[PPP_HDRLEN+1];
+    if (seq != state->seqno) {
+       if (state->debug)
+           printf("z_decompress%d: bad seq # %d, expected %d\n",
+                  state->unit, seq, state->seqno);
+       return DECOMP_ERROR;
+    }
+    ++state->seqno;
+
+    /* Allocate an output mbuf. */
+    MGETHDR(mo, M_DONTWAIT, MT_DATA);
+    if (mo == NULL)
+       return DECOMP_ERROR;
+    mo_head = mo;
+    mo->m_len = 0;
+    mo->m_next = NULL;
+    MCLGET(mo, M_DONTWAIT);
+    ospace = M_TRAILINGSPACE(mo);
+    if (state->hdrlen + PPP_HDRLEN < ospace) {
+       mo->m_data += state->hdrlen;
+       ospace -= state->hdrlen;
+    }
+
+    /*
+     * Fill in the first part of the PPP header.  The protocol field
+     * comes from the decompressed data.
+     */
+    wptr = mtod(mo, u_char *);
+    wptr[0] = PPP_ADDRESS(hdr);
+    wptr[1] = PPP_CONTROL(hdr);
+    wptr[2] = 0;
+
+    /*
+     * Set up to call inflate.  We set avail_out to 1 initially so we can
+     * look at the first byte of the output and decide whether we have
+     * a 1-byte or 2-byte protocol field.
+     */
+    state->strm.next_in = rptr;
+    state->strm.avail_in = rlen;
+    mi = mi->m_next;
+    flush = (mi == NULL)? Z_PACKET_FLUSH: Z_NO_FLUSH;
+    rlen += PPP_HDRLEN + DEFLATE_OVHD;
+    state->strm.next_out = wptr + 3;
+    state->strm.avail_out = 1;
+    decode_proto = 1;
+    olen = PPP_HDRLEN;
+
+    /*
+     * Call inflate, supplying more input or output as needed.
+     */
+    for (;;) {
+       r = inflate(&state->strm, flush);
+       if (r != Z_OK) {
+           if (state->debug)
+               printf("z_decompress%d: inflate returned %d (%s)\n",
+                      state->unit, r, (state->strm.msg? state->strm.msg: ""));
+           m_freem(mo_head);
+           return DECOMP_FATALERROR;
+       }
+       if (flush != Z_NO_FLUSH && state->strm.avail_out != 0)
+           break;              /* all done */
+       if (state->strm.avail_in == 0 && mi != NULL) {
+           state->strm.next_in = mtod(mi, u_char *);
+           state->strm.avail_in = mi->m_len;
+           rlen += mi->m_len;
+           mi = mi->m_next;
+           if (mi == NULL)
+               flush = Z_PACKET_FLUSH;
+       }
+       if (state->strm.avail_out == 0) {
+           if (decode_proto) {
+               state->strm.avail_out = ospace - PPP_HDRLEN;
+               if ((wptr[3] & 1) == 0) {
+                   /* 2-byte protocol field */
+                   wptr[2] = wptr[3];
+                   --state->strm.next_out;
+                   ++state->strm.avail_out;
+                   --olen;
+               }
+               decode_proto = 0;
+           } else {
+               mo->m_len = ospace;
+               olen += ospace;
+               MGET(mo->m_next, M_DONTWAIT, MT_DATA);
+               mo = mo->m_next;
+               if (mo == NULL) {
+                   m_freem(mo_head);
+                   return DECOMP_ERROR;
+               }
+               MCLGET(mo, M_DONTWAIT);
+               state->strm.next_out = mtod(mo, u_char *);
+               state->strm.avail_out = ospace = M_TRAILINGSPACE(mo);
+           }
+       }
+    }
+    if (decode_proto) {
+       m_freem(mo_head);
+       return DECOMP_ERROR;
+    }
+    olen += (mo->m_len = ospace - state->strm.avail_out);
+
+    state->stats.unc_bytes += olen;
+    state->stats.unc_packets++;
+    state->stats.comp_bytes += rlen;
+    state->stats.comp_packets++;
+
+    *mop = mo_head;
+    return DECOMP_OK;
+}
+
+/*
+ * Incompressible data has arrived - add it to the history.
+ */
+static void
+z_incomp(arg, mi)
+    void *arg;
+    struct mbuf *mi;
+{
+    struct deflate_state *state = (struct deflate_state *) arg;
+    u_char *rptr;
+    int rlen, proto, r;
+
+    /*
+     * Check that the protocol is one we handle.
+     */
+    rptr = mtod(mi, u_char *);
+    proto = PPP_PROTOCOL(rptr);
+    if (proto > 0x3fff || proto == 0xfd || proto == 0xfb)
+       return;
+
+    ++state->seqno;
+
+    /*
+     * Iterate through the mbufs, adding the characters in them
+     * to the decompressor's history.  For the first mbuf, we start
+     * at the either the 1st or 2nd byte of the protocol field,
+     * depending on whether the protocol value is compressible.
+     */
+    rlen = mi->m_len;
+    state->strm.next_in = rptr + 3;
+    state->strm.avail_in = rlen - 3;
+    if (proto > 0xff) {
+       --state->strm.next_in;
+       ++state->strm.avail_in;
+    }
+    for (;;) {
+       r = inflateIncomp(&state->strm);
+       if (r != Z_OK) {
+           /* gak! */
+           if (state->debug) {
+               printf("z_incomp%d: inflateIncomp returned %d (%s)\n",
+                      state->unit, r, (state->strm.msg? state->strm.msg: ""));
+           }
+           return;
+       }
+       mi = mi->m_next;
+       if (mi == NULL)
+           break;
+       state->strm.next_in = mtod(mi, u_char *);
+       state->strm.avail_in = mi->m_len;
+       rlen += mi->m_len;
+    }
+
+    /*
+     * Update stats.
+     */
+    state->stats.inc_bytes += rlen;
+    state->stats.inc_packets++;
+    state->stats.unc_bytes += rlen;
+    state->stats.unc_packets++;
+}
+
+#endif /* DO_DEFLATE */
index 40d6cf2a13d391478a9094bb72861fe4bb0ce65e..38d643897751ef3860778d51254c73b406131ec8 100644 (file)
@@ -62,7 +62,7 @@
  * Extensively modified by Paul Mackerras (paulus@cs.anu.edu.au).
  * Cleaned up a lot of the mbuf-related code to fix bugs that
  * caused system crashes and packet corruption.  Changed pppstart
- * so that it doesn't just give up with a collision if the whole
+ * so that it doesn't just give up with a "collision" if the whole
  * packet doesn't fit in the output ring buffer.
  *
  * Added priority queueing for interactive IP packets, following
@@ -73,8 +73,9 @@
  * Robert Olsson <robert@robur.slu.se> and Paul Mackerras.
  */
 
-/* $Id: ppp_tty.c,v 1.6 1995/10/27 04:00:10 paulus Exp $ */
+/* $Id: ppp_tty.c,v 1.7 1996/07/01 01:24:28 paulus Exp $ */
 /* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */
+/* from NetBSD: if_ppp.c,v 1.15.2.2 1994/07/28 05:17:58 cgd Exp */
 
 #include "ppp.h"
 #if NPPP > 0
@@ -156,6 +157,7 @@ static void ppplogchar __P((struct ppp_softc *, int));
 #define CCOUNT(q)      ((q)->c_cc)
 
 #define t_sc           T_LINEP
+#define PPP_LOWAT      100     /* Process more output when < LOWAT on queue */
 #define        PPP_HIWAT       400     /* Don't start a new packet if HIWAT on que */
 
 /*
@@ -170,7 +172,7 @@ pppopen(dev, tp)
     register struct tty *tp;
 {
     register struct ppp_softc *sc;
-    int error, s, i;
+    int error, s;
     struct proc *p = u.u_procp;
 
     if (!suser())
@@ -227,7 +229,6 @@ pppclose(tp, flag)
     int flag;
 {
     register struct ppp_softc *sc;
-    struct mbuf *m;
     int s;
 
     s = spltty();
@@ -488,62 +489,20 @@ pppfcs(fcs, cp, len)
 }
 
 /*
- * This gets called from pppoutput when a new packet is
- * put on a queue, at splnet.
+ * This gets called at splnet from if_ppp.c at various times
+ * when there is data ready to be sent.
  */
 static void
 pppasyncstart(sc)
     register struct ppp_softc *sc;
 {
     register struct tty *tp = (struct tty *) sc->sc_devp;
-    int s;
-
-    s = spltty();
-    pppstart(tp);
-    splx(s);
-}
-
-/*
- * This gets called when a received packet is placed on
- * the inq, at splnet.
- */
-static void
-pppasyncctlp(sc)
-    struct ppp_softc *sc;
-{
-    struct tty *tp;
-    int s;
-
-    /* Put a placeholder byte in canq for ttselect()/ttnread(). */
-    s = spltty();
-    tp = (struct tty *) sc->sc_devp;
-    putc(0, &tp->t_canq);
-    ttwakeup(tp);
-    splx(s);
-}
-
-/*
- * Start output on async tty interface.  Get another datagram
- * to send from the interface queue and start sending it.
- * Called at spltty or higher.
- */
-int
-pppstart(tp)
-    register struct tty *tp;
-{
-    register struct ppp_softc *sc = (struct ppp_softc *) tp->t_sc;
     register struct mbuf *m;
     register int len;
     register u_char *start, *stop, *cp;
-    int n, s, ndone, done, idle;
+    int n, ndone, done, idle;
     struct mbuf *m2;
-
-    if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0
-       || sc == NULL || tp != (struct tty *) sc->sc_devp) {
-       if (tp->t_oproc != NULL)
-           (*tp->t_oproc)(tp);
-       return 0;
-    }
+    int s;
 
     idle = 0;
     while (CCOUNT(&tp->t_outq) < PPP_HIWAT) {
@@ -568,7 +527,7 @@ pppstart(tp)
             * the line may have been idle for some time.
             */
            if (CCOUNT(&tp->t_outq) == 0) {
-               ++sc->sc_bytessent;
+               ++sc->sc_stats.ppp_obytes;
                (void) putc(PPP_FLAG, &tp->t_outq);
            }
 
@@ -593,24 +552,27 @@ pppstart(tp)
                    ndone = n - b_to_q(start, n, &tp->t_outq);
                    len -= ndone;
                    start += ndone;
-                   sc->sc_bytessent += ndone;
+                   sc->sc_stats.ppp_obytes += ndone;
 
                    if (ndone < n)
                        break;  /* packet doesn't fit */
                }
                /*
                 * If there are characters left in the mbuf,
-                * the first one must be special..
+                * the first one must be special.
                 * Put it out in a different form.
                 */
                if (len) {
+                   s = spltty();
                    if (putc(PPP_ESCAPE, &tp->t_outq))
                        break;
                    if (putc(*start ^ PPP_TRANS, &tp->t_outq)) {
                        (void) unputc(&tp->t_outq);
+                       splx(s);
                        break;
                    }
-                   sc->sc_bytessent += 2;
+                   splx(s);
+                   sc->sc_stats.ppp_obytes += 2;
                    start++;
                    len--;
                }
@@ -650,6 +612,7 @@ pppstart(tp)
                 * Try to output the FCS and flag.  If the bytes
                 * don't all fit, back out.
                 */
+               s = spltty();
                for (q = endseq; q < p; ++q)
                    if (putc(*q, &tp->t_outq)) {
                        done = 0;
@@ -657,7 +620,9 @@ pppstart(tp)
                            unputc(&tp->t_outq);
                        break;
                    }
-               sc->sc_bytessent += q - endseq;
+               splx(s);
+               if (done)
+                   sc->sc_stats.ppp_obytes += q - endseq;
            }
 
            if (!done) {
@@ -671,27 +636,24 @@ pppstart(tp)
            m = m2;
            if (m == NULL) {
                /* Finished a packet */
-               sc->sc_if.if_opackets++;
                break;
            }
            sc->sc_outfcs = pppfcs(sc->sc_outfcs, mtod(m, u_char *), m->m_len);
        }
 
        /*
-        * Here we have either finished a packet (m == NULL)
-        * or filled up the output queue (m != NULL).
+        * If m == NULL, we have finished a packet.
+        * If m != NULL, we've either done as much work this time
+        * as we need to, or else we've filled up the output queue.
         */
        sc->sc_outm = m;
        if (m)
            break;
     }
 
-    /*
-     * If there is stuff in the output queue, send it now.
-     * We are being called in lieu of ttstart and must do what it would.
-     */
-    if (tp->t_oproc != NULL)
-       (*tp->t_oproc)(tp);
+    /* Call pppstart to start output again if necessary. */
+    s = spltty();
+    pppstart(tp);
 
     /*
      * This timeout is needed for operation on a pseudo-tty,
@@ -703,6 +665,58 @@ pppstart(tp)
        sc->sc_flags |= SC_TIMEOUT;
     }
 
+    splx(s);
+}
+
+/*
+ * This gets called when a received packet is placed on
+ * the inq, at splsoftnet.
+ */
+static void
+pppasyncctlp(sc)
+    struct ppp_softc *sc;
+{
+    struct tty *tp;
+    int s;
+
+    /* Put a placeholder byte in canq for ttselect()/ttnread(). */
+    s = spltty();
+    tp = (struct tty *) sc->sc_devp;
+    putc(0, &tp->t_canq);
+    ttwakeup(tp);
+    splx(s);
+}
+
+/*
+ * Start output on async tty interface.  If the transmit queue
+ * has drained sufficiently, arrange for pppasyncstart to be
+ * called later at splsoftnet.
+ * Called at spltty or higher.
+ */
+int
+pppstart(tp)
+    register struct tty *tp;
+{
+    register struct ppp_softc *sc = (struct ppp_softc *) tp->t_sc;
+
+    /*
+     * If there is stuff in the output queue, send it now.
+     * We are being called in lieu of ttstart and must do what it would.
+     */
+    if (tp->t_oproc != NULL)
+       (*tp->t_oproc)(tp);
+
+    /*
+     * If the transmit queue has drained and the tty has not hung up
+     * or been disconnected from the ppp unit, then tell if_ppp.c that
+     * we need more output.
+     */
+    if (CCOUNT(&tp->t_outq) < PPP_LOWAT
+       && !((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0)
+       && sc != NULL && tp == (struct tty *) sc->sc_devp) {
+       ppp_restart(sc);
+    }
+
     return 0;
 }
 
@@ -732,9 +746,7 @@ pppgetm(sc)
 {
     struct mbuf *m, **mp, *p;
     int len;
-    int s;
 
-    s = spltty();
     mp = &sc->sc_m;
     for (len = sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN; len > 0; ){
        if ((m = *mp) == NULL) {
@@ -747,7 +759,6 @@ pppgetm(sc)
        len -= M_DATASIZE(m);
        mp = &m->m_next;
     }
-    splx(s);
 }
 
 /*
@@ -772,21 +783,30 @@ pppinput(c, tp)
     if (sc == NULL || tp != (struct tty *) sc->sc_devp)
        return 0;
 
-    s = spltty();              /* should be unnecessary */
     ++tk_nin;
-    ++sc->sc_bytesrcvd;
+    ++sc->sc_stats.ppp_ibytes;
+
+    if (c & TTY_FE) {
+       /* framing error or overrun on this char - abort packet */
+       if (sc->sc_flags & SC_DEBUG)
+           printf("ppp%d: bad char %x\n", sc->sc_if.if_unit, c);
+       goto flush;
+    }
 
     c &= 0xff;
 
-    if (sc->sc_flags & SC_XONXOFF) {
-       if (c == XOFF) {
+    /*
+     * Handle software flow control of output.
+     */
+    if (tp->t_iflag & IXON) {
+       if (c == tp->t_cc[VSTOP] && tp->t_cc[VSTOP] != _POSIX_VDISABLE) {
            if ((tp->t_state & TS_TTSTOP) == 0) {
                tp->t_state |= TS_TTSTOP;
                (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
            }
            return 0;
        }
-       if (c == XON) {
+       if (c == tp->t_cc[VSTART] && tp->t_cc[VSTART] != _POSIX_VDISABLE) {
            tp->t_state &= ~TS_TTSTOP;
            if (tp->t_oproc != NULL)
                (*tp->t_oproc)(tp);
@@ -794,6 +814,7 @@ pppinput(c, tp)
        }
     }
 
+    s = spltty();
     if (c & 0x80)
        sc->sc_flags |= SC_RCV_B7_1;
     else
@@ -802,6 +823,7 @@ pppinput(c, tp)
        sc->sc_flags |= SC_RCV_ODDP;
     else
        sc->sc_flags |= SC_RCV_EVNP;
+    splx(s);
 
     if (sc->sc_flags & SC_LOG_RAWIN)
        ppplogchar(sc, c);
@@ -818,13 +840,15 @@ pppinput(c, tp)
         * abort sequence "}~".
         */
        if (sc->sc_flags & (SC_FLUSH | SC_ESCAPED)
-           || ilen > 0 && sc->sc_fcs != PPP_GOODFCS) {
+           || (ilen > 0 && sc->sc_fcs != PPP_GOODFCS)) {
+           s = spltty();
            sc->sc_flags |= SC_PKTLOST; /* note the dropped packet */
            if ((sc->sc_flags & (SC_FLUSH | SC_ESCAPED)) == 0){
                if (sc->sc_flags & SC_DEBUG)
-                   printf("ppp%d: bad fcs %x\n", sc->sc_if.if_unit,
-                          sc->sc_fcs);
+                   printf("ppp%d: bad fcs %x, pkt len %d\n",
+                          sc->sc_if.if_unit, sc->sc_fcs, ilen);
                sc->sc_if.if_ierrors++;
+               sc->sc_stats.ppp_ierrors++;
            } else
                sc->sc_flags &= ~(SC_FLUSH | SC_ESCAPED);
            splx(s);
@@ -835,10 +859,12 @@ pppinput(c, tp)
            if (ilen) {
                if (sc->sc_flags & SC_DEBUG)
                    printf("ppp%d: too short (%d)\n", sc->sc_if.if_unit, ilen);
+               s = spltty();
                sc->sc_if.if_ierrors++;
+               sc->sc_stats.ppp_ierrors++;
                sc->sc_flags |= SC_PKTLOST;
+               splx(s);
            }
-           splx(s);
            return 0;
        }
 
@@ -859,25 +885,26 @@ pppinput(c, tp)
        sc->sc_mc->m_next = NULL;
 
        ppppktin(sc, m, sc->sc_flags & SC_PKTLOST);
-       sc->sc_flags &= ~SC_PKTLOST;
+       if (sc->sc_flags & SC_PKTLOST) {
+           s = spltty();
+           sc->sc_flags &= ~SC_PKTLOST;
+           splx(s);
+       }
 
        pppgetm(sc);
-       splx(s);
        return 0;
     }
 
     if (sc->sc_flags & SC_FLUSH) {
        if (sc->sc_flags & SC_LOG_FLUSH)
            ppplogchar(sc, c);
-       splx(s);
        return 0;
     }
 
-    if (c < 0x20 && (sc->sc_rasyncmap & (1 << c))) {
-       splx(s);
+    if (c < 0x20 && (sc->sc_rasyncmap & (1 << c)))
        return 0;
-    }
 
+    s = spltty();
     if (sc->sc_flags & SC_ESCAPED) {
        sc->sc_flags &= ~SC_ESCAPED;
        c ^= PPP_TRANS;
@@ -886,6 +913,7 @@ pppinput(c, tp)
        splx(s);
        return 0;
     }
+    splx(s);
 
     /*
      * Initialize buffer on first octet received.
@@ -971,17 +999,18 @@ pppinput(c, tp)
     ++m->m_len;
     *sc->sc_mp++ = c;
     sc->sc_fcs = PPP_FCS(sc->sc_fcs, c);
-    splx(s);
     return 0;
 
  flush:
     if (!(sc->sc_flags & SC_FLUSH)) {
+       s = spltty();
        sc->sc_if.if_ierrors++;
+       sc->sc_stats.ppp_ierrors++;
        sc->sc_flags |= SC_FLUSH;
+       splx(s);
        if (sc->sc_flags & SC_LOG_FLUSH)
            ppplogchar(sc, c);
     }
-    splx(s);
     return 0;
 }
 
@@ -995,7 +1024,7 @@ ppplogchar(sc, c)
     if (c >= 0)
        sc->sc_rawin[sc->sc_rawin_count++] = c;
     if (sc->sc_rawin_count >= sizeof(sc->sc_rawin)
-       || c < 0 && sc->sc_rawin_count > 0) {
+       || (c < 0 && sc->sc_rawin_count > 0)) {
        printf("ppp%d input: ", sc->sc_if.if_unit);
        pppdumpb(sc->sc_rawin, sc->sc_rawin_count);
        sc->sc_rawin_count = 0;
index 4512a235446da342a928ab6558d3cf938b13c08a..88fc3dbdb2c7f0458878c660de68c4c9a2194cc9 100644 (file)
@@ -1,66 +1,13 @@
-*** /usr/sys/net/net/netisr.h.orig     Fri Dec  9 09:53:17 1994
---- /usr/sys/net/net/netisr.h  Fri Dec  9 09:54:14 1994
-***************
-*** 77,82 ****
---- 77,83 ----
-  #define NETISR_LAT   14              /* same as AF_LAT */
-  #define NETISR_BSC   15              /* same as AF_BSC */
-  #define NETISR_DLO      19              /* same as AF_OSI */
-+ #define NETISR_PPP   26              /* Point-to-Point Protocol */
-  
-  #define      schednetisr(anisr)      { set_bit_atomic(anisr,&netisr); setsoftnet(); }
-  
-*** /usr/sys/net/net/conf_net.c.orig   Fri Dec  9 13:29:49 1994
---- /usr/sys/net/net/conf_net.c        Fri Dec  9 13:32:50 1994
-***************
-*** 84,89 ****
---- 84,90 ----
-  #ifdef vax
-  #include "bsc.h"
-  #endif vax
-+ #include "ppp.h"
-  
-  
-  #if ((NETHER==0 && NFDDI==0) || NINET==0)
-***************
-*** 251,257 ****
-  };
-  
-  
-! extern int rawintr(), ipintr(), nsintr(), dnetintr(), dlointr(), dliintr(), latintr(), bscintr();
-  #ifdef       __mips
-  extern int scsiisr();
-  #endif
---- 252,258 ----
-  };
-  
-  
-! extern int rawintr(), ipintr(), nsintr(), dnetintr(), dlointr(), dliintr(), latintr(), bscintr(), pppintr();
-  #ifdef       __mips
-  extern int scsiisr();
-  #endif
-***************
-*** 289,294 ****
---- 290,298 ----
-          {NETISR_SCSI,scsiisr},
-  #endif /* NSCSI > 0 || NSII > 0 || NASC > 0 */
-  #endif       /* __mips */
-+ #if NPPP > 0
-+      {NETISR_PPP,pppintr},
-+ #endif /* NPPP */
-  
-       {-1     ,0}
-  };
 *** /usr/sys/conf/mips/files.mips.orig Sat Sep 11 06:09:28 1993
 --- /usr/sys/conf/mips/files.mips      Fri Dec  9 09:32:01 1994
 ***************
-*** 115,120 ****
---- 115,122 ----
-  io/netif/if_ne.c             optional ne device-driver Binary
-  io/netif/if_sl.c             optional sl device-driver Binary Unsupported
+*** 117,122 ****
+--- 117,124 ----
   io/netif/if_ppp.c            optional ppp device-driver Notbinary
-+ io/netif/ppp_tty.c           optional ppp device-driver Notbinary
-+ io/netif/bsd-comp.c          optional ppp device-driver Notbinary
+  io/netif/ppp_tty.c           optional ppp device-driver Notbinary
+  io/netif/bsd-comp.c          optional ppp device-driver Notbinary
++ io/netif/ppp-deflate.c               optional ppp device-driver Notbinary
++ io/netif/zlib.c                      optional ppp device-driver Notbinary
   io/netif/slcompress.c                optional sl or ppp device-driver Notbinary
   io/netif/if_qe.c             optional qe device-driver Binary
   io/netif/if_uba.c            optional inet device-driver Binary