--- Net2/net/if_sl.c 2018/04/24 18:04:02 1.1.1.1 +++ Net2/net/if_sl.c 2018/04/24 18:21:41 1.1.1.5 @@ -30,7 +30,10 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)if_sl.c 7.22 (Berkeley) 4/20/91 + * from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp + * + * from: @(#)if_sl.c 7.22 (Berkeley) 4/20/91 + * if_sl.c,v 1.8 1993/05/22 11:42:11 cgd Exp */ /* @@ -64,9 +67,6 @@ * interrupts and network activity; thus, splimp must be >= spltty. */ -/* $Header: /var/lib/cvsd/net2/Net2/net/if_sl.c,v 1.1.1.1 2018/04/24 18:04:02 root Exp $ */ -/* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */ - #include "sl.h" #if NSL > 0 @@ -99,6 +99,13 @@ Huh? Slip without inet? #include "slcompress.h" #include "if_slvar.h" +#include "slip.h" + +#include "bpfilter.h" +#if NBPFILTER > 0 +#include +#include +#endif /* * SLMAX is a hard limit on input packet size. To simplify the code @@ -140,12 +147,15 @@ Huh? Slip without inet? * time. So, setting SLIP_HIWAT to ~100 guarantees that we'll lose * at most 1% while maintaining good interactive response. */ -#define BUFOFFSET 128 +#if NBPFILTER > 0 +#define BUFOFFSET (128+sizeof(struct ifnet **)+SLIP_HDRLEN) +#else +#define BUFOFFSET (128+sizeof(struct ifnet **)) +#endif #define SLMAX (MCLBYTES - BUFOFFSET) #define SLBUFSIZE (SLMAX + BUFOFFSET) -#define SLMTU 296 +#define SLMTU 296 /* try 1006 later */ #define SLIP_HIWAT roundup(50,CBSIZE) -#define CLISTRESERVE 1024 /* Can't let clists get too low */ /* * SLIP ABORT ESCAPE MECHANISM: @@ -154,11 +164,13 @@ Huh? Slip without inet? * signals a "soft" exit from slip mode by usermode process */ +#ifdef ABT_ESC +#undef ABT_ESC #define ABT_ESC '\033' /* can't be t_intr - distant host must know it*/ #define ABT_WAIT 1 /* in seconds - idle before an escape & after */ #define ABT_RECYCLE (5*2+2) /* in seconds - time window processing abort */ - #define ABT_SOFT 3 /* count of escapes */ +#endif /* ABT_ESC */ /* * The following disgusting hack gets around the problem that IP TOS @@ -203,6 +215,10 @@ slattach() sc->sc_if.if_snd.ifq_maxlen = 50; sc->sc_fastq.ifq_maxlen = 32; if_attach(&sc->sc_if); +#if NBPFILTER > 0 + bpfattach(&sc->sc_bpf, &sc->sc_if, DLT_SLIP, + SLIP_HDRLEN); +#endif } } @@ -233,9 +249,8 @@ slinit(sc) * Attach the given tty to the first available sl unit. */ /* ARGSUSED */ -slopen(dev, tp) - dev_t dev; - register struct tty *tp; +int +slopen(dev_t dev, struct tty *tp) { struct proc *p = curproc; /* XXX */ register struct sl_softc *sc; @@ -266,8 +281,10 @@ slopen(dev, tp) * Detach the tty from the sl unit. * Mimics part of ttyclose(). */ -slclose(tp) +void +slclose(tp, flag) struct tty *tp; + int flag; { register struct sl_softc *sc; int s; @@ -357,25 +374,13 @@ sloutput(ifp, m, dst) } ifq = &sc->sc_if.if_snd; if ((ip = mtod(m, struct ip *))->ip_p == IPPROTO_TCP) { - register int p = ((int *)ip)[ip->ip_hl]; + u_short srcport = ntohs(((short *)ip)[ip->ip_hl << 1]); + u_short dstport = ntohs(((short *)ip)[(ip->ip_hl << 1) + 1]); - if (INTERACTIVE(p & 0xffff) || INTERACTIVE(p >> 16)) { + if (INTERACTIVE(srcport) || INTERACTIVE(dstport)) { ifq = &sc->sc_fastq; - p = 1; - } else - p = 0; - - if (sc->sc_flags & SC_COMPRESS) { - /* - * The last parameter turns off connection id - * compression for background traffic: Since - * fastq traffic can jump ahead of the background - * traffic, we don't know what order packets will - * go on the line. - */ - p = sl_compress_tcp(m, ip, &sc->sc_comp, p); - *mtod(m, u_char *) |= p; } + } else if (sc->sc_flags & SC_NOICMP && ip->ip_p == IPPROTO_ICMP) { m_freem(m); return (0); @@ -401,15 +406,20 @@ sloutput(ifp, m, dst) * to send from the interface queue and map it to * the interface before starting output. */ +void slstart(tp) register struct tty *tp; { register struct sl_softc *sc = (struct sl_softc *)tp->t_sc; register struct mbuf *m; register u_char *cp; + register struct ip *ip; int s; struct mbuf *m2; - extern int cfreecount; +#if NBPFILTER > 0 + u_char bpfbuf[SLMTU + SLIP_HDRLEN]; + register int len; +#endif for (;;) { /* @@ -429,6 +439,17 @@ slstart(tp) return; /* + * Do not remove the packet from the IP queue if it + * doesn't look like the packet will fit into the + * current COM output queue, with a packet full of + * escapes this could be as bad as SLMTU*2. The size + * of the ring buffer must be at least SLMTU*2 to + * avoid deadlock. + */ + if (tp->t_outq.c_cn - tp->t_outq.c_cc < 2 * SLMTU) + return; + + /* * Get a packet and send it to the interface. */ s = splimp(); @@ -438,17 +459,50 @@ slstart(tp) splx(s); if (m == NULL) return; - sc->sc_if.if_lastchange = time; /* - * If system is getting low on clists, just flush our - * output queue (if the stuff was important, it'll get - * retransmitted). + * We do the header compression here rather than in sl_output + * because the packets will be out of order if we are using TOS + * queueing, and the connection id compression will get messed + * up when this happens. */ - if (cfreecount < CLISTRESERVE + SLMTU) { - m_freem(m); - sc->sc_if.if_collisions++; - continue; +#if NBPFILTER > 0 + if (sc->sc_bpf) { + /* + * We need to save the TCP/IP header before it's compressed. + * To avoid complicated code, we just copy the entire packet + * into a stack buffer (since this is a serial line, packets + * should be short and/or the copy should be negligible cost + * compared to the packet transmission time). + */ + register struct mbuf *m1 = m; + register u_char *cp = bpfbuf + SLIP_HDRLEN; + len = 0; + do { + register int mlen = m1->m_len; + + bcopy(mtod(m1, caddr_t), cp, mlen); + cp += mlen; + len += mlen; + } while (m1 = m1->m_next); } +#endif + if ((ip = mtod(m, struct ip *))->ip_p == IPPROTO_TCP) { + if (sc->sc_flags & SC_COMPRESS) + *mtod(m, u_char *) |= sl_compress_tcp(m, ip, &sc->sc_comp, 1); + } +#if NBPFILTER > 0 + if (sc->sc_bpf) { + /* + * Put the SLIP pseudo-"link header" in place. The compressed + * header is now at the beginning of the mbuf. + */ + bpfbuf[SLX_DIR] = SLIPDIR_OUT; + bcopy(mtod(m, caddr_t), &bpfbuf[SLX_CHDR], CHDR_LEN); + bpf_tap(sc->sc_bpf, bpfbuf, len + SLIP_HDRLEN); + } +#endif + + sc->sc_if.if_lastchange = time; /* * The extra FRAME_END will start up a new packet, and thus @@ -485,7 +539,7 @@ slstart(tp) * Put n characters at once * into the tty output queue. */ - if (b_to_q((char *)bp, cp - bp, &tp->t_outq)) + if (b_to_q((u_char *)bp, cp - bp, &tp->t_outq)) break; sc->sc_bytessent += cp - bp; } @@ -575,6 +629,7 @@ sl_btom(sc, len) /* * tty interface receiver interrupt. */ +void slinput(c, tp) register int c; register struct tty *tp; @@ -583,17 +638,20 @@ slinput(c, tp) register struct mbuf *m; register int len; int s; - +#if NBPFILTER > 0 + u_char chdr[CHDR_LEN]; +#endif tk_nin++; sc = (struct sl_softc *)tp->t_sc; if (sc == NULL) return; - if (!(tp->t_state&TS_CARR_ON)) /* XXX */ + if (c & TTY_ERRORMASK|| !(tp->t_state&TS_CARR_ON)) { + sc->sc_flags |= SC_ERROR; return; + } ++sc->sc_bytesrcvd; ++sc->sc_if.if_ibytes; - c &= 0xff; /* XXX */ #ifdef ABT_ESC if (sc->sc_flags & SC_ABORT) { @@ -639,11 +697,28 @@ slinput(c, tp) return; case FRAME_END: + if(sc->sc_flags & SC_ERROR) { + sc->sc_flags &= ~SC_ERROR; + goto newpack; + } len = sc->sc_mp - sc->sc_buf; + if (len < 3) /* less than min length packet - ignore */ goto newpack; +#if NBPFILTER > 0 + if (sc->sc_bpf) + /* + * Save the compressed header, so we can + * tack it on later. Note that we just + * we will end up copying garbage in some + * cases but this is okay. We remember + * where the buffer started so we can + * compute the new header length. + */ + bcopy(sc->sc_buf, chdr, CHDR_LEN); +#endif if ((c = (*sc->sc_buf & 0xf0)) != (IPVERSION << 4)) { if (c & 0x80) c = TYPE_COMPRESSED_TCP; @@ -671,6 +746,21 @@ slinput(c, tp) } else goto error; } +#if NBPFILTER > 0 + if (sc->sc_bpf) { + /* + * Put the SLIP pseudo-"link header" in place. + * We couldn't do this any earlier since + * decompression probably moved the buffer + * pointer. Then, invoke BPF. + */ + register u_char *hp = sc->sc_buf - SLIP_HDRLEN; + + hp[SLX_DIR] = SLIPDIR_IN; + bcopy(chdr, &hp[SLX_CHDR], CHDR_LEN); + bpf_tap(sc->sc_bpf, hp, len + SLIP_HDRLEN); + } +#endif m = sl_btom(sc, len); if (m == NULL) goto error; @@ -695,6 +785,7 @@ slinput(c, tp) sc->sc_escape = 0; return; } + sc->sc_flags |= SC_ERROR; error: sc->sc_if.if_ierrors++; newpack: