/*
- * Copyright (c) 1987, 1989 Regents of the University of California.
+ * Copyright (c) 1987, 1989, 1992 Regents of the University of California.
* All rights reserved.
*
* %sccs.include.redist.c%
*
- * @(#)if_sl.c 7.22 (Berkeley) %G%
+ * @(#)if_sl.c 7.31 (Berkeley) %G%
*/
/*
* 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 "proc.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 "if.h"
-#include "if_types.h"
-#include "netisr.h"
-#include "route.h"
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/mbuf.h>
+#include <sys/buf.h>
+#include <sys/dkstat.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/file.h>
+#include <sys/tty.h>
+#include <sys/kernel.h>
+#include <sys/conf.h>
+
+#include <machine/cpu.h>
+
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/netisr.h>
+#include <net/route.h>
+
#if INET
-#include "netinet/in.h"
-#include "netinet/in_systm.h"
-#include "netinet/in_var.h"
-#include "netinet/ip.h"
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
#else
Huh? Slip without inet?
#endif
-#include "machine/mtpr.h"
-
-#include "slcompress.h"
-#include "if_slvar.h"
+#include <net/slcompress.h>
+#include <net/if_slvar.h>
/*
* SLMAX is a hard limit on input packet size. To simplify the code
* 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];
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;
/* ARGSUSED */
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;
*(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);
}
register struct sl_softc *sc = &sl_softc[ifp->if_unit];
register struct ip *ip;
register struct ifqueue *ifq;
+ register int p;
int s;
/*
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);
}
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
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)) {
*/
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
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);
}
*/
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,
(void) unputc(&tp->t_outq);
break;
}
- sc->sc_bytessent += 2;
+ sc->sc_if.if_obytes += 2;
}
}
MFREE(m, m2);
(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;
}
}
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
* 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;
}
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) {
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