⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 if_sl.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef lintstatic	char	*sccsid = "@(#)if_sl.c	4.3		(ULTRIX)		2/1/91";#endif lint/* * Copyright (c) 1989 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. * * Based on - *	Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: *	- Initial distribution. * * As modified for Ultrix V4.0 by - *      Tim Theisen             Department of Computer Sciences *      tim@cs.wisc.edu         University of Wisconsin-Madison *      uwvax!tim               1210 West Dayton Street *      (608)262-0438           Madison, WI   53706 * * And finally the NSL version is by - *      Michael Reilly          Network Systems Lab *      reilly@nsl.dec.com      Digital Equipment corporation *                              505 Hamilton Avenue *                              Palo Alto, CA  94301 * * For Ultrix V3.1 or V4.0 on a mips based DECstation * *//* * NOTE:  You must define either ULTRIX_3 for an Ultrix V3.1 driver or *                               ULTRIX_4 for an Ultrix V4.0 driver *//* * Serial Line interface * * Originally written by * 	Rick Adams * 	Center for Seismic Studies * 	1300 N 17th Street, Suite 1450 * 	Arlington, Virginia 22209 * 	(703)276-7900 * 	rick@seismo.css.gov * 	seismo!rick * * Pounded on heavily by Chris Torek (chris@mimsy.umd.edu, umcp-cs!chris). * N.B.: this belongs in netinet, not net, the way it stands now. * Should have a link-layer type designation, but wouldn't be * backwards-compatible. * * Converted to 4.3BSD Beta by Chris Torek. * Other changes made at Berkeley, based in part on code by Kirk Smith. * * Hacked almost beyond recognition by Van Jacobson (van@helios.ee.lbl.gov). * Added priority queuing for "interactive" traffic; hooks for TCP * header compression; ICMP filtering (at 2400 baud, some cretin * pinging you can use up all your bandwidth); conditionals for Sun * OS 3.x in addition to 4.x BSD.  Made low clist behavior more robust * and slightly less likely to hang serial line.  Sped up a bunch of * things. *//* originally from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp *//* And from if_sl.c,v 1.12 90/08/20 14:24:28 tim Exp */#define ULTRIX_4#ifdef ultrix#if !defined(ULTRIX_3) && !defined(ULTRIX_4)#include "Either option ULTRIX_3 or ULTRIX_4 must be defined"#endif#endif#include "sl.h"#if NSL > 0#if defined(ultrix) && defined(ULTRIX_3)#include "../data/if_sl_data.c"#endif#if defined(ultrix) && defined(ULTRIX_4)#include "../../data/if_sl_data.c"#endif#ifdef ultrix#if defined(ULTRIX_3) && defined(ULTRIX_4)#include "Error - both ULTRIX_3 and ULTRIX_4 are defined"#endif#endif/* * The following are patchable defaults for the three options * in the interface flags word.  If desired, they should be set * by config file options SL_DOCOMPRESS, SL_ALLOWCOMPRESS and * SL_NOICMP. * *   sl_docompress	If = 1, compression for a line will default to "on" * *   sl_allowcompres	If = 1, compression for a line will default to "off" *			but will be turned on if a compressed packet is *			received.  * *   sl_noicmp		If = 1, outbound ICMP packets will be discarded. *			XXX - shouldn't have to set this but some cretin *			pinging us can drive our throughput to zero (not *			to mention the raft of quenches we'll get if we're *			unlucky enough to have to traverse the milnet. */#ifndef SL_DOCOMPRESS#define SL_DOCOMPRESS 0#endif#ifndef SL_ALLOWCOMPRESS#define SL_ALLOWCOMPRESS 0#endif#ifndef SL_NOICMP#define SL_NOICMP 0#endifint sl_docompress = SL_DOCOMPRESS;int sl_allowcompress = SL_ALLOWCOMPRESS;int sl_noicmp = SL_NOICMP;/* Compatibility with 4.2 BSD (and variants) */#ifndef MCLBYTES#ifdef ultrix#define MCLBYTES M_CLUSTERSZ#else#define MCLBYTES CLBYTES#endif#endif/* * SLMAX is a hard limit on input packet size.  To simplify the code * and improve performance, we require that packets fit in an mbuf * cluster, that there be enough extra room for the ifnet pointer that * IP input requires and, if we get a compressed packet, there's * enough extra room to expand the header into a max length tcp/ip * header (128 bytes).  So, SLMAX can be at most *	MCLBYTES - sizeof(struct ifnet *) - 128 * * SLMTU is a hard limit on output packet size.  To insure good * interactive response, SLMTU wants to be the smallest size that * amortizes the header cost.  (Remember that even with * type-of-service queuing, we have to wait for any in-progress * packet to finish.  I.e., we wait, on the average, 1/2 * mtu / * cps, where cps is the line speed in characters per second. * E.g., 533ms wait for a 1024 byte MTU on a 9600 baud line.  The * average compressed header size is 6-8 bytes so any MTU > 90 * bytes will give us 90% of the line bandwidth.  A 100ms wait is * tolerable (500ms is not), so want an MTU around 296.  (Since TCP * will send 256 byte segments (to allow for 40 byte headers), the * typical packet size on the wire will be around 260 bytes).  In * 4.3tahoe+ systems, we can set an MTU in a route so we do that & * leave the interface MTU relatively high (so we don't IP fragment * when acting as a gateway to someone using a stupid MTU). * * Similar considerations apply to SLIP_HIWAT:  It's the amount of * data that will be queued 'downstream' of us (i.e., in clists * waiting to be picked up by the tty output interrupt).  If we * queue a lot of data downstream, it's immune to our t.o.s. queuing. * E.g., if SLIP_HIWAT is 1024, the interactive traffic in mixed * telnet/ftp will see a 1 sec wait, independent of the mtu (the * wait is dependent on the ftp window size but that's typically * 1k - 4k).  So, we want SLIP_HIWAT just big enough to amortize * the cost (in idle time on the wire) of the tty driver running * off the end of its clists & having to call back slstart for a * new packet.  For a tty interface with any buffering at all, this * cost will be zero.  Even with a totally brain dead interface (like * the one on a typical workstation), the cost will be <= 1 character * time.  So, setting SLIP_HIWAT to ~100 guarantees that we'll lose * at most 1% while maintaining good interactive response. */#define BUFOFFSET (128+sizeof(struct ifnet **))#define	SLMAX	(MCLBYTES - BUFOFFSET)#define	SLMTU	296#define	SLIP_HIWAT	roundup(50,CBSIZE)#define	CLISTRESERVE	1024	/* Can't let clists get too low *//* * The following disgusting hack gets around the problem that IP TOS * can't be set in BSD/Sun OS 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 it's ports * if 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 FRAME_END		0xc0		/* Frame End */#define FRAME_ESCAPE		0xdb		/* Frame Esc */#define TRANS_FRAME_END		0xdc		/* transposed frame end */#define TRANS_FRAME_ESCAPE	0xdd		/* transposed frame esc */#ifdef sun#define t_sc t_linep#else#define t_sc T_LINEP#endif#if defined(SL_NIT) && defined(NIT)#include "../h/time.h"#include "../net/nit.h"#include "../netinet/if_ether.h"extern struct nit_cb nitcb;int sl_donit = 0;#endif/* Sun OS3.x doesn't have an MCLGET or MCLFREE.  Sun OS4.x doesn't * have an MCLFREE.  The code below should work on either Sun OS * (this driver, however will *NOT* work on a stock Sun OS4 system * because of the slow, broken, worthless, System-V "streams" tty * driver). * * All BSD systems since 4.1c have both MCLGET and MCLFREE. * However 4.2bsd had a second, unused parameter to MCLGET.  Some * versions of cpp may complain if you compile this routine under * a stock 4.2bsd.  For reasons I have never understood, various * vendors chose to break BSD in mysterious ways (e.g., DEC's Ultrix * changed the definition of m_off to make mbuf cluster use * a factor of two more costly -- no doubt this was done to encourage * the sale of faster processors since there is no technical * justification whatsoever for the change).  If you are stuck with * one of these abortions and, for reasons best known to yourself, * don't want to upgrade to the BSD network code freely available via * anonymous ftp from ucbarpa.berkeley.edu, the following macros * might give you a prototype to work from.  Then again, they might * not.  Good luck. */#ifdef sun#ifndef MCLGET#define MCLGET(m) { int ms = splimp(); (void)mclget(m); (void) splx(ms); }#endif#ifndef MCLFREE#define	MCLFREE(p) { \	extern char *mclrefcnt; \	struct mbuf mxxx; \	mxxx.m_len = MCLBYTES; \	mxxx.m_off = (int)p - (int)xm; \	mxxx.m_cltype = 1; \	mclput(&mxxx); \	}#endif#endif#ifdef ultrix/* Ultrix 3.x on Vaxen misdefines the MCLGET macro to cause the m_len field * to be set to half of the amount actually allocated.  Thus this re- * definition is necessary. */#if defined(vax) && defined(ULTRIX_3)#undef MCLGET#define MCLGET(m, p) \        KM_ALLOC((p), struct mbuf *, M_CLUSTERSZ, KM_CLUSTER, KM_NOWAIT); \        if((p)) { \                (m)->m_cltype = M_CLTYPE1; (m)->m_clptr = (caddr_t) p; \                m->m_off = (int)(p); m->m_len = M_CLUSTERSZ; \                mbstat.m_clfree++; mbstat.m_clusters++; \        }#endif defined(vax) && defined(ULTRIX_3)#ifndef MCLFREE#define	MCLFREE(p) { \	KM_FREE((p), KM_CLUSTER); \	mbstat.m_clusters--; mbstat.m_clfree--; \	}#endif#endifint sloutput(), slioctl();/* * Called from boot code to establish sl interfaces. */slattach(){	register struct sl_softc *sc;	register int i = 0;#if defined(ultrix) && defined(ULTRIX_4)	int s;#endif	if (sl_softc[0].sc_if.if_name == NULL) {		for (sc = sl_softc; i < nNSL; sc++) {			sc->sc_if.if_name = "sl";			sc->sc_if.if_unit = i++;			sc->sc_if.if_mtu = SLMTU;			sc->sc_if.if_flags = IFF_POINTOPOINT;			sc->sc_if.if_ioctl = slioctl;			sc->sc_if.if_output = sloutput;			sc->sc_if.if_snd.ifq_maxlen = 50;			sc->sc_fastq.ifq_maxlen = 32;#if defined(ultrix) && defined(ULTRIX_4)			s = splnet();	/* SMP */			if_attach(&sc->sc_if);			splx(s);#else			if_attach(&sc->sc_if);#endif		}	}}static intslinit(sc)	register struct sl_softc *sc;{	if (sc->sc_ep == (u_char *) 0) {		struct mbuf m;#ifdef ultrix		struct mbuf *p;		MCLGET((&m),p);#else		MCLGET((&m));#endif		if (m.m_len == MCLBYTES)			sc->sc_ep = mtod(&m,u_char *) + (BUFOFFSET + SLMAX);		else {			printf("sl%d: can't allocate buffer\n", sc - sl_softc);			sc->sc_if.if_flags &= ~IFF_UP;			return (0);		}	}	sc->sc_buf = sc->sc_ep - SLMAX;	sc->sc_mp = sc->sc_buf;	if (sl_docompress)		sc->sc_if.if_flags |= IFF_D1;	else 		sc->sc_if.if_flags &=~ IFF_D1;	if (sl_allowcompress)		sc->sc_if.if_flags |= IFF_D2;	else 		sc->sc_if.if_flags &=~ IFF_D2;	if (sl_noicmp)		sc->sc_if.if_flags |= IFF_D3;	else 		sc->sc_if.if_flags &=~ IFF_D3;	sl_compress_init(&sc->sc_comp);	return (1);}/* * Line specific open routine. * Attach the given tty to the first available sl unit. *//* ARGSUSED */slopen(dev, tp)	dev_t dev;	register struct tty *tp;{	register struct sl_softc *sc;	register int nsl;	if (!suser())		return (EPERM);#ifdef ultrix	slattach();#define SLIPDISC SLPDISC#endif	if (tp->t_line == SLIPDISC)		return (EBUSY);	for (nsl = nNSL, sc = sl_softc; --nsl >= 0; sc++)		if (sc->sc_ttyp == NULL) {			if (slinit(sc) == 0)				return (ENOBUFS);			tp->t_sc = (caddr_t)sc;			sc->sc_ttyp = tp;			ttyflush(tp, FREAD | FWRITE);			return (0);		}	return (ENXIO);}#ifdef sun/* XXX - Sun OS3 is missing these 4bsd routines. * * Mark an interface down and notify protocols of * the transition. */static voidif_down(ifp)	register struct ifnet *ifp;{	register struct ifqueue *ifq = &ifp->if_snd;	register struct mbuf *m, *n;	ifp->if_flags &=~ IFF_UP;	pfctlinput(PRC_IFDOWN, &ifp->if_addr);	/* Flush the interface queue. */	n = ifq->ifq_head;	while (m = n) {		n = m->m_act;		m_freem(m);	}	ifq->ifq_head = 0;	ifq->ifq_tail = 0;	ifq->ifq_len = 0;}static voidif_rtdelete(ifp)	register struct ifnet *ifp;{	static struct rtentry route;	if (ifp->if_flags & IFF_ROUTE) {		route.rt_dst = ifp->if_dstaddr;		route.rt_gateway = ifp->if_addr;		route.rt_flags = RTF_HOST|RTF_UP;		(void) rtrequest(SIOCDELRT, &route);		ifp->if_flags &=~ IFF_ROUTE;	}}#endif/* * Line specific close routine. * Detach the tty from the sl unit. * Mimics part of ttyclose(). */slclose(tp)	struct tty *tp;{	register struct sl_softc *sc;	int s;	ttywflush(tp);	tp->t_line = 0;	s = splimp();	sc = (struct sl_softc *)tp->t_sc;	if (sc != NULL) {#ifdef sun		if_rtdelete(&sc->sc_if);#endif		if_down(&sc->sc_if);		rtpurge(&sc->sc_if);		in_reminterface(&sc->sc_if);		sc->sc_if.if_addrlist = NULL;		sc->sc_ttyp = NULL;		tp->t_sc = NULL;		MCLFREE((struct mbuf *)(sc->sc_ep - (SLMAX + BUFOFFSET)));		sc->sc_ep = 0;		sc->sc_mp = 0;		sc->sc_buf = 0;	}	splx(s);}/* * Line specific (tty) ioctl routine. * Provide a way to get the sl unit number. *//* ARGSUSED */sltioctl(tp, cmd, data, flag)	struct tty *tp;	caddr_t data;{	if (cmd == TIOCGETD) {		*(int *)data = ((struct sl_softc *)tp->t_sc)->sc_if.if_unit;		return (0);	}	return (EINVAL);}/* * Queue a packet.  Start transmission if not active. */sloutput(ifp, m, dst)	register struct ifnet *ifp;	register struct mbuf *m;	struct sockaddr *dst;{	register struct sl_softc *sc;	register struct ip *ip;	register struct ifqueue *ifq;	int s;	/*	 * `Cannot happen' (see slioctl).  Someday we will extend	 * the line protocol to support other address families.	 */	if (dst->sa_family != AF_INET) {		printf("sl%d: af%d not supported\n", ifp->if_unit,			dst->sa_family);		m_freem(m);		return (EAFNOSUPPORT);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -