summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Wemm <peter@FreeBSD.org>1997-07-01 20:44:12 +0000
committerPeter Wemm <peter@FreeBSD.org>1997-07-01 20:44:12 +0000
commit03014c1e6467405d5925f015611454c2957323d9 (patch)
tree9cde6da033ecb86d1740c3ad7d9318d255469c91
parentba33edfee8f72607d1746d94002a32b8b921bd04 (diff)
downloadsrc-test2-03014c1e6467405d5925f015611454c2957323d9.tar.gz
src-test2-03014c1e6467405d5925f015611454c2957323d9.zip
Import files from the ppp-2.3.0 dist for working on. This does not change
the present code, all existing files have left the vendor branch. There are three new files that will appear but they are not used and should not be a problem. Obtained from: Paul Mackerras, via ftp://cs.anu.edu.au/pub/software/ppp
Notes
Notes: svn path=/cvs2svn/branches/MACKERAS/; revision=27156
-rw-r--r--sys/net/bsd_comp.c25
-rw-r--r--sys/net/if_ppp.c419
-rw-r--r--sys/net/if_ppp.h16
-rw-r--r--sys/net/if_pppvar.h18
-rw-r--r--sys/net/ppp_comp.h30
-rw-r--r--sys/net/ppp_defs.h66
-rw-r--r--sys/net/ppp_tty.c254
-rw-r--r--sys/net/slcompress.c185
-rw-r--r--sys/net/slcompress.h24
9 files changed, 663 insertions, 374 deletions
diff --git a/sys/net/bsd_comp.c b/sys/net/bsd_comp.c
index 40da4e52c3bf..f4f298455de9 100644
--- a/sys/net/bsd_comp.c
+++ b/sys/net/bsd_comp.c
@@ -1,3 +1,5 @@
+/* $Id: bsd-comp.c,v 1.6 1996/08/28 06:31:58 paulus Exp $ */
+
/* Because this code is derived from the 4.3BSD compress source:
*
*
@@ -39,12 +41,11 @@
/*
* This version is for use with mbufs on BSD-derived systems.
- *
- * $Id: bsd-comp.c,v 1.11 1995/07/04 03:35:11 paulus Exp $
*/
#include <sys/param.h>
#include <sys/types.h>
+#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <net/if.h>
@@ -186,6 +187,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
*/
@@ -199,7 +206,6 @@ bsd_clear(db)
db->ratio = 0;
db->bytes_out = 0;
db->in_count = 0;
- db->incomp_count = 0;
db->checkpoint = CHECK_GAP;
}
@@ -307,7 +313,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;
@@ -405,11 +411,11 @@ bsd_init(db, options, opt_len, unit, hdrlen, mru, debug, decomp)
{
int i;
- 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
|| BSD_NBITS(options[2]) != db->maxbits
- || decomp && db->lens == NULL)
+ || (decomp && db->lens == NULL))
return 0;
if (decomp) {
@@ -479,11 +485,10 @@ bsd_compress(state, mret, mp, slen, maxolen)
struct bsd_dict *dictp;
u_char c;
int hval, disp, ent, ilen;
- struct mbuf *np;
u_char *rptr, *wptr;
u_char *cp_end;
int olen;
- struct mbuf *m, **mnp;
+ struct mbuf *m;
#define PUTBYTE(v) { \
++olen; \
@@ -708,7 +713,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;
@@ -829,7 +833,6 @@ bsd_decompress(state, cmp, dmpp)
struct mbuf *m, *dmp, *mret;
int adrs, ctrl, ilen;
int space, codelen, extra;
- struct mbuf *last;
/*
* Save the address/control from the PPP header
@@ -939,7 +942,7 @@ bsd_decompress(state, cmp, dmpp)
}
if (incode > max_ent + 2 || incode > db->maxmaxcode
- || incode > max_ent && oldcode == CLEAR) {
+ || (incode > max_ent && oldcode == CLEAR)) {
m_freem(mret);
if (db->debug) {
printf("bsd_decomp%d: bad code 0x%x oldcode=0x%x ",
diff --git a/sys/net/if_ppp.c b/sys/net/if_ppp.c
index d62251aa5dba..d9369d62c46c 100644
--- a/sys/net/if_ppp.c
+++ b/sys/net/if_ppp.c
@@ -69,8 +69,9 @@
* Paul Mackerras (paulus@cs.anu.edu.au).
*/
-/* $Id: if_ppp.c,v 1.5 1995/08/16 01:36:38 paulus Exp $ */
+/* $Id: if_ppp.c,v 1.12 1997/04/30 05:42:07 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
@@ -85,11 +86,16 @@
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/kernel.h>
+#include <sys/time.h>
+#include <sys/malloc.h>
#include <net/if.h>
#include <net/if_types.h>
#include <net/netisr.h>
#include <net/route.h>
+#ifdef PPP_FILTER
+#include <net/bpf.h>
+#endif
#if INET
#include <netinet/in.h>
@@ -100,7 +106,6 @@
#include "bpfilter.h"
#if NBPFILTER > 0
-#include <sys/time.h>
#include <net/bpf.h>
#endif
@@ -113,6 +118,8 @@
#include <net/if_pppvar.h>
#include <machine/cpu.h>
+#define splsoftnet splnet
+
#ifndef NETISR_PPP
/* This definition should be moved to net/netisr.h */
#define NETISR_PPP 26 /* PPP software interrupt */
@@ -123,17 +130,11 @@
#include <net/ppp-comp.h>
#endif
-void pppattach __P((void));
-int pppioctl __P((struct ppp_softc *sc, int cmd, caddr_t data, int flag,
- struct proc *));
-int pppoutput __P((struct ifnet *ifp, struct mbuf *m0,
- struct sockaddr *dst, struct rtentry *rtp));
-int pppsioctl __P((struct ifnet *ifp, int cmd, caddr_t data));
-void pppintr __P((void));
-
+static int pppsioctl __P((struct ifnet *, int, caddr_t));
+static int pppoutput __P((struct ifnet *, struct mbuf *,
+ struct sockaddr *, struct rtentry *));
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,11 +167,15 @@ static void pppdumpm __P((struct mbuf *m0));
*/
extern struct compressor ppp_bsd_compress;
+extern struct compressor ppp_deflate;
struct compressor *ppp_compressors[8] = {
#if DO_BSD_COMPRESS
&ppp_bsd_compress,
#endif
+#if DO_DEFLATE
+ &ppp_deflate,
+#endif
NULL
};
#endif /* PPP_COMPRESS */
@@ -205,7 +210,7 @@ pppattach()
bpfattach(&sc->sc_bpf, &sc->sc_if, DLT_PPP, PPP_HDRLEN);
#endif
}
- netisrs[NETISR_PPP] = ppp_intr;
+ netisrs[NETISR_PPP] = pppintr;
}
/*
@@ -232,8 +237,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
- vj_compress_init(&sc->sc_comp, -1);
+ MALLOC(sc->sc_comp, struct vjcompress *, sizeof(struct vjcompress),
+ M_DEVBUF, M_NOWAIT);
+ if (sc->sc_comp)
+ vj_compress_init(sc->sc_comp, -1);
#endif
#ifdef PPP_COMPRESS
sc->sc_xc_state = NULL;
@@ -249,7 +258,7 @@ pppalloc(pid)
}
/*
- * Deallocate a ppp unit. Must be called at splnet or higher.
+ * Deallocate a ppp unit. Must be called at splsoftnet or higher.
*/
void
pppdealloc(sc)
@@ -292,6 +301,24 @@ pppdealloc(sc)
sc->sc_xc_state = NULL;
sc->sc_rc_state = NULL;
#endif /* PPP_COMPRESS */
+#ifdef PPP_FILTER
+ if (sc->sc_pass_filt.bf_insns != 0) {
+ FREE(sc->sc_pass_filt.bf_insns, M_DEVBUF);
+ sc->sc_pass_filt.bf_insns = 0;
+ sc->sc_pass_filt.bf_len = 0;
+ }
+ if (sc->sc_active_filt.bf_insns != 0) {
+ FREE(sc->sc_active_filt.bf_insns, M_DEVBUF);
+ sc->sc_active_filt.bf_insns = 0;
+ sc->sc_active_filt.bf_len = 0;
+ }
+#endif /* PPP_FILTER */
+#ifdef VJC
+ if (sc->sc_comp != 0) {
+ FREE(sc->sc_comp, M_DEVBUF);
+ sc->sc_comp = 0;
+ }
+#endif
}
/*
@@ -300,8 +327,9 @@ pppdealloc(sc)
int
pppioctl(sc, cmd, data, flag, p)
struct ppp_softc *sc;
+ int cmd;
caddr_t data;
- int cmd, flag;
+ int flag;
struct proc *p;
{
int s, error, flags, mru, nb, npx;
@@ -309,6 +337,11 @@ pppioctl(sc, cmd, data, flag, p)
struct compressor **cp;
struct npioctl *npi;
time_t t;
+#ifdef PPP_FILTER
+ struct bpf_program *bp, *nbp;
+ struct bpf_insn *newcode, *oldcode;
+ int newcodelen;
+#endif /* PPP_FILTER */
#ifdef PPP_COMPRESS
u_char ccp_option[CCP_MAX_OPTION_LENGTH];
#endif
@@ -327,10 +360,10 @@ pppioctl(sc, cmd, data, flag, p)
break;
case PPPIOCSFLAGS:
- if (error = suser(p->p_ucred, &p->p_acflag))
+ if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
return (error);
flags = *(int *)data & SC_MASK;
- s = splnet();
+ s = splsoftnet();
#ifdef PPP_COMPRESS
if (sc->sc_flags & SC_CCP_OPEN && !(flags & SC_CCP_OPEN))
ppp_ccp_closed(sc);
@@ -341,7 +374,7 @@ pppioctl(sc, cmd, data, flag, p)
break;
case PPPIOCSMRU:
- if (error = suser(p->p_ucred, &p->p_acflag))
+ if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
return (error);
mru = *(int *)data;
if (mru >= PPP_MRU && mru <= PPP_MAXMRU)
@@ -354,29 +387,31 @@ pppioctl(sc, cmd, data, flag, p)
#ifdef VJC
case PPPIOCSMAXCID:
- if (error = suser(p->p_ucred, &p->p_acflag))
+ if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
return (error);
- s = splnet();
- vj_compress_init(&sc->sc_comp, *(int *)data);
- splx(s);
+ if (sc->sc_comp) {
+ s = splsoftnet();
+ vj_compress_init(sc->sc_comp, *(int *)data);
+ splx(s);
+ }
break;
#endif
case PPPIOCXFERUNIT:
- if (error = suser(p->p_ucred, &p->p_acflag))
+ if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
return (error);
sc->sc_xfer = p->p_pid;
break;
#ifdef PPP_COMPRESS
case PPPIOCSCOMPRESS:
- if (error = suser(p->p_ucred, &p->p_acflag))
+ if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
return (error);
odp = (struct ppp_option_data *) data;
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);
@@ -387,8 +422,8 @@ pppioctl(sc, cmd, data, flag, p)
* a compressor or decompressor.
*/
error = 0;
- s = splnet();
if (odp->transmit) {
+ s = splsoftnet();
if (sc->sc_xc_state != NULL)
(*sc->sc_xcomp->comp_free)(sc->sc_xc_state);
sc->sc_xcomp = *cp;
@@ -401,7 +436,9 @@ pppioctl(sc, cmd, data, flag, p)
}
splimp();
sc->sc_flags &= ~SC_COMP_RUN;
+ splx(s);
} else {
+ s = splsoftnet();
if (sc->sc_rc_state != NULL)
(*sc->sc_rcomp->decomp_free)(sc->sc_rc_state);
sc->sc_rcomp = *cp;
@@ -414,8 +451,8 @@ pppioctl(sc, cmd, data, flag, p)
}
splimp();
sc->sc_flags &= ~SC_DECOMP_RUN;
+ splx(s);
}
- splx(s);
return (error);
}
if (sc->sc_flags & SC_DEBUG)
@@ -438,10 +475,10 @@ pppioctl(sc, cmd, data, flag, p)
if (cmd == PPPIOCGNPMODE) {
npi->mode = sc->sc_npmode[npx];
} else {
- if (error = suser(p->p_ucred, &p->p_acflag))
+ if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
return (error);
if (npi->mode != sc->sc_npmode[npx]) {
- s = splimp();
+ s = splsoftnet();
sc->sc_npmode[npx] = npi->mode;
if (npi->mode != NPMODE_QUEUE) {
ppp_requeue(sc);
@@ -453,13 +490,47 @@ pppioctl(sc, cmd, data, flag, p)
break;
case PPPIOCGIDLE:
- s = splimp();
+ s = splsoftnet();
t = time.tv_sec;
((struct ppp_idle *)data)->xmit_idle = t - sc->sc_last_sent;
((struct ppp_idle *)data)->recv_idle = t - sc->sc_last_recv;
splx(s);
break;
+#ifdef PPP_FILTER
+ case PPPIOCSPASS:
+ case PPPIOCSACTIVE:
+ nbp = (struct bpf_program *) data;
+ if ((unsigned) nbp->bf_len > BPF_MAXINSNS)
+ return EINVAL;
+ newcodelen = nbp->bf_len * sizeof(struct bpf_insn);
+ if (newcodelen != 0) {
+ MALLOC(newcode, struct bpf_insn *, newcodelen, M_DEVBUF, M_WAITOK);
+ if (newcode == 0) {
+ return EINVAL; /* or sumpin */
+ }
+ if ((error = copyin((caddr_t)nbp->bf_insns, (caddr_t)newcode,
+ newcodelen)) != 0) {
+ FREE(newcode, M_DEVBUF);
+ return error;
+ }
+ if (!bpf_validate(newcode, nbp->bf_len)) {
+ FREE(newcode, M_DEVBUF);
+ return EINVAL;
+ }
+ } else
+ newcode = 0;
+ bp = (cmd == PPPIOCSPASS)? &sc->sc_pass_filt: &sc->sc_active_filt;
+ oldcode = bp->bf_insns;
+ s = splimp();
+ bp->bf_len = nbp->bf_len;
+ bp->bf_insns = newcode;
+ splx(s);
+ if (oldcode != 0)
+ FREE(oldcode, M_DEVBUF);
+ break;
+#endif
+
default:
return (-1);
}
@@ -469,7 +540,7 @@ pppioctl(sc, cmd, data, flag, p)
/*
* Process an ioctl request to the ppp network interface.
*/
-int
+static int
pppsioctl(ifp, cmd, data)
register struct ifnet *ifp;
int cmd;
@@ -502,7 +573,7 @@ pppsioctl(ifp, cmd, data)
break;
case SIOCSIFMTU:
- if (error = suser(p->p_ucred, &p->p_acflag))
+ if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
break;
sc->sc_if.if_mtu = ifr->ifr_mtu;
break;
@@ -513,6 +584,10 @@ pppsioctl(ifp, cmd, data)
case SIOCADDMULTI:
case SIOCDELMULTI:
+ if (ifr == 0) {
+ error = EAFNOSUPPORT;
+ break;
+ }
switch(ifr->ifr_addr.sa_family) {
#ifdef INET
case AF_INET:
@@ -527,21 +602,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;
@@ -575,16 +647,17 @@ pppoutput(ifp, m0, dst, rtp)
struct rtentry *rtp;
{
register struct ppp_softc *sc = &ppp_softc[ifp->if_unit];
- struct ppp_header *ph;
int protocol, address, control;
u_char *cp;
int s, error;
struct ip *ip;
struct ifqueue *ifq;
enum NPmode mode;
+ int len;
+ struct mbuf *m;
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;
}
@@ -655,11 +728,45 @@ pppoutput(ifp, m0, dst, rtp)
*cp++ = protocol & 0xff;
m0->m_len += PPP_HDRLEN;
+ len = 0;
+ for (m = m0; m != 0; m = m->m_next)
+ len += m->m_len;
+
if (sc->sc_flags & SC_LOG_OUTPKT) {
printf("ppp%d output: ", ifp->if_unit);
pppdumpm(m0);
}
+ if ((protocol & 0x8000) == 0) {
+#ifdef PPP_FILTER
+ /*
+ * Apply the pass and active filters to the packet,
+ * but only if it is a data packet.
+ */
+ *mtod(m0, u_char *) = 1; /* indicates outbound */
+ if (sc->sc_pass_filt.bf_insns != 0
+ && bpf_filter(sc->sc_pass_filt.bf_insns, (u_char *) m0,
+ len, 0) == 0) {
+ error = 0; /* drop this packet */
+ goto bad;
+ }
+
+ /*
+ * Update the time we sent the most recent packet.
+ */
+ if (sc->sc_active_filt.bf_insns == 0
+ || bpf_filter(sc->sc_active_filt.bf_insns, (u_char *) m0, len, 0))
+ sc->sc_last_sent = time.tv_sec;
+
+ *mtod(m0, u_char *) = address;
+#else
+ /*
+ * Update the time we sent the most recent data packet.
+ */
+ sc->sc_last_sent = time.tv_sec;
+#endif /* PPP_FILTER */
+ }
+
#if NBPFILTER > 0
/*
* See if bpf wants to look at the packet.
@@ -671,7 +778,7 @@ pppoutput(ifp, m0, dst, rtp)
/*
* Put the packet on the appropriate queue.
*/
- s = splimp(); /* splnet should be OK now */
+ s = splsoftnet();
if (mode == NPMODE_QUEUE) {
/* XXX we should limit the number of packets on this queue */
*sc->sc_npqtail = m0;
@@ -679,16 +786,20 @@ pppoutput(ifp, m0, dst, rtp)
sc->sc_npqtail = &m0->m_nextpkt;
} else {
ifq = (m0->m_flags & M_HIGHPRI)? &sc->sc_fastq: &ifp->if_snd;
- if (IF_QFULL(ifq)) {
+ if (IF_QFULL(ifq) && dst->sa_family != AF_UNSPEC) {
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_lastchange = time;
+ ifp->if_opackets++;
+ ifp->if_obytes += len;
splx(s);
return (0);
@@ -701,7 +812,7 @@ bad:
/*
* After a change in the NPmode for some NP, move packets from the
* npqueue to the send queue or the fast queue as appropriate.
- * Should be called at splimp (actually splnet would probably suffice).
+ * Should be called at splsoftnet.
*/
static void
ppp_requeue(sc)
@@ -731,6 +842,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;
@@ -750,78 +862,33 @@ ppp_requeue(sc)
}
/*
- * Get a packet to send. This procedure is intended to be called
- * at spltty()/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 (;;) {
- IF_DEQUEUE(&sc->sc_rawq, m);
- 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;
/*
* Grab a packet to send: first try the fast queue, then the
@@ -831,7 +898,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.
@@ -844,16 +913,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;
@@ -867,7 +931,7 @@ ppp_outpkt(sc)
}
/* this code assumes the IP/TCP header is in one non-shared mbuf */
if (ip->ip_p == IPPROTO_TCP) {
- type = vj_compress_tcp(mp, ip, &sc->sc_comp,
+ type = vj_compress_tcp(mp, ip, sc->sc_comp,
!(sc->sc_flags & SC_NO_TCP_CCID));
switch (type) {
case TYPE_UNCOMPRESSED_TCP:
@@ -904,13 +968,18 @@ ppp_outpkt(sc)
for (mp = m; mp != NULL; mp = mp->m_next)
slen += mp->m_len;
clen = (*sc->sc_xcomp->compress)
- (sc->sc_xc_state, &mcomp, m, slen,
- (sc->sc_flags & SC_CCP_UP? sc->sc_if.if_mtu: 0));
+ (sc->sc_xc_state, &mcomp, m, slen, sc->sc_if.if_mtu + PPP_HDRLEN);
if (mcomp != NULL) {
- m_freem(m);
- m = mcomp;
- cp = mtod(m, u_char *);
- protocol = cp[3];
+ if (sc->sc_flags & SC_CCP_UP) {
+ /* Send the compressed packet instead of the original. */
+ m_freem(m);
+ m = mcomp;
+ cp = mtod(m, u_char *);
+ protocol = cp[3];
+ } else {
+ /* Can't transmit compressed packets until CCP is up. */
+ m_freem(mcomp);
+ }
}
}
#endif /* PPP_COMPRESS */
@@ -935,9 +1004,38 @@ ppp_outpkt(sc)
--m->m_len;
}
- s = splimp();
- 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);
}
@@ -946,7 +1044,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;
@@ -975,7 +1073,7 @@ ppp_ccp(sc, m, rcvd)
slen = CCP_LENGTH(dp);
if (dp + slen > ep) {
if (sc->sc_flags & SC_DEBUG)
- printf("if_ppp/ccp: not enough data in mbuf (%x+%x > %x+%x)\n",
+ printf("if_ppp/ccp: not enough data in mbuf (%p+%x > %p+%x)\n",
dp, slen, mtod(mp, u_char *), mp->m_len);
return;
}
@@ -1081,6 +1179,7 @@ ppppktin(sc, m, lost)
/*
* Process a received PPP packet, doing decompression as necessary.
+ * Should be called at splsoftnet.
*/
#define COMPTYPE(proto) ((proto) == PPP_VJC_COMP? TYPE_COMPRESSED_TCP: \
TYPE_UNCOMPRESSED_TCP)
@@ -1090,6 +1189,7 @@ ppp_inproc(sc, m)
struct ppp_softc *sc;
struct mbuf *m;
{
+ struct ifnet *ifp = &sc->sc_if;
struct ifqueue *inq;
int s, ilen, xlen, proto, rv;
u_char *cp, adrs, ctrl;
@@ -1097,10 +1197,13 @@ ppp_inproc(sc, m)
u_char *iphdr;
u_int hlen;
- sc->sc_if.if_ipackets++;
+ sc->sc_stats.ppp_ipackets++;
if (sc->sc_flags & SC_LOG_INPKT) {
- printf("ppp%d: got %d bytes\n", sc->sc_if.if_unit, ilen);
+ ilen = 0;
+ for (mp = m; mp != NULL; mp = mp->m_next)
+ ilen += mp->m_len;
+ printf("ppp%d: got %d bytes\n", ifp->if_unit, ilen);
pppdumpm(m);
}
@@ -1142,7 +1245,7 @@ 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);
+ printf("ppp%d: decompress failed %d\n", ifp->if_unit, rv);
s = splimp();
sc->sc_flags |= SC_VJ_RESET;
if (rv == DECOMP_ERROR)
@@ -1172,7 +1275,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.
*/
- vj_uncompress_tcp(NULL, 0, TYPE_ERROR, &sc->sc_comp);
+ if (sc->sc_comp)
+ vj_uncompress_tcp(NULL, 0, TYPE_ERROR, sc->sc_comp);
s = splimp();
sc->sc_flags &= ~SC_VJ_RESET;
splx(s);
@@ -1182,17 +1286,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 = vj_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;
}
@@ -1234,17 +1338,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 = vj_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;
}
@@ -1267,7 +1371,35 @@ ppp_inproc(sc, m)
}
}
m->m_pkthdr.len = ilen;
- m->m_pkthdr.rcvif = &sc->sc_if;
+ m->m_pkthdr.rcvif = ifp;
+
+ if ((proto & 0x8000) == 0) {
+#ifdef PPP_FILTER
+ /*
+ * See whether we want to pass this packet, and
+ * if it counts as link activity.
+ */
+ adrs = *mtod(m, u_char *); /* save address field */
+ *mtod(m, u_char *) = 0; /* indicate inbound */
+ if (sc->sc_pass_filt.bf_insns != 0
+ && bpf_filter(sc->sc_pass_filt.bf_insns, (u_char *) m,
+ ilen, 0) == 0) {
+ /* drop this packet */
+ m_freem(m);
+ return;
+ }
+ if (sc->sc_active_filt.bf_insns == 0
+ || bpf_filter(sc->sc_active_filt.bf_insns, (u_char *) m, ilen, 0))
+ sc->sc_last_recv = time.tv_sec;
+
+ *mtod(m, u_char *) = adrs;
+#else
+ /*
+ * Record the time that we received this packet.
+ */
+ sc->sc_last_recv = time.tv_sec;
+#endif /* PPP_FILTER */
+ }
#if NBPFILTER > 0
/* See if bpf wants to look at the packet. */
@@ -1282,7 +1414,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);
@@ -1293,7 +1425,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
@@ -1314,12 +1445,15 @@ ppp_inproc(sc, m)
IF_DROP(inq);
splx(s);
if (sc->sc_flags & SC_DEBUG)
- printf("ppp%d: input queue full\n", sc->sc_if.if_unit);
- sc->sc_if.if_iqdrops++;
+ printf("ppp%d: input queue full\n", ifp->if_unit);
+ ifp->if_iqdrops++;
goto bad;
}
IF_ENQUEUE(inq, m);
splx(s);
+ ifp->if_ipackets++;
+ ifp->if_ibytes += ilen;
+ ifp->if_lastchange = time;
if (rv)
(*sc->sc_ctlp)(sc);
@@ -1329,6 +1463,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/sys/net/if_ppp.h b/sys/net/if_ppp.h
index 5433cfbda3c7..17060c74d2f7 100644
--- a/sys/net/if_ppp.h
+++ b/sys/net/if_ppp.h
@@ -1,4 +1,4 @@
-/* $Id: if_ppp.h,v 1.12 1995/04/24 02:40:23 paulus Exp $ */
+/* $Id: if_ppp.h,v 1.16 1997/04/30 05:46:04 paulus Exp $ */
/*
* if_ppp.h - Point-to-Point Protocol definitions.
@@ -23,12 +23,6 @@
#define _IF_PPP_H_
/*
- * Packet sizes
- */
-#define PPP_MTU 1500 /* Default MTU (size of Info field) */
-#define PPP_MAXMRU 65000 /* Largest MRU we allow */
-
-/*
* Bit definitions for flags.
*/
#define SC_COMP_PROT 0x00000001 /* protocol compression (output) */
@@ -111,6 +105,10 @@ struct ifpppcstatsreq {
#define PPPIOCGNPMODE _IOWR('t', 76, struct npioctl) /* get NP mode */
#define PPPIOCSNPMODE _IOW('t', 75, struct npioctl) /* set NP mode */
#define PPPIOCGIDLE _IOR('t', 74, struct ppp_idle) /* get idle time */
+#ifdef PPP_FILTER
+#define PPPIOCSPASS _IOW('t', 71, struct bpf_program) /* set pass filter */
+#define PPPIOCSACTIVE _IOW('t', 70, struct bpf_program) /* set active filt */
+#endif /* PPP_FILTER */
/* PPPIOC[GS]MTU are alternatives to SIOC[GS]IFMTU, used under Ultrix */
#define PPPIOCGMTU _IOR('t', 73, int) /* get interface MTU */
@@ -127,4 +125,8 @@ struct ifpppcstatsreq {
#define ifr_mtu ifr_ifru.ifru_metric
#endif
+#if defined(_KERNEL) || defined(KERNEL)
+void pppattach __P((void));
+void pppintr __P((void));
+#endif
#endif /* _IF_PPP_H_ */
diff --git a/sys/net/if_pppvar.h b/sys/net/if_pppvar.h
index 196e54bb7462..91e8e4e75863 100644
--- a/sys/net/if_pppvar.h
+++ b/sys/net/if_pppvar.h
@@ -1,4 +1,4 @@
-/* $Id: if_pppvar.h,v 1.1 1994/12/15 22:28:09 paulus Exp $ */
+/* $Id: if_pppvar.h,v 1.5 1997/04/30 05:42:08 paulus Exp $ */
/*
* if_pppvar.h - private structures and declarations for PPP.
*
@@ -66,11 +66,7 @@ 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 vjcompress 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 */
@@ -79,7 +75,14 @@ struct ppp_softc {
void *sc_rc_state; /* receive decompressor state */
time_t sc_last_sent; /* time (secs) last NP pkt sent */
time_t sc_last_recv; /* time (secs) last NP pkt rcvd */
-
+#ifdef PPP_FILTER
+ struct bpf_program sc_pass_filt; /* filter for packets to pass */
+ struct bpf_program sc_active_filt; /* filter for "non-idle" packets */
+#endif /* PPP_FILTER */
+#ifdef VJC
+ struct vjcompress *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 +103,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/sys/net/ppp_comp.h b/sys/net/ppp_comp.h
index e2579f85702a..adab65cd3e02 100644
--- a/sys/net/ppp_comp.h
+++ b/sys/net/ppp_comp.h
@@ -24,7 +24,7 @@
* OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
* OR MODIFICATIONS.
*
- * $Id: ppp-comp.h,v 1.7 1995/05/01 01:43:37 paulus Exp $
+ * $Id: ppp-comp.h,v 1.10 1996/09/26 06:30:11 paulus Exp $
*/
#ifndef _NET_PPP_COMP_H
@@ -37,6 +37,11 @@
#ifndef DO_BSD_COMPRESS
#define DO_BSD_COMPRESS 1 /* by default, include BSD-Compress */
#endif
+#ifndef DO_DEFLATE
+#define DO_DEFLATE 1 /* by default, include Deflate */
+#endif
+#define DO_PREDICTOR_1 0
+#define DO_PREDICTOR_2 0
/*
* Structure giving methods for compression/decompression.
@@ -133,4 +138,27 @@ struct compressor {
#define BSD_MIN_BITS 9 /* smallest code size supported */
#define BSD_MAX_BITS 15 /* largest code size supported */
+/*
+ * Definitions for Deflate.
+ */
+#define CI_DEFLATE 24 /* config option for Deflate */
+#define CILEN_DEFLATE 4 /* length of its config option */
+
+#define DEFLATE_MIN_SIZE 8
+#define DEFLATE_MAX_SIZE 15
+#define DEFLATE_METHOD_VAL 8
+#define DEFLATE_SIZE(x) (((x) >> 4) + DEFLATE_MIN_SIZE)
+#define DEFLATE_METHOD(x) ((x) & 0x0F)
+#define DEFLATE_MAKE_OPT(w) ((((w) - DEFLATE_MIN_SIZE) << 4) \
+ + DEFLATE_METHOD_VAL)
+#define DEFLATE_CHK_SEQUENCE 0
+
+/*
+ * Definitions for other, as yet unsupported, compression methods.
+ */
+#define CI_PREDICTOR_1 1 /* config option for Predictor-1 */
+#define CILEN_PREDICTOR_1 2 /* length of its config option */
+#define CI_PREDICTOR_2 2 /* config option for Predictor-2 */
+#define CILEN_PREDICTOR_2 2 /* length of its config option */
+
#endif /* _NET_PPP_COMP_H */
diff --git a/sys/net/ppp_defs.h b/sys/net/ppp_defs.h
index 77f01bb1b1ba..49a6e53b636e 100644
--- a/sys/net/ppp_defs.h
+++ b/sys/net/ppp_defs.h
@@ -1,4 +1,4 @@
-/* $Id: ppp_defs.h,v 1.7 1995/08/10 06:49:35 paulus Exp $ */
+/* $Id: ppp_defs.h,v 1.2 1997/04/30 05:42:20 paulus Exp $ */
/*
* ppp_defs.h - PPP definitions.
@@ -54,15 +54,18 @@
* Protocol field values.
*/
#define PPP_IP 0x21 /* Internet Protocol */
+#define PPP_AT 0x29 /* AppleTalk Protocol */
#define PPP_VJC_COMP 0x2d /* VJ compressed TCP */
#define PPP_VJC_UNCOMP 0x2f /* VJ uncompressed TCP */
#define PPP_COMP 0xfd /* compressed packet */
#define PPP_IPCP 0x8021 /* IP Control Protocol */
+#define PPP_ATCP 0x8029 /* AppleTalk Control Protocol */
#define PPP_CCP 0x80fd /* Compression Control Protocol */
#define PPP_LCP 0xc021 /* Link Control Protocol */
#define PPP_PAP 0xc023 /* Password Authentication Protocol */
#define PPP_LQR 0xc025 /* Link Quality Report protocol */
#define PPP_CHAP 0xc223 /* Cryptographic Handshake Auth. Protocol */
+#define PPP_CBCP 0xc029 /* Callback Control Protocol */
/*
* Values for FCS calculations.
@@ -72,17 +75,6 @@
#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
/*
- * A 32-bit unsigned integral type.
- */
-#if !defined(__BIT_TYPES_DEFINED__) && !defined(_BITYPES)
-#ifdef UINT32_T
-typedef UINT32_T u_int32_t;
-#else
-typedef unsigned int u_int32_t;
-#endif
-#endif
-
-/*
* Extended asyncmap - allows any character to be escaped.
*/
typedef u_int32_t ext_accm[8];
@@ -101,43 +93,43 @@ enum NPmode {
* Statistics.
*/
struct pppstat {
- u_int ppp_ibytes; /* bytes received */
- u_int ppp_ipackets; /* packets received */
- u_int ppp_ierrors; /* receive errors */
- u_int ppp_obytes; /* bytes sent */
- u_int ppp_opackets; /* packets sent */
- u_int ppp_oerrors; /* transmit errors */
+ unsigned int ppp_ibytes; /* bytes received */
+ unsigned int ppp_ipackets; /* packets received */
+ unsigned int ppp_ierrors; /* receive errors */
+ unsigned int ppp_obytes; /* bytes sent */
+ unsigned int ppp_opackets; /* packets sent */
+ unsigned int ppp_oerrors; /* transmit errors */
};
struct vjstat {
- u_int vjs_packets; /* outbound packets */
- u_int vjs_compressed; /* outbound compressed packets */
- u_int vjs_searches; /* searches for connection state */
- u_int vjs_misses; /* times couldn't find conn. state */
- u_int vjs_uncompressedin; /* inbound uncompressed packets */
- u_int vjs_compressedin; /* inbound compressed packets */
- u_int vjs_errorin; /* inbound unknown type packets */
- u_int vjs_tossed; /* inbound packets tossed because of error */
+ unsigned int vjs_packets; /* outbound packets */
+ unsigned int vjs_compressed; /* outbound compressed packets */
+ unsigned int vjs_searches; /* searches for connection state */
+ unsigned int vjs_misses; /* times couldn't find conn. state */
+ unsigned int vjs_uncompressedin; /* inbound uncompressed packets */
+ unsigned int vjs_compressedin; /* inbound compressed packets */
+ unsigned int vjs_errorin; /* inbound unknown type packets */
+ unsigned int vjs_tossed; /* inbound packets tossed because of error */
};
struct ppp_stats {
- struct pppstat p; /* basic PPP statistics */
- struct vjstat vj; /* VJ header compression statistics */
+ struct pppstat p; /* basic PPP statistics */
+ struct vjstat vj; /* VJ header compression statistics */
};
struct compstat {
- u_int unc_bytes; /* total uncompressed bytes */
- u_int unc_packets; /* total uncompressed packets */
- u_int comp_bytes; /* compressed bytes */
- u_int comp_packets; /* compressed packets */
- u_int inc_bytes; /* incompressible bytes */
- u_int inc_packets; /* incompressible packets */
- u_int ratio; /* recent compression ratio << 8 */
+ unsigned int unc_bytes; /* total uncompressed bytes */
+ unsigned int unc_packets; /* total uncompressed packets */
+ unsigned int comp_bytes; /* compressed bytes */
+ unsigned int comp_packets; /* compressed packets */
+ unsigned int inc_bytes; /* incompressible bytes */
+ unsigned int inc_packets; /* incompressible packets */
+ unsigned int ratio; /* recent compression ratio << 8 */
};
struct ppp_comp_stats {
- struct compstat c; /* packet compression statistics */
- struct compstat d; /* packet decompression statistics */
+ struct compstat c; /* packet compression statistics */
+ struct compstat d; /* packet decompression statistics */
};
/*
diff --git a/sys/net/ppp_tty.c b/sys/net/ppp_tty.c
index 5ad17d22572a..912f0831a27c 100644
--- a/sys/net/ppp_tty.c
+++ b/sys/net/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
@@ -70,8 +70,9 @@
* Paul Mackerras (paulus@cs.anu.edu.au).
*/
-/* $Id: ppp_tty.c,v 1.3 1995/08/16 01:36:40 paulus Exp $ */
+/* $Id: ppp_tty.c,v 1.8 1997/04/30 05:42:08 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
@@ -102,6 +103,9 @@
#include <net/pppcompress.h>
#endif
+#ifdef PPP_FILTER
+#include <net/bpf.h>
+#endif
#include <net/ppp_defs.h>
#include <net/if_ppp.h>
#include <net/if_pppvar.h>
@@ -149,6 +153,7 @@ static void ppplogchar __P((struct ppp_softc *, int));
/* This is a FreeBSD-2.0 kernel. */
#define CCOUNT(q) ((q)->c_cc)
+#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 */
/*
@@ -171,6 +176,7 @@ TEXT_SET(pseudo_set, pppasyncattach);
/*
* Line specific open routine for async tty devices.
* Attach the given tty to the first available ppp unit.
+ * Called from device open routine or ttioctl.
*/
/* ARGSUSED */
int
@@ -180,24 +186,29 @@ pppopen(dev, tp)
{
struct proc *p = curproc; /* XXX */
register struct ppp_softc *sc;
- int error, s, i;
+ int error, s;
- if (error = suser(p->p_ucred, &p->p_acflag))
+ if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
return (error);
+ s = spltty();
+
if (tp->t_line == PPPDISC) {
sc = (struct ppp_softc *) tp->t_sc;
- if (sc != NULL && sc->sc_devp == (void *) tp)
+ if (sc != NULL && sc->sc_devp == (void *) tp) {
+ splx(s);
return (0);
+ }
}
- if ((sc = pppalloc(p->p_pid)) == NULL)
+ if ((sc = pppalloc(p->p_pid)) == NULL) {
+ splx(s);
return ENXIO;
+ }
if (sc->sc_relinq)
(*sc->sc_relinq)(sc); /* get previous owner to relinquish the unit */
- s = splimp();
sc->sc_ilen = 0;
sc->sc_m = NULL;
bzero(sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
@@ -211,16 +222,18 @@ pppopen(dev, tp)
sc->sc_outm = NULL;
pppgetm(sc);
sc->sc_if.if_flags |= IFF_RUNNING;
+ sc->sc_if.if_baudrate = tp->t_ospeed;
tp->t_sc = (caddr_t) sc;
ttyflush(tp, FREAD | FWRITE);
- splx(s);
+ splx(s);
return (0);
}
/*
- * Line specific close routine.
+ * Line specific close routine, called from device close routine
+ * and from ttioctl.
* Detach the tty from the ppp unit.
* Mimics part of ttyclose().
*/
@@ -230,11 +243,10 @@ pppclose(tp, flag)
int flag;
{
register struct ppp_softc *sc;
- struct mbuf *m;
int s;
- ttywflush(tp);
- s = splimp(); /* paranoid; splnet probably ok */
+ s = spltty();
+ ttyflush(tp, FREAD|FWRITE);
tp->t_line = 0;
sc = (struct ppp_softc *) tp->t_sc;
if (sc != NULL) {
@@ -257,7 +269,7 @@ pppasyncrelinq(sc)
{
int s;
- s = splimp();
+ s = spltty();
if (sc->sc_outm) {
m_freem(sc->sc_outm);
sc->sc_outm = NULL;
@@ -293,7 +305,7 @@ pppread(tp, uio, flag)
* Loop waiting for input, checking that nothing disasterous
* happens in the meantime.
*/
- s = splimp();
+ s = spltty();
for (;;) {
if (tp != (struct tty *) sc->sc_devp || tp->t_line != PPPDISC) {
splx(s);
@@ -301,7 +313,8 @@ pppread(tp, uio, flag)
}
if (sc->sc_inq.ifq_head != NULL)
break;
- if ((tp->t_state & TS_CONNECTED) == 0 && (tp->t_state & TS_ISOPEN)) {
+ if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0
+ && (tp->t_state & TS_ISOPEN)) {
splx(s);
return 0; /* end of file */
}
@@ -309,7 +322,7 @@ pppread(tp, uio, flag)
splx(s);
return (EWOULDBLOCK);
}
- error = ttysleep(tp, TSA_HUP_OR_INPUT(tp), TTIPRI | PCATCH, "pppin", 0);
+ error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH, "ttyin", 0);
if (error) {
splx(s);
return error;
@@ -324,7 +337,7 @@ pppread(tp, uio, flag)
splx(s);
for (m = m0; m && uio->uio_resid; m = m->m_next)
- if (error = uiomove(mtod(m, u_char *), m->m_len, uio))
+ if ((error = uiomove(mtod(m, u_char *), m->m_len, uio)) != 0)
break;
m_freem(m0);
return (error);
@@ -344,7 +357,7 @@ pppwrite(tp, uio, flag)
struct sockaddr dst;
int len, error;
- if ((tp->t_state & TS_CONNECTED) == 0)
+ if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0)
return 0; /* wrote 0 bytes */
if (tp->t_line != PPPDISC)
return (EINVAL);
@@ -365,7 +378,7 @@ pppwrite(tp, uio, flag)
len = M_TRAILINGSPACE(m);
if (len > uio->uio_resid)
len = uio->uio_resid;
- if (error = uiomove(mtod(m, u_char *), len, uio)) {
+ if ((error = uiomove(mtod(m, u_char *), len, uio)) != 0) {
m_freem(m0);
return (error);
}
@@ -387,8 +400,9 @@ pppwrite(tp, uio, flag)
int
ppptioctl(tp, cmd, data, flag, p)
struct tty *tp;
+ int cmd;
caddr_t data;
- int cmd, flag;
+ int flag;
struct proc *p;
{
struct ppp_softc *sc = (struct ppp_softc *) tp->t_sc;
@@ -400,7 +414,7 @@ ppptioctl(tp, cmd, data, flag, p)
error = 0;
switch (cmd) {
case PPPIOCSASYNCMAP:
- if (error = suser(p->p_ucred, &p->p_acflag))
+ if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
break;
sc->sc_asyncmap[0] = *(u_int *)data;
break;
@@ -410,7 +424,7 @@ ppptioctl(tp, cmd, data, flag, p)
break;
case PPPIOCSRASYNCMAP:
- if (error = suser(p->p_ucred, &p->p_acflag))
+ if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
break;
sc->sc_rasyncmap = *(u_int *)data;
break;
@@ -420,7 +434,7 @@ ppptioctl(tp, cmd, data, flag, p)
break;
case PPPIOCSXASYNCMAP:
- if (error = suser(p->p_ucred, &p->p_acflag))
+ if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
break;
s = spltty();
bcopy(data, sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
@@ -496,58 +510,20 @@ pppfcs(fcs, cp, len)
}
/*
- * This gets called from pppoutput when a new packet is
- * put on a queue.
+ * This gets called at splsoftnet 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 = splimp();
- pppstart(tp);
- splx(s);
-}
-
-/*
- * This gets called when a received packet is placed on
- * the inq.
- */
-static void
-pppasyncctlp(sc)
- struct ppp_softc *sc;
-{
- struct tty *tp;
-
- /* Put a placeholder byte in canq for ttselect()/ttnread(). */
- tp = (struct tty *) sc->sc_devp;
- putc(0, &tp->t_canq);
- ttwakeup(tp);
-}
-
-/*
- * Start output on async tty interface. Get another datagram
- * to send from the interface queue and start sending it.
- */
-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_CONNECTED) == 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) {
@@ -572,12 +548,13 @@ 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);
}
/* Calculate the FCS for the first mbuf's worth. */
sc->sc_outfcs = pppfcs(PPP_INITFCS, mtod(m, u_char *), m->m_len);
+ sc->sc_if.if_lastchange = time;
}
for (;;) {
@@ -598,24 +575,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--;
}
@@ -655,6 +635,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;
@@ -662,7 +643,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) {
@@ -677,28 +660,24 @@ pppstart(tp)
m = m2;
if (m == NULL) {
/* Finished a packet */
- sc->sc_if.if_opackets++;
- sc->sc_if.if_obytes = sc->sc_bytessent;
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;
}
- /*
- * Send anything that may be in the output queue.
- * 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,
@@ -710,6 +689,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;
}
@@ -724,7 +755,7 @@ ppp_timeout(x)
struct tty *tp = (struct tty *) sc->sc_devp;
int s;
- s = splimp();
+ s = spltty();
sc->sc_flags &= ~SC_TIMEOUT;
pppstart(tp);
splx(s);
@@ -739,9 +770,7 @@ pppgetm(sc)
{
struct mbuf *m, **mp;
int len;
- int s;
- s = splimp();
mp = &sc->sc_m;
for (len = sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN; len > 0; ){
if ((m = *mp) == NULL) {
@@ -754,7 +783,6 @@ pppgetm(sc)
len -= M_DATASIZE(m);
mp = &m->m_next;
}
- splx(s);
}
/*
@@ -778,9 +806,8 @@ pppinput(c, tp)
if (sc == NULL || tp != (struct tty *) sc->sc_devp)
return 0;
- s = spltty();
++tk_nin;
- ++sc->sc_bytesrcvd;
+ ++sc->sc_stats.ppp_ibytes;
if (c & TTY_FE) {
/* framing error or overrun on this char - abort packet */
@@ -791,6 +818,26 @@ pppinput(c, tp)
c &= 0xff;
+ /*
+ * 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 == tp->t_cc[VSTART] && tp->t_cc[VSTART] != _POSIX_VDISABLE) {
+ tp->t_state &= ~TS_TTSTOP;
+ if (tp->t_oproc != NULL)
+ (*tp->t_oproc)(tp);
+ return 0;
+ }
+ }
+
+ s = spltty();
if (c & 0x80)
sc->sc_flags |= SC_RCV_B7_1;
else
@@ -799,6 +846,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);
@@ -806,7 +854,6 @@ pppinput(c, tp)
if (c == PPP_FLAG) {
ilen = sc->sc_ilen;
sc->sc_ilen = 0;
- sc->sc_if.if_ibytes = sc->sc_bytesrcvd;
if (sc->sc_rawin_count > 0)
ppplogchar(sc, -1);
@@ -816,13 +863,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);
@@ -833,10 +882,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;
}
@@ -857,25 +908,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;
@@ -884,6 +936,7 @@ pppinput(c, tp)
splx(s);
return 0;
}
+ splx(s);
/*
* Initialize buffer on first octet received.
@@ -969,17 +1022,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;
}
@@ -993,7 +1047,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/sys/net/slcompress.c b/sys/net/slcompress.c
index 70af9358e37b..9e6346c75fe6 100644
--- a/sys/net/slcompress.c
+++ b/sys/net/slcompress.c
@@ -1,4 +1,7 @@
-/*-
+/* $NetBSD: slcompress.c,v 1.15 1996/03/15 02:28:12 paulus Exp $ */
+/* Id: slcompress.c,v 1.3 1996/05/24 07:04:47 paulus Exp */
+
+/*
* Copyright (c) 1989, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
@@ -39,13 +42,11 @@
*
* Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
* - Initial distribution.
- *
- * static char rcsid[] =
- * "$Header: slcompress.c,v 1.19 89/12/31 08:52:59 van Exp $";
*/
#include <sys/param.h>
#include <sys/mbuf.h>
+#include <sys/systm.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
@@ -62,23 +63,31 @@
#define BCMP(p1, p2, n) bcmp((char *)(p1), (char *)(p2), (int)(n))
#define BCOPY(p1, p2, n) bcopy((char *)(p1), (char *)(p2), (int)(n))
-#ifndef KERNEL
+#ifndef _KERNEL
#define ovbcopy bcopy
#endif
void
-sl_compress_init(comp)
+sl_compress_init(comp, max_state)
struct slcompress *comp;
+ int max_state;
{
register u_int i;
register struct cstate *tstate = comp->tstate;
- bzero((char *)comp, sizeof(*comp));
- for (i = MAX_STATES - 1; i > 0; --i) {
+ if (max_state == -1) {
+ max_state = MAX_STATES - 1;
+ bzero((char *)comp, sizeof(*comp));
+ } else {
+ /* Don't reset statistics */
+ bzero((char *)comp->tstate, sizeof(comp->tstate));
+ bzero((char *)comp->rstate, sizeof(comp->rstate));
+ }
+ for (i = max_state; i > 0; --i) {
tstate[i].cs_id = i;
tstate[i].cs_next = &tstate[i - 1];
}
- tstate[0].cs_next = &tstate[MAX_STATES - 1];
+ tstate[0].cs_next = &tstate[max_state];
tstate[0].cs_id = 0;
comp->last_cs = &tstate[0];
comp->last_recv = 255;
@@ -92,7 +101,7 @@ sl_compress_init(comp)
* form).
*/
#define ENCODE(n) { \
- if ((u_short)(n) >= 256) { \
+ if ((u_int16_t)(n) >= 256) { \
*cp++ = 0; \
cp[1] = (n); \
cp[0] = (n) >> 8; \
@@ -102,7 +111,7 @@ sl_compress_init(comp)
} \
}
#define ENCODEZ(n) { \
- if ((u_short)(n) >= 256 || (u_short)(n) == 0) { \
+ if ((u_int16_t)(n) >= 256 || (u_int16_t)(n) == 0) { \
*cp++ = 0; \
cp[1] = (n); \
cp[0] = (n) >> 8; \
@@ -117,7 +126,7 @@ sl_compress_init(comp)
(f) = htonl(ntohl(f) + ((cp[1] << 8) | cp[2])); \
cp += 3; \
} else { \
- (f) = htonl(ntohl(f) + (u_long)*cp++); \
+ (f) = htonl(ntohl(f) + (u_int32_t)*cp++); \
} \
}
@@ -126,7 +135,7 @@ sl_compress_init(comp)
(f) = htons(ntohs(f) + ((cp[1] << 8) | cp[2])); \
cp += 3; \
} else { \
- (f) = htons(ntohs(f) + (u_long)*cp++); \
+ (f) = htons(ntohs(f) + (u_int32_t)*cp++); \
} \
}
@@ -135,7 +144,7 @@ sl_compress_init(comp)
(f) = htons((cp[1] << 8) | cp[2]); \
cp += 3; \
} else { \
- (f) = htons((u_long)*cp++); \
+ (f) = htons((u_int32_t)*cp++); \
} \
}
@@ -164,7 +173,7 @@ sl_compress_tcp(m, ip, comp, compress_cid)
if ((ip->ip_off & htons(0x3fff)) || m->m_len < 40)
return (TYPE_IP);
- th = (struct tcphdr *)&((int *)ip)[hlen];
+ th = (struct tcphdr *)&((int32_t *)ip)[hlen];
if ((th->th_flags & (TH_SYN|TH_FIN|TH_RST|TH_ACK)) != TH_ACK)
return (TYPE_IP);
/*
@@ -177,7 +186,7 @@ sl_compress_tcp(m, ip, comp, compress_cid)
INCR(sls_packets)
if (ip->ip_src.s_addr != cs->cs_ip.ip_src.s_addr ||
ip->ip_dst.s_addr != cs->cs_ip.ip_dst.s_addr ||
- *(int *)th != ((int *)&cs->cs_ip)[cs->cs_ip.ip_hl]) {
+ *(int32_t *)th != ((int32_t *)&cs->cs_ip)[cs->cs_ip.ip_hl]) {
/*
* Wasn't the first -- search for it.
*
@@ -198,7 +207,8 @@ sl_compress_tcp(m, ip, comp, compress_cid)
INCR(sls_searches)
if (ip->ip_src.s_addr == cs->cs_ip.ip_src.s_addr
&& ip->ip_dst.s_addr == cs->cs_ip.ip_dst.s_addr
- && *(int *)th == ((int *)&cs->cs_ip)[cs->cs_ip.ip_hl])
+ && *(int32_t *)th ==
+ ((int32_t *)&cs->cs_ip)[cs->cs_ip.ip_hl])
goto found;
} while (cs != lastcs);
@@ -240,14 +250,14 @@ sl_compress_tcp(m, ip, comp, compress_cid)
* different between the previous & current datagram, we send the
* current datagram `uncompressed'.
*/
- oth = (struct tcphdr *)&((int *)&cs->cs_ip)[hlen];
+ oth = (struct tcphdr *)&((int32_t *)&cs->cs_ip)[hlen];
deltaS = hlen;
hlen += th->th_off;
hlen <<= 2;
- if (((u_short *)ip)[0] != ((u_short *)&cs->cs_ip)[0] ||
- ((u_short *)ip)[3] != ((u_short *)&cs->cs_ip)[3] ||
- ((u_short *)ip)[4] != ((u_short *)&cs->cs_ip)[4] ||
+ if (((u_int16_t *)ip)[0] != ((u_int16_t *)&cs->cs_ip)[0] ||
+ ((u_int16_t *)ip)[3] != ((u_int16_t *)&cs->cs_ip)[3] ||
+ ((u_int16_t *)ip)[4] != ((u_int16_t *)&cs->cs_ip)[4] ||
th->th_off != oth->th_off ||
(deltaS > 5 &&
BCMP(ip + 1, &cs->cs_ip + 1, (deltaS - 5) << 2)) ||
@@ -272,19 +282,22 @@ sl_compress_tcp(m, ip, comp, compress_cid)
* with it. */
goto uncompressed;
- if (deltaS = (u_short)(ntohs(th->th_win) - ntohs(oth->th_win))) {
+ deltaS = (u_int16_t)(ntohs(th->th_win) - ntohs(oth->th_win));
+ if (deltaS) {
ENCODE(deltaS);
changes |= NEW_W;
}
- if (deltaA = ntohl(th->th_ack) - ntohl(oth->th_ack)) {
+ deltaA = ntohl(th->th_ack) - ntohl(oth->th_ack);
+ if (deltaA) {
if (deltaA > 0xffff)
goto uncompressed;
ENCODE(deltaA);
changes |= NEW_A;
}
- if (deltaS = ntohl(th->th_seq) - ntohl(oth->th_seq)) {
+ deltaS = ntohl(th->th_seq) - ntohl(oth->th_seq);
+ if (deltaS) {
if (deltaS > 0xffff)
goto uncompressed;
ENCODE(deltaS);
@@ -398,29 +411,89 @@ sl_uncompress_tcp(bufp, len, type, comp)
u_int type;
struct slcompress *comp;
{
+ u_char *hdr, *cp;
+ int hlen, vjlen;
+
+ cp = bufp? *bufp: NULL;
+ vjlen = sl_uncompress_tcp_core(cp, len, len, type, comp, &hdr, &hlen);
+ if (vjlen < 0)
+ return (0); /* error */
+ if (vjlen == 0)
+ return (len); /* was uncompressed already */
+
+ cp += vjlen;
+ len -= vjlen;
+
+ /*
+ * At this point, cp points to the first byte of data in the
+ * packet. If we're not aligned on a 4-byte boundary, copy the
+ * data down so the ip & tcp headers will be aligned. Then back up
+ * cp by the tcp/ip header length to make room for the reconstructed
+ * header (we assume the packet we were handed has enough space to
+ * prepend 128 bytes of header).
+ */
+ if ((long)cp & 3) {
+ if (len > 0)
+ (void) ovbcopy(cp, (caddr_t)((long)cp &~ 3), len);
+ cp = (u_char *)((long)cp &~ 3);
+ }
+ cp -= hlen;
+ len += hlen;
+ BCOPY(hdr, cp, hlen);
+
+ *bufp = cp;
+ return (len);
+}
+
+/*
+ * Uncompress a packet of total length total_len. The first buflen
+ * bytes are at buf; this must include the entire (compressed or
+ * uncompressed) TCP/IP header. This procedure returns the length
+ * of the VJ header, with a pointer to the uncompressed IP header
+ * in *hdrp and its length in *hlenp.
+ */
+int
+sl_uncompress_tcp_core(buf, buflen, total_len, type, comp, hdrp, hlenp)
+ u_char *buf;
+ int buflen, total_len;
+ u_int type;
+ struct slcompress *comp;
+ u_char **hdrp;
+ u_int *hlenp;
+{
register u_char *cp;
register u_int hlen, changes;
register struct tcphdr *th;
register struct cstate *cs;
register struct ip *ip;
+ register u_int16_t *bp;
+ register u_int vjlen;
switch (type) {
case TYPE_UNCOMPRESSED_TCP:
- ip = (struct ip *) *bufp;
+ ip = (struct ip *) buf;
if (ip->ip_p >= MAX_STATES)
goto bad;
cs = &comp->rstate[comp->last_recv = ip->ip_p];
comp->flags &=~ SLF_TOSS;
ip->ip_p = IPPROTO_TCP;
- hlen = ip->ip_hl;
- hlen += ((struct tcphdr *)&((int *)ip)[hlen])->th_off;
- hlen <<= 2;
+ /*
+ * Calculate the size of the TCP/IP header and make sure that
+ * we don't overflow the space we have available for it.
+ */
+ hlen = ip->ip_hl << 2;
+ if (hlen + sizeof(struct tcphdr) > buflen)
+ goto bad;
+ hlen += ((struct tcphdr *)&((char *)ip)[hlen])->th_off << 2;
+ if (hlen > MAX_HDR || hlen > buflen)
+ goto bad;
BCOPY(ip, &cs->cs_ip, hlen);
- cs->cs_ip.ip_sum = 0;
cs->cs_hlen = hlen;
INCR(sls_uncompressedin)
- return (len);
+ *hdrp = (u_char *) &cs->cs_ip;
+ *hlenp = hlen;
+ return (0);
default:
goto bad;
@@ -430,7 +503,7 @@ sl_uncompress_tcp(bufp, len, type, comp)
}
/* We've got a compressed packet. */
INCR(sls_compressedin)
- cp = *bufp;
+ cp = buf;
changes = *cp++;
if (changes & NEW_C) {
/* Make sure the state index is in range, then grab the state.
@@ -446,7 +519,7 @@ sl_uncompress_tcp(bufp, len, type, comp)
* explicit state index, we have to toss the packet. */
if (comp->flags & SLF_TOSS) {
INCR(sls_tossed)
- return (0);
+ return (-1);
}
}
cs = &comp->rstate[comp->last_recv];
@@ -494,42 +567,34 @@ sl_uncompress_tcp(bufp, len, type, comp)
/*
* At this point, cp points to the first byte of data in the
- * packet. If we're not aligned on a 4-byte boundary, copy the
- * data down so the ip & tcp headers will be aligned. Then back up
- * cp by the tcp/ip header length to make room for the reconstructed
- * header (we assume the packet we were handed has enough space to
- * prepend 128 bytes of header). Adjust the length to account for
- * the new header & fill in the IP total length.
+ * packet. Fill in the IP total length and update the IP
+ * header checksum.
*/
- len -= (cp - *bufp);
- if (len < 0)
+ vjlen = cp - buf;
+ buflen -= vjlen;
+ if (buflen < 0)
/* we must have dropped some characters (crc should detect
* this but the old slip framing won't) */
goto bad;
- if ((int)cp & 3) {
- if (len > 0)
- (void) ovbcopy(cp, (caddr_t)((int)cp &~ 3), len);
- cp = (u_char *)((int)cp &~ 3);
- }
- cp -= cs->cs_hlen;
- len += cs->cs_hlen;
- cs->cs_ip.ip_len = htons(len);
- BCOPY(&cs->cs_ip, cp, cs->cs_hlen);
- *bufp = cp;
+ total_len += cs->cs_hlen - vjlen;
+ cs->cs_ip.ip_len = htons(total_len);
/* recompute the ip header checksum */
- {
- register u_short *bp = (u_short *)cp;
- for (changes = 0; hlen > 0; hlen -= 2)
- changes += *bp++;
- changes = (changes & 0xffff) + (changes >> 16);
- changes = (changes & 0xffff) + (changes >> 16);
- ((struct ip *)cp)->ip_sum = ~ changes;
- }
- return (len);
+ bp = (u_int16_t *) &cs->cs_ip;
+ cs->cs_ip.ip_sum = 0;
+ for (changes = 0; hlen > 0; hlen -= 2)
+ changes += *bp++;
+ changes = (changes & 0xffff) + (changes >> 16);
+ changes = (changes & 0xffff) + (changes >> 16);
+ cs->cs_ip.ip_sum = ~ changes;
+
+ *hdrp = (u_char *) &cs->cs_ip;
+ *hlenp = cs->cs_hlen;
+ return vjlen;
+
bad:
comp->flags |= SLF_TOSS;
INCR(sls_errorin)
- return (0);
+ return (-1);
}
diff --git a/sys/net/slcompress.h b/sys/net/slcompress.h
index cefe940f1981..f5e0cf7b610b 100644
--- a/sys/net/slcompress.h
+++ b/sys/net/slcompress.h
@@ -1,9 +1,7 @@
-/* slcompress.h 8.1 93/06/10 */
+/* $NetBSD: slcompress.h,v 1.9 1995/07/04 06:28:29 paulus Exp $ */
+/* Id: slcompress.h,v 1.1 1995/12/11 05:17:12 paulus Exp */
+
/*
- * Definitions for tcp compression routines.
- *
- * $Header: slcompress.h,v 1.10 89/12/31 08:53:02 van Exp $
- *
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -35,7 +33,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
+ * @(#)slcompress.h 8.1 (Berkeley) 6/10/93
+ */
+
+/*
+ * Definitions for tcp compression routines.
+ *
+ * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
* - Initial distribution.
*/
@@ -115,7 +119,7 @@
*/
struct cstate {
struct cstate *cs_next; /* next most recently used cstate (xmit only) */
- u_short cs_hlen; /* size of hdr (receive only) */
+ u_int16_t cs_hlen; /* size of hdr (receive only) */
u_char cs_id; /* connection # associated with this state */
u_char cs_filler;
union {
@@ -134,7 +138,7 @@ struct slcompress {
struct cstate *last_cs; /* most recently used tstate */
u_char last_recv; /* last rcvd conn. id */
u_char last_xmit; /* last sent conn. id */
- u_short flags;
+ u_int16_t flags;
#ifndef SL_NO_STATS
int sls_packets; /* outbound packets */
int sls_compressed; /* outbound compressed packets */
@@ -151,7 +155,9 @@ struct slcompress {
/* flag values */
#define SLF_TOSS 1 /* tossing rcvd frames because of input err */
-void sl_compress_init __P((struct slcompress *));
+void sl_compress_init __P((struct slcompress *, int));
u_int sl_compress_tcp __P((struct mbuf *,
struct ip *, struct slcompress *, int));
int sl_uncompress_tcp __P((u_char **, int, u_int, struct slcompress *));
+int sl_uncompress_tcp_core __P((u_char *, int, int, u_int,
+ struct slcompress *, u_char **, u_int *));