X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/af951bc0b6cc98ca4f88e6e478fa13b0993db2b3..ad7871609881e73855d0b04da49b486cd93efca7:/usr/src/sys/net/if_sl.c diff --git a/usr/src/sys/net/if_sl.c b/usr/src/sys/net/if_sl.c index 92b62030f5..0f51fc2a18 100644 --- a/usr/src/sys/net/if_sl.c +++ b/usr/src/sys/net/if_sl.c @@ -1,20 +1,36 @@ /* - * Copyright (c) 1987, 1989 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1987, 1989, 1992, 1993 + * The Regents of the University of California. All rights reserved. * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. * - * @(#)if_sl.c 7.19 (Berkeley) %G% + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)if_sl.c 8.1 (Berkeley) 6/10/93 */ /* @@ -48,41 +64,39 @@ * interrupts and network activity; thus, splimp must be >= spltty. */ -/* $Header: if_sl.c,v 1.7 89/05/31 02:24:52 van Exp $ */ -/* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */ - #include "sl.h" #if NSL > 0 -#include "param.h" -#include "dir.h" -#include "user.h" -#include "mbuf.h" -#include "buf.h" -#include "dk.h" -#include "socket.h" -#include "ioctl.h" -#include "file.h" -#include "tty.h" -#include "kernel.h" -#include "conf.h" -#include "errno.h" - -#include "if.h" -#include "if_types.h" -#include "netisr.h" -#include "route.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + #if INET -#include "../netinet/in.h" -#include "../netinet/in_systm.h" -#include "../netinet/in_var.h" -#include "../netinet/ip.h" +#include +#include +#include +#include +#else +Huh? Slip without inet? #endif -#include "machine/mtpr.h" - -#include "slcompress.h" -#include "if_slvar.h" +#include +#include /* * SLMAX is a hard limit on input packet size. To simplify the code @@ -135,26 +149,13 @@ * SLIP ABORT ESCAPE MECHANISM: * (inspired by HAYES modem escape arrangement) * 1sec escape 1sec escape 1sec escape { 1sec escape 1sec escape } - * signals a "soft" exit from slip mode by usermode process + * within window time signals a "soft" exit from slip mode by remote end + * if the IFF_DEBUG flag is on. */ - #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 */ - -/* - * The following disgusting hack gets around the problem that IP TOS - * can't be set yet. We want to put "interactive" traffic on a high - * priority queue. To decide if traffic is interactive, we check that - * a) it is TCP and b) one of its ports is telnet, rlogin or ftp control. - */ -static u_short interactive_ports[8] = { - 0, 513, 0, 0, - 0, 21, 0, 23, -}; -#define INTERACTIVE(p) (interactive_ports[(p) & 7] == (p)) +#define ABT_IDLE 1 /* in seconds - idle before an escape */ +#define ABT_COUNT 3 /* count of escapes for abort */ +#define ABT_WINDOW (ABT_COUNT*2+2) /* in seconds - time to count */ struct sl_softc sl_softc[NSL]; @@ -165,12 +166,15 @@ struct sl_softc sl_softc[NSL]; #define t_sc T_LINEP -int sloutput(), slioctl(), ttrstrt(); extern struct timeval time; +static int slinit __P((struct sl_softc *)); +static struct mbuf *sl_btom __P((struct sl_softc *, int)); + /* * Called from boot code to establish sl interfaces. */ +void slattach() { register struct sl_softc *sc; @@ -178,9 +182,11 @@ slattach() for (sc = sl_softc; i < NSL; sc++) { sc->sc_if.if_name = "sl"; + sc->sc_if.if_next = NULL; sc->sc_if.if_unit = i++; sc->sc_if.if_mtu = SLMTU; - sc->sc_if.if_flags = IFF_POINTOPOINT; + sc->sc_if.if_flags = + IFF_POINTOPOINT | SC_AUTOCOMP | IFF_MULTICAST; sc->sc_if.if_type = IFT_SLIP; sc->sc_if.if_ioctl = slioctl; sc->sc_if.if_output = sloutput; @@ -217,15 +223,17 @@ slinit(sc) * Attach the given tty to the first available sl unit. */ /* ARGSUSED */ +int slopen(dev, tp) dev_t dev; register struct tty *tp; { + struct proc *p = curproc; /* XXX */ register struct sl_softc *sc; register int nsl; int error; - if (error = suser(u.u_cred, &u.u_acflag)) + if (error = suser(p->p_ucred, &p->p_acflag)) return (error); if (tp->t_line == SLIPDISC) @@ -247,8 +255,8 @@ slopen(dev, tp) /* * Line specific close routine. * Detach the tty from the sl unit. - * Mimics part of ttyclose(). */ +void slclose(tp) struct tty *tp; { @@ -276,31 +284,21 @@ slclose(tp) * Provide a way to get the sl unit number. */ /* ARGSUSED */ +int sltioctl(tp, cmd, data, flag) struct tty *tp; + int cmd; caddr_t data; + int flag; { struct sl_softc *sc = (struct sl_softc *)tp->t_sc; int s; switch (cmd) { - case TIOCGETD: /* XXX */ - case SLIOGUNIT: + case SLIOCGUNIT: *(int *)data = sc->sc_if.if_unit; break; - case SLIOCGFLAGS: - *(int *)data = sc->sc_flags; - break; - - case SLIOCSFLAGS: -#define SC_MASK 0xffff - s = splimp(); - sc->sc_flags = - (sc->sc_flags &~ SC_MASK) | ((*(int *)data) & SC_MASK); - splx(s); - break; - default: return (-1); } @@ -310,14 +308,17 @@ sltioctl(tp, cmd, data, flag) /* * Queue a packet. Start transmission if not active. */ -sloutput(ifp, m, dst) +int +sloutput(ifp, m, dst, rtp) struct ifnet *ifp; register struct mbuf *m; struct sockaddr *dst; + struct rtentry *rtp; { register struct sl_softc *sc = &sl_softc[ifp->if_unit]; register struct ip *ip; register struct ifqueue *ifq; + register int p; int s; /* @@ -328,6 +329,7 @@ sloutput(ifp, m, dst) printf("sl%d: af%d not supported\n", sc->sc_if.if_unit, dst->sa_family); m_freem(m); + sc->sc_if.if_noproto++; return (EAFNOSUPPORT); } @@ -340,16 +342,14 @@ sloutput(ifp, m, dst) return (EHOSTUNREACH); } ifq = &sc->sc_if.if_snd; - if ((ip = mtod(m, struct ip *))->ip_p == IPPROTO_TCP) { - register int p = ((int *)ip)[ip->ip_hl]; - - if (INTERACTIVE(p & 0xffff) || INTERACTIVE(p >> 16)) { - ifq = &sc->sc_fastq; - p = 1; - } else - p = 0; - - if (sc->sc_flags & SC_COMPRESS) { + ip = mtod(m, struct ip *); + if (ip->ip_tos & IPTOS_LOWDELAY) { + ifq = &sc->sc_fastq; + p = 1; + } else + p = 0; + if (ip->ip_p == IPPROTO_TCP) { + if (sc->sc_if.if_flags & SC_COMPRESS) { /* * The last parameter turns off connection id * compression for background traffic: Since @@ -360,9 +360,9 @@ sloutput(ifp, m, dst) 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) { + } else if (sc->sc_if.if_flags & SC_NOICMP && ip->ip_p == IPPROTO_ICMP) { m_freem(m); - return (0); + return (ENETRESET); /* XXX ? */ } s = splimp(); if (IF_QFULL(ifq)) { @@ -385,6 +385,7 @@ 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; { @@ -417,12 +418,15 @@ slstart(tp) */ s = splimp(); IF_DEQUEUE(&sc->sc_fastq, m); - if (m == NULL) + if (m) + sc->sc_if.if_omcasts++; /* XXX */ + else IF_DEQUEUE(&sc->sc_if.if_snd, m); 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 @@ -433,14 +437,13 @@ slstart(tp) sc->sc_if.if_collisions++; continue; } - /* * The extra FRAME_END 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 (tp->t_outq.c_cc == 0) { - ++sc->sc_bytessent; + ++sc->sc_if.if_obytes; (void) putc(FRAME_END, &tp->t_outq); } @@ -471,7 +474,7 @@ slstart(tp) */ if (b_to_q((char *)bp, cp - bp, &tp->t_outq)) break; - sc->sc_bytessent += cp - bp; + sc->sc_if.if_obytes += cp - bp; } /* * If there are characters left in the mbuf, @@ -487,7 +490,7 @@ slstart(tp) (void) unputc(&tp->t_outq); break; } - sc->sc_bytessent += 2; + sc->sc_if.if_obytes += 2; } } MFREE(m, m2); @@ -506,10 +509,9 @@ slstart(tp) (void) putc(FRAME_END, &tp->t_outq); sc->sc_if.if_collisions++; } else { - ++sc->sc_bytessent; + ++sc->sc_if.if_obytes; sc->sc_if.if_opackets++; } - sc->sc_if.if_obytes = sc->sc_bytessent; } } @@ -559,6 +561,7 @@ sl_btom(sc, len) /* * tty interface receiver interrupt. */ +void slinput(c, tp) register int c; register struct tty *tp; @@ -575,33 +578,33 @@ slinput(c, tp) if (!(tp->t_state&TS_CARR_ON)) /* XXX */ return; - ++sc->sc_bytesrcvd; ++sc->sc_if.if_ibytes; c &= 0xff; /* XXX */ #ifdef ABT_ESC - if (sc->sc_flags & SC_ABORT) { - /* if we see an abort after "idle" time, count it */ - if (c == ABT_ESC && time.tv_sec >= sc->sc_lasttime + ABT_WAIT) { - sc->sc_abortcount++; - /* record when the first abort escape arrived */ - if (sc->sc_abortcount == 1) - sc->sc_starttime = time.tv_sec; - } - /* - * if we have an abort, see that we have not run out of time, - * or that we have an "idle" time after the complete escape - * sequence - */ - if (sc->sc_abortcount) { - if (time.tv_sec >= sc->sc_starttime + ABT_RECYCLE) + if (sc->sc_if.if_flags & IFF_DEBUG) { + if (c == ABT_ESC) { + /* + * If we have a previous abort, see whether + * this one is within the time limit. + */ + if (sc->sc_abortcount && + time.tv_sec >= sc->sc_starttime + ABT_WINDOW) sc->sc_abortcount = 0; - if (sc->sc_abortcount >= ABT_SOFT && - time.tv_sec >= sc->sc_lasttime + ABT_WAIT) { - slclose(tp); - return; + /* + * If we see an abort after "idle" time, count it; + * record when the first abort escape arrived. + */ + if (time.tv_sec >= sc->sc_lasttime + ABT_IDLE) { + if (++sc->sc_abortcount == 1) + sc->sc_starttime = time.tv_sec; + if (sc->sc_abortcount >= ABT_COUNT) { + slclose(tp); + return; + } } - } + } else + sc->sc_abortcount = 0; sc->sc_lasttime = time.tv_sec; } #endif @@ -640,18 +643,18 @@ slinput(c, tp) * it's a reasonable packet, decompress it and then * enable compression. Otherwise, drop it. */ - if (sc->sc_flags & SC_COMPRESS) { + if (sc->sc_if.if_flags & SC_COMPRESS) { len = sl_uncompress_tcp(&sc->sc_buf, len, (u_int)c, &sc->sc_comp); if (len <= 0) goto error; - } else if ((sc->sc_flags & SC_AUTOCOMP) && + } else if ((sc->sc_if.if_flags & SC_AUTOCOMP) && c == TYPE_UNCOMPRESSED_TCP && len >= 40) { len = sl_uncompress_tcp(&sc->sc_buf, len, (u_int)c, &sc->sc_comp); if (len <= 0) goto error; - sc->sc_flags |= SC_COMPRESS; + sc->sc_if.if_flags |= SC_COMPRESS; } else goto error; } @@ -689,13 +692,15 @@ newpack: /* * Process an ioctl request. */ +int slioctl(ifp, cmd, data) register struct ifnet *ifp; int cmd; caddr_t data; { register struct ifaddr *ifa = (struct ifaddr *)data; - int s = splimp(), error = 0; + register struct ifreq *ifr; + register int s = splimp(), error = 0; switch (cmd) { @@ -711,10 +716,30 @@ slioctl(ifp, cmd, data) error = EAFNOSUPPORT; break; + case SIOCADDMULTI: + case SIOCDELMULTI: + ifr = (struct ifreq *)data; + if (ifr == 0) { + error = EAFNOSUPPORT; /* XXX */ + break; + } + switch (ifr->ifr_addr.sa_family) { + +#ifdef INET + case AF_INET: + break; +#endif + + default: + error = EAFNOSUPPORT; + break; + } + break; +#endif + default: error = EINVAL; } splx(s); return (error); } -#endif