From c5871dbfa014bb554c101e65150c48fc8ba80c7b Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 1 Jul 1996 01:24:29 +0000 Subject: [PATCH] update to 2.3 based on netbsd stuff --- ultrix/bsd-comp.c | 15 +- ultrix/if_ppp.c | 248 ++++++++-------- ultrix/if_pppvar.h | 18 +- ultrix/patches | 4 +- ultrix/ppp-deflate.c | 654 +++++++++++++++++++++++++++++++++++++++++++ ultrix/ppp_tty.c | 199 +++++++------ ultrix/upgrade | 65 +---- 7 files changed, 926 insertions(+), 277 deletions(-) create mode 100644 ultrix/ppp-deflate.c diff --git a/ultrix/bsd-comp.c b/ultrix/bsd-comp.c index 12bca92..8246343 100644 --- a/ultrix/bsd-comp.c +++ b/ultrix/bsd-comp.c @@ -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) +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 diff --git a/ultrix/if_ppp.c b/ultrix/if_ppp.c index 76725fe..1aaf5cd 100644 --- a/ultrix/if_ppp.c +++ b/ultrix/if_ppp.c @@ -72,8 +72,9 @@ * Robert Olsson 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" @@ -105,13 +107,12 @@ #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 @@ -119,16 +120,9 @@ #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 diff --git a/ultrix/if_pppvar.h b/ultrix/if_pppvar.h index 4193111..25b1454 100644 --- a/ultrix/if_pppvar.h +++ b/ultrix/if_pppvar.h @@ -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)); diff --git a/ultrix/patches b/ultrix/patches index 53e5ddf..d445ca9 100644 --- a/ultrix/patches +++ b/ultrix/patches @@ -137,13 +137,15 @@ 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 index 0000000..c6e6299 --- /dev/null +++ b/ultrix/ppp-deflate.c @@ -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 */ diff --git a/ultrix/ppp_tty.c b/ultrix/ppp_tty.c index 40d6cf2..38d6438 100644 --- a/ultrix/ppp_tty.c +++ b/ultrix/ppp_tty.c @@ -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 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; diff --git a/ultrix/upgrade b/ultrix/upgrade index 4512a23..88fc3db 100644 --- a/ultrix/upgrade +++ b/ultrix/upgrade @@ -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 -- 2.39.2