summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorjoshd <joshd@cvs.openbsd.org>1996-07-25 14:20:53 +0000
committerjoshd <joshd@cvs.openbsd.org>1996-07-25 14:20:53 +0000
commitb2c40fc620e5ca3e1005a76f3da5d47647750f29 (patch)
tree705839ba26c08c97e551f4fc41ab91990bbe6873 /sys
parentc721a42504c2fd28c3742587e7331f007634d999 (diff)
Kernel changes for ppp2.3a4.
Diffstat (limited to 'sys')
-rw-r--r--sys/net/if_ppp.c303
-rw-r--r--sys/net/ppp_tty.c373
-rw-r--r--sys/net/slcompress.c16
3 files changed, 370 insertions, 322 deletions
diff --git a/sys/net/if_ppp.c b/sys/net/if_ppp.c
index 4e8dc87d27e..f8997836756 100644
--- a/sys/net/if_ppp.c
+++ b/sys/net/if_ppp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ppp.c,v 1.7 1996/05/10 12:31:10 deraadt Exp $ */
+/* $OpenBSD: if_ppp.c,v 1.8 1996/07/25 14:20:50 joshd Exp $ */
/* $NetBSD: if_ppp.c,v 1.31 1996/05/07 02:40:36 thorpej Exp $ */
/*
@@ -91,6 +91,10 @@
#include <sys/time.h>
#include <sys/malloc.h>
+#if NetBSD1_0 && defined(i386)
+#include <machine/psl.h>
+#endif
+
#include <net/if.h>
#include <net/if_types.h>
#include <net/netisr.h>
@@ -119,13 +123,16 @@
#include <net/if_pppvar.h>
#include <machine/cpu.h>
+#if NetBSD1_0
+#define splsoftnet splnet
+#endif
+
#ifdef PPP_COMPRESS
#define PACKETPTR struct mbuf *
#include <net/ppp-comp.h>
#endif
static void ppp_requeue __P((struct ppp_softc *));
-static void ppp_outpkt __P((struct ppp_softc *));
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 *));
@@ -200,6 +207,19 @@ pppattach()
bpfattach(&sc->sc_bpf, &sc->sc_if, DLT_PPP, PPP_HDRLEN);
#endif
}
+
+#if NetBSD1_0 && defined(i386)
+ /*
+ * XXX kludge to fix the bug in the i386 interrupt handling code,
+ * where software interrupts could be taken while hardware
+ * interrupts were blocked.
+ */
+ if ((imask[IPL_TTY] & (1 << SIR_NET)) == 0) {
+ imask[IPL_TTY] |= (1 << SIR_NET);
+ intr_calculatemasks();
+ }
+#endif
+
}
/*
@@ -839,190 +859,187 @@ 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 = splhigh();
+ 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 splsoftnet.
- */
-void
-pppintr()
-{
- struct ppp_softc *sc;
- int i, s;
- struct mbuf *m;
-
- 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 = splhigh();
- IF_DEQUEUE(&sc->sc_rawq, m);
- splx(s);
- if (m == NULL)
- break;
- ppp_inproc(sc, m);
- }
- }
-}
/*
- * Grab another packet off a queue and apply VJ compression,
- * packet compression, address/control and/or protocol compression
- * if enabled. Should be called at splsoftnet.
+ * 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;
{
struct mbuf *m, *mp;
u_char *cp;
int address, control, protocol;
-
+ int s = splhigh();
+
/*
* Grab a packet to send: first try the fast queue, then the
* normal queue.
*/
IF_DEQUEUE(&sc->sc_fastq, m);
- if (m == NULL)
+ if (m == NULL)
IF_DEQUEUE(&sc->sc_if.if_snd, m);
if (m == NULL)
- return;
-
+ { splx(s);
+ return NULL;
+ }
+
++sc->sc_stats.ppp_opackets;
/*
* Extract the ppp header of the new packet.
- * The ppp header will be in one mbuf.
+ * The ppp header will be in one mbuf.
*/
cp = mtod(m, u_char *);
address = PPP_ADDRESS(cp);
control = PPP_CONTROL(cp);
protocol = PPP_PROTOCOL(cp);
-
+
switch (protocol) {
case PPP_IP:
#ifdef VJC
- /*
- * If the packet is a TCP/IP packet, see if we can compress it.
- */
- if ((sc->sc_flags & SC_COMP_TCP) && sc->sc_comp != NULL) {
- struct ip *ip;
- int type;
-
- mp = m;
- ip = (struct ip *) (cp + PPP_HDRLEN);
- if (mp->m_len <= PPP_HDRLEN) {
- mp = mp->m_next;
- if (mp == NULL)
- break;
- ip = mtod(mp, struct ip *);
- }
- /* 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,
- !(sc->sc_flags & SC_NO_TCP_CCID));
- switch (type) {
- case TYPE_UNCOMPRESSED_TCP:
- protocol = PPP_VJC_UNCOMP;
- break;
- case TYPE_COMPRESSED_TCP:
- protocol = PPP_VJC_COMP;
- cp = mtod(m, u_char *);
- cp[0] = address; /* header has moved */
- cp[1] = control;
- cp[2] = 0;
- break;
- }
- cp[3] = protocol; /* update protocol in PPP header */
- }
- }
-#endif /* VJC */
- break;
-
+ /*
+ * If the packet is a TCP/IP packet, see if we can compress it.
+ */
+ if ((sc->sc_flags & SC_COMP_TCP) && sc->sc_comp != NULL) {
+ struct ip *ip;
+ int type;
+
+ mp = m;
+ ip = (struct ip *) (cp + PPP_HDRLEN);
+ if (mp->m_len <= PPP_HDRLEN) {
+ mp = mp->m_next;
+ if (mp == NULL)
+ break;
+ ip = mtod(mp, struct ip *);
+ }
+ /* 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,
+ !(sc->sc_flags & SC_NO_TCP_CCID));
+ switch (type) {
+ case TYPE_UNCOMPRESSED_TCP:
+ protocol = PPP_VJC_UNCOMP;
+ break;
+ case TYPE_COMPRESSED_TCP:
+ protocol = PPP_VJC_COMP;
+ cp = mtod(m, u_char *);
+ cp[0] = address; /* header has moved */
+ cp[1] = control;
+ cp[2] = 0;
+ break;
+ }
+ cp[3] = protocol; /* update protocol in PPP header */
+ }
+ }
+#endif /* VJC */
+ break;
+
#ifdef PPP_COMPRESS
case PPP_CCP:
- ppp_ccp(sc, m, 0);
- break;
-#endif /* PPP_COMPRESS */
+ ppp_ccp(sc, m, 0);
+ break;
+#endif /* PPP_COMPRESS */
}
-
+
#ifdef PPP_COMPRESS
if (protocol != PPP_LCP && protocol != PPP_CCP
- && sc->sc_xc_state && (sc->sc_flags & SC_COMP_RUN)) {
- struct mbuf *mcomp = NULL;
- int slen, clen;
-
- slen = 0;
- 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));
- if (mcomp != NULL) {
- m_freem(m);
- m = mcomp;
- cp = mtod(m, u_char *);
- protocol = cp[3];
- }
+ && sc->sc_xc_state && (sc->sc_flags & SC_COMP_RUN)) {
+ struct mbuf *mcomp = NULL;
+ int slen, clen;
+
+ slen = 0;
+ 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));
+ if (mcomp != NULL) {
+ m_freem(m);
+ m = mcomp;
+ cp = mtod(m, u_char *);
+ protocol = cp[3];
+ }
}
-#endif /* PPP_COMPRESS */
-
+#endif /* PPP_COMPRESS */
+
/*
* Compress the address/control and protocol, if possible.
*/
if (sc->sc_flags & SC_COMP_AC && address == PPP_ALLSTATIONS &&
- control == PPP_UI && protocol != PPP_ALLSTATIONS &&
- protocol != PPP_LCP) {
- /* can compress address/control */
- m->m_data += 2;
- m->m_len -= 2;
- }
+ control == PPP_UI && protocol != PPP_ALLSTATIONS &&
+ protocol != PPP_LCP) {
+ /* can compress address/control */
+ m->m_data += 2;
+ m->m_len -= 2;
+ }
if (sc->sc_flags & SC_COMP_PROT && protocol < 0xFF) {
- /* can compress protocol */
- if (mtod(m, u_char *) == cp) {
- cp[2] = cp[1]; /* move address/control up */
- cp[1] = cp[0];
- }
- ++m->m_data;
- --m->m_len;
+ /* can compress protocol */
+ if (mtod(m, u_char *) == cp) {
+ cp[2] = cp[1]; /* move address/control up */
+ cp[1] = cp[0];
+ }
+ ++m->m_data;
+ --m->m_len;
}
+ splx(s);
+ return m;
+
+}
- sc->sc_togo = m;
- (*sc->sc_start)(sc);
+/*
+ * 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
/*
* Handle a CCP packet. `rcvd' is 1 if the packet was received,
@@ -1068,7 +1085,7 @@ ppp_ccp(sc, m, rcvd)
case CCP_TERMACK:
/* CCP must be going down - disable compression */
if (sc->sc_flags & SC_CCP_UP) {
- s = splhigh();
+ s = splimp();
sc->sc_flags &= ~(SC_CCP_UP | SC_COMP_RUN | SC_DECOMP_RUN);
splx(s);
}
@@ -1084,7 +1101,7 @@ ppp_ccp(sc, m, rcvd)
&& (*sc->sc_xcomp->comp_init)
(sc->sc_xc_state, dp + CCP_HDRLEN, slen - CCP_HDRLEN,
sc->sc_unit, 0, sc->sc_flags & SC_DEBUG)) {
- s = splhigh();
+ s = splimp();
sc->sc_flags |= SC_COMP_RUN;
splx(s);
}
@@ -1095,7 +1112,7 @@ ppp_ccp(sc, m, rcvd)
(sc->sc_rc_state, dp + CCP_HDRLEN, slen - CCP_HDRLEN,
sc->sc_unit, 0, sc->sc_mru,
sc->sc_flags & SC_DEBUG)) {
- s = splhigh();
+ s = splimp();
sc->sc_flags |= SC_DECOMP_RUN;
sc->sc_flags &= ~(SC_DC_ERROR | SC_DC_FERROR);
splx(s);
@@ -1152,7 +1169,7 @@ ppppktin(sc, m, lost)
struct mbuf *m;
int lost;
{
- int s = splhigh();
+ int s = splimp();
if (lost)
m->m_flags |= M_ERRMARK;
@@ -1198,7 +1215,7 @@ ppp_inproc(sc, m)
if (m->m_flags & M_ERRMARK) {
m->m_flags &= ~M_ERRMARK;
- s = splhigh();
+ s = splimp();
sc->sc_flags |= SC_VJ_RESET;
splx(s);
}
@@ -1230,7 +1247,7 @@ ppp_inproc(sc, m)
*/
if (sc->sc_flags & SC_DEBUG)
printf("%s: decompress failed %d\n", ifp->if_xname, rv);
- s = splhigh();
+ s = splimp();
sc->sc_flags |= SC_VJ_RESET;
if (rv == DECOMP_ERROR)
sc->sc_flags |= SC_DC_ERROR;
@@ -1261,7 +1278,7 @@ ppp_inproc(sc, m)
*/
if (sc->sc_comp)
sl_uncompress_tcp(NULL, 0, TYPE_ERROR, sc->sc_comp);
- s = splhigh();
+ s = splimp();
sc->sc_flags &= ~SC_VJ_RESET;
splx(s);
}
@@ -1417,7 +1434,7 @@ ppp_inproc(sc, m)
/*
* Put the packet on the appropriate input queue.
*/
- s = splhigh();
+ s = splimp();
if (IF_QFULL(inq)) {
IF_DROP(inq);
splx(s);
diff --git a/sys/net/ppp_tty.c b/sys/net/ppp_tty.c
index b46f96d2510..928789966fd 100644
--- a/sys/net/ppp_tty.c
+++ b/sys/net/ppp_tty.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ppp_tty.c,v 1.4 1996/05/10 12:31:13 deraadt Exp $ */
+/* $OpenBSD: ppp_tty.c,v 1.5 1996/07/25 14:20:51 joshd Exp $ */
/* $NetBSD: ppp_tty.c,v 1.6 1996/05/07 02:40:51 thorpej Exp $ */
/*
@@ -153,6 +153,7 @@ static void ppplogchar __P((struct ppp_softc *, int));
/* This is a NetBSD-1.0 or later 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 */
/*
@@ -500,11 +501,179 @@ pppasyncstart(sc)
register struct ppp_softc *sc;
{
register struct tty *tp = (struct tty *) sc->sc_devp;
+ register struct mbuf *m;
+ register int len;
+ register u_char *start, *stop, *cp;
+ int n, ndone, done, idle;
+ struct mbuf *m2;
int s;
-
+
+ idle = 0;
+ while (CCOUNT(&tp->t_outq) < PPP_HIWAT) {
+ /*
+ * See if we have an existing packet partly sent.
+ * If not, get a new packet and start sending it.
+ */
+ m = sc->sc_outm;
+ if (m == NULL) {
+ /*
+ * Get another packet to be sent.
+ */
+ m = ppp_dequeue(sc);
+ if (m == NULL) {
+ idle = 1;
+ break;
+ }
+
+ /*
+ * The extra PPP_FLAG will start up a new packet, and thus
+ * will flush any accumulated garbage. We do this whenever
+ * the line may have been idle for some time.
+ */
+ if (CCOUNT(&tp->t_outq) == 0) {
+ ++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 (;;) {
+ start = mtod(m, u_char *);
+ len = m->m_len;
+ stop = start + len;
+ while (len > 0) {
+ /*
+ * Find out how many bytes in the string we can
+ * handle without doing something special.
+ */
+ for (cp = start; cp < stop; cp++)
+ if (ESCAPE_P(*cp))
+ break;
+ n = cp - start;
+ if (n) {
+ /* NetBSD (0.9 or later), 4.3-Reno or similar. */
+ ndone = n - b_to_q(start, n, &tp->t_outq);
+ len -= ndone;
+ start += 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.
+ * 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;
+ }
+ splx(s);
+ sc->sc_stats.ppp_obytes += 2;
+ start++;
+ len--;
+ }
+ }
+
+ /*
+ * If we didn't empty this mbuf, remember where we're up to.
+ * If we emptied the last mbuf, try to add the FCS and closing
+ * flag, and if we can't, leave sc_outm pointing to m, but with
+ * m->m_len == 0, to remind us to output the FCS and flag later.
+ */
+ done = len == 0;
+ if (done && m->m_next == NULL) {
+ u_char *p, *q;
+ int c;
+ u_char endseq[8];
+
+ /*
+ * We may have to escape the bytes in the FCS.
+ */
+ p = endseq;
+ c = ~sc->sc_outfcs & 0xFF;
+ if (ESCAPE_P(c)) {
+ *p++ = PPP_ESCAPE;
+ *p++ = c ^ PPP_TRANS;
+ } else
+ *p++ = c;
+ c = (~sc->sc_outfcs >> 8) & 0xFF;
+ if (ESCAPE_P(c)) {
+ *p++ = PPP_ESCAPE;
+ *p++ = c ^ PPP_TRANS;
+ } else
+ *p++ = c;
+ *p++ = PPP_FLAG;
+
+ /*
+ * 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;
+ for (; q > endseq; --q)
+ unputc(&tp->t_outq);
+ break;
+ }
+ splx(s);
+ if (done)
+ sc->sc_stats.ppp_obytes += q - endseq;
+ }
+
+ if (!done) {
+ /* remember where we got to */
+ m->m_data = start;
+ m->m_len = len;
+ break;
+ }
+
+ /* Finished with this mbuf; free it and move on. */
+ MFREE(m, m2);
+ m = m2;
+ if (m == NULL) {
+ /* Finished a packet */
+ break;
+ }
+ sc->sc_outfcs = pppfcs(sc->sc_outfcs, mtod(m, u_char *), m->m_len);
+ }
+
+ /*
+ * 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;
+ }
+
+ /* Call pppstart to start output again if necessary. */
s = spltty();
pppstart(tp);
- splx(s);
+
+ /*
+ * This timeout is needed for operation on a pseudo-tty,
+ * because the pty code doesn't call pppstart after it has
+ * drained the t_outq.
+ */
+ if (!idle && (sc->sc_flags & SC_TIMEOUT) == 0) {
+ timeout(ppp_timeout, (void *) sc, 1);
+ sc->sc_flags |= SC_TIMEOUT;
+ }
+
+ splx(s);
+
}
/*
@@ -530,187 +699,34 @@ pppasyncctlp(sc)
* 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, 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;
- }
-
- idle = 0;
- while (CCOUNT(&tp->t_outq) < PPP_HIWAT) {
- /*
- * See if we have an existing packet partly sent.
- * If not, get a new packet and start sending it.
- */
- m = sc->sc_outm;
- if (m == NULL) {
- /*
- * Get another packet to be sent.
- */
- m = ppp_dequeue(sc);
- if (m == NULL) {
- idle = 1;
- break;
- }
-
- /*
- * The extra PPP_FLAG will start up a new packet, and thus
- * will flush any accumulated garbage. We do this whenever
- * the line may have been idle for some time.
- */
- if (CCOUNT(&tp->t_outq) == 0) {
- ++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 (;;) {
- start = mtod(m, u_char *);
- len = m->m_len;
- stop = start + len;
- while (len > 0) {
- /*
- * Find out how many bytes in the string we can
- * handle without doing something special.
- */
- for (cp = start; cp < stop; cp++)
- if (ESCAPE_P(*cp))
- break;
- n = cp - start;
- if (n) {
- /* NetBSD (0.9 or later), 4.3-Reno or similar. */
- ndone = n - b_to_q(start, n, &tp->t_outq);
- len -= ndone;
- start += 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..
- * Put it out in a different form.
- */
- if (len) {
- if (putc(PPP_ESCAPE, &tp->t_outq))
- break;
- if (putc(*start ^ PPP_TRANS, &tp->t_outq)) {
- (void) unputc(&tp->t_outq);
- break;
- }
- sc->sc_stats.ppp_obytes += 2;
- start++;
- len--;
- }
- }
-
- /*
- * If we didn't empty this mbuf, remember where we're up to.
- * If we emptied the last mbuf, try to add the FCS and closing
- * flag, and if we can't, leave sc_outm pointing to m, but with
- * m->m_len == 0, to remind us to output the FCS and flag later.
- */
- done = len == 0;
- if (done && m->m_next == NULL) {
- u_char *p, *q;
- int c;
- u_char endseq[8];
-
- /*
- * We may have to escape the bytes in the FCS.
- */
- p = endseq;
- c = ~sc->sc_outfcs & 0xFF;
- if (ESCAPE_P(c)) {
- *p++ = PPP_ESCAPE;
- *p++ = c ^ PPP_TRANS;
- } else
- *p++ = c;
- c = (~sc->sc_outfcs >> 8) & 0xFF;
- if (ESCAPE_P(c)) {
- *p++ = PPP_ESCAPE;
- *p++ = c ^ PPP_TRANS;
- } else
- *p++ = c;
- *p++ = PPP_FLAG;
-
- /*
- * Try to output the FCS and flag. If the bytes
- * don't all fit, back out.
- */
- for (q = endseq; q < p; ++q)
- if (putc(*q, &tp->t_outq)) {
- done = 0;
- for (; q > endseq; --q)
- unputc(&tp->t_outq);
- break;
- }
- sc->sc_stats.ppp_obytes += q - endseq;
- }
-
- if (!done) {
- /* remember where we got to */
- m->m_data = start;
- m->m_len = len;
- break;
- }
-
- /* Finished with this mbuf; free it and move on. */
- MFREE(m, m2);
- m = m2;
- if (m == NULL) {
- /* Finished a packet */
- 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).
- */
- 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);
+ (*tp->t_oproc)(tp);
/*
- * This timeout is needed for operation on a pseudo-tty,
- * because the pty code doesn't call pppstart after it has
- * drained the t_outq.
+ * 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 (!idle && (sc->sc_flags & SC_TIMEOUT) == 0) {
- timeout(ppp_timeout, (void *) sc, 1);
- sc->sc_flags |= SC_TIMEOUT;
+ 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;
-}
+}
+
/*
* Timeout routine - try to start some more output.
@@ -777,7 +793,6 @@ pppinput(c, tp)
if (sc == NULL || tp != (struct tty *) sc->sc_devp)
return 0;
- s = spltty(); /* should be unnecessary */
++tk_nin;
++sc->sc_stats.ppp_ibytes;
@@ -809,6 +824,7 @@ pppinput(c, tp)
}
}
+ s = spltty();
if (c & 0x80)
sc->sc_flags |= SC_RCV_B7_1;
else
@@ -818,6 +834,7 @@ pppinput(c, tp)
else
sc->sc_flags |= SC_RCV_EVNP;
+ splx(s);
if (sc->sc_flags & SC_LOG_RAWIN)
ppplogchar(sc, c);
@@ -834,6 +851,7 @@ pppinput(c, tp)
*/
if (sc->sc_flags & (SC_FLUSH | SC_ESCAPED)
|| (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)
@@ -854,8 +872,8 @@ pppinput(c, tp)
sc->sc_if.if_ierrors++;
sc->sc_stats.ppp_ierrors++;
sc->sc_flags |= SC_PKTLOST;
+ splx(s);
}
- splx(s);
return 0;
}
@@ -876,25 +894,27 @@ 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);
return 0;
}
+ s = spltty();
if (sc->sc_flags & SC_ESCAPED) {
sc->sc_flags &= ~SC_ESCAPED;
c ^= PPP_TRANS;
@@ -903,6 +923,7 @@ pppinput(c, tp)
splx(s);
return 0;
}
+ splx(s);
/*
* Initialize buffer on first octet received.
@@ -993,9 +1014,11 @@ pppinput(c, tp)
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);
}
diff --git a/sys/net/slcompress.c b/sys/net/slcompress.c
index 59bd8a6ddff..8601bbd06c7 100644
--- a/sys/net/slcompress.c
+++ b/sys/net/slcompress.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: slcompress.c,v 1.4 1996/04/21 22:28:46 deraadt Exp $ */
+/* $OpenBSD: slcompress.c,v 1.5 1996/07/25 14:20:52 joshd Exp $ */
/* $NetBSD: slcompress.c,v 1.15 1996/03/15 02:28:12 paulus Exp $ */
/*
@@ -478,9 +478,17 @@ sl_uncompress_tcp_core(buf, buflen, total_len, type, comp, hdrp, hlenp)
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 *)&((int32_t *)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_hlen = hlen;
INCR(sls_uncompressedin)