diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/net/bsd_comp.c | 25 | ||||
-rw-r--r-- | sys/net/if_pppvar.h | 18 | ||||
-rw-r--r-- | sys/net/ppp_comp.h | 30 | ||||
-rw-r--r-- | sys/net/ppp_defs.h | 66 | ||||
-rw-r--r-- | sys/net/ppp_tty.c | 254 | ||||
-rw-r--r-- | sys/net/slcompress.c | 185 | ||||
-rw-r--r-- | sys/net/slcompress.h | 24 |
7 files changed, 377 insertions, 225 deletions
diff --git a/sys/net/bsd_comp.c b/sys/net/bsd_comp.c index 40da4e5..f4f2984 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_pppvar.h b/sys/net/if_pppvar.h index 196e54b..91e8e4e 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 e2579f8..adab65c 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 77f01bb..49a6e53 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 5ad17d2..912f083 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 70af935..9e6346c 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 cefe940..f5e0cf7 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 *)); |