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

📄 if_en.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1992, 1993 *	The Regents of the University of California.  All rights reserved. * * This code is derived from software contributed to Berkeley by * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc. * * 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. * * 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. * * from: $Hdr: if_en.c,v 4.300 91/06/09 06:25:54 root Rel41 $ SONY * *	@(#)if_en.c	8.1 (Berkeley) 6/11/93 */#include "en.h"#include "rawether.h"#include "bpfilter.h"#if NEN > 0/* * Interlan Ethernet Communications Controller interface */#include <sys/types.h>#include <machine/pte.h>#include <sys/param.h>#include <sys/systm.h>#include <sys/mbuf.h>#include <sys/buf.h>#include <sys/protosw.h>#include <sys/socket.h>#include <sys/ioctl.h>#include <sys/errno.h>#include <sys/time.h>#include <sys/cdefs.h>#include <net/if.h>#include <net/netisr.h>#include <net/route.h>#ifdef INET#include <netinet/in.h>#include <netinet/in_systm.h>#include <netinet/in_var.h>#include <netinet/ip.h>#include <netinet/if_ether.h>#endif#include <news3400/if/if_news.h>#include <news3400/if/if_en.h>#ifdef CPU_SINGLE#include <news3400/hbdev/hbvar.h>#define	iop_device	hb_device#define	iop_driver	hb_driver#define	ii_unit		hi_unit#define	ii_intr		hi_intr#define	ii_alive	hi_alive#else#include <news3400/iop/iopvar.h>#endifint	enprobe(), enattach(), enrint(), enxint();struct	mbuf *m_devget();#ifdef CPU_SINGLEstruct	hb_device *eninfo[NEN];struct	hb_driver endriver = { enprobe, 0, enattach, 0, 0, "en", eninfo };#elsestruct	iop_device *eninfo[NEN];struct	iop_driver endriver = { enprobe, 0, enattach, 0, "en", eninfo };#endif#define	ENUNIT(x)	minor(x)int	eninit(),enioctl(),enreset(),enwatch(),enstart();int	endebug = 0;struct ether_addr {	u_char	addr[6];};extern struct ifnet loif;struct en_softc en_softc[NEN];#if NBPFILTER > 0#include <net/bpf.h>#endifenprobe(ii)	struct iop_device *ii;{	return (en_probe(ii));}/* * Interface exists: make available by filling in network interface * record.  System will initialize the interface when it is ready * to accept packets.  A STATUS command is done to get the ethernet * address and other interesting data. */enattach(ii)	register struct iop_device *ii;{	register struct en_softc *es = &en_softc[ii->ii_unit];	register struct ifnet *ifp = &es->es_if;	extern char *ether_sprintf();	en_attach(ii->ii_unit);	printf("en%d: hardware address %s\n",		ii->ii_unit, ether_sprintf((u_char *)es->es_addr));	ifp->if_unit = ii->ii_unit;	ifp->if_name = "en";	ifp->if_mtu = ETHERMTU;	ifp->if_init = eninit;	ifp->if_ioctl = enioctl;	ifp->if_output = ether_output;#ifdef NOTDEF /* KU:XXX if_reset is obsolete */	ifp->if_reset = enreset;#endif	ifp->if_start = enstart;	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;#if NBPFILTER > 0	bpfattach(&es->es_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));#endif	if_attach(ifp);}/* * Reset of interface after IOP reset. */enreset(unit)	int unit;{	register struct iop_device *ii;	if (unit >= NEN || (ii = eninfo[unit]) == 0 || ii->ii_alive == 0)		return;	printf(" en%d", unit);	en_softc[unit].es_if.if_flags &= ~(IFF_RUNNING|IFF_OACTIVE);	en_softc[unit].es_flags &= ~ENF_RUNNING;	eninit(unit);}/* * Initialization of interface; clear recorded pending * operations, and reinitialize IOP usage. */eninit(unit)	int unit;{	register struct en_softc *es = &en_softc[unit];	register struct ifnet *ifp = &es->es_if;	int s;	/* not yet, if address still unknown */	if (ifp->if_addrlist == (struct ifaddr *)0)		return;	if (es->es_flags & ENF_RUNNING)		return;	if ((ifp->if_flags & IFF_RUNNING) == 0) {		if (if_newsinit(&es->es_ifnews,		    sizeof (struct en_rheader), (int)btoc(ETHERMTU)) == 0) { 			printf("en%d: can't initialize\n", unit);			es->es_if.if_flags &= ~IFF_UP;			return;		}		ifp->if_watchdog = enwatch;		es->es_interval = ENWATCHINTERVAL;		ifp->if_timer = es->es_interval;		s = splimp();		en_init(unit);		splx(s);	}	es->es_if.if_flags |= IFF_RUNNING|IFF_NOTRAILERS;	es->es_flags |= ENF_RUNNING;}/* * Start output on interface. * Get another datagram to send off of the interface queue, * and map it to the interface before starting the output. */enstart(ifp)	register struct ifnet *ifp;{        int unit = ifp->if_unit, len;	register struct en_softc *es = &en_softc[unit];	register struct mbuf *m;	int s;	IF_DEQUEUE(&es->es_if.if_snd, m);	if (m == 0)		return(0);#ifdef CPU_SINGLE	es->es_ifnews.ifn_waddr = (caddr_t)get_xmit_buffer(unit);#endif	len = if_wnewsput(&es->es_ifnews, m);	/*	 * Ensure minimum packet length.	 * This makes the safe assumtion that there are no virtual holes	 * after the data.	 * For security, it might be wise to zero out the added bytes,	 * but we're mainly interested in speed at the moment.	 */	if (len - sizeof(struct ether_header) < ETHERMIN)		len = ETHERMIN + sizeof(struct ether_header);	s = splclock();			/* KU:XXX should be gone */	en_start(unit, len);	es->es_if.if_flags |= IFF_OACTIVE;	(void) splx(s);			/* KU:XXX */#if NBPFILTER > 0	/*	 * If bpf is listening on this interface, let it	 * see the packet before we commit it to the wire.	 */	if (es->es_bpf) {#ifdef CPU_SINGLE		bpf_tap(es->es_bpf, es->es_ifnews.ifn_waddr, len);#else		bpf_mtap(es->es_bpf, m);#endif	}#endif /* NBPFILTER > 0 */	return(0);}/* * Transmit done interrupt. */_enxint(unit, error, collision)	int unit;	int error, collision;{	register struct en_softc *es = &en_softc[unit];#ifdef notyet /* KU:XXX */	intrcnt[INTR_ETHER0 + unit]++;#endif	if ((es->es_if.if_flags & IFF_OACTIVE) == 0) {		printf("en%d: stray xmit interrupt\n", unit);		return;	} else {		es->es_if.if_flags &= ~IFF_OACTIVE;		es->es_if.if_opackets++;	}	if (error)		es->es_if.if_oerrors++;	if (collision)		es->es_if.if_collisions++;	enstart(&es->es_if);}/* * Ethernet interface receiver interrupt. * If input error just drop packet. * Otherwise purge input buffered data path and examine  * packet to determine type.  If can't determine length * from type, then have to drop packet.  Othewise decapsulate * packet based on type and pass to type specific higher-level * input routine. */_enrint(unit, len)	int unit;	register int len;{	register struct en_softc *es = &en_softc[unit];	register struct en_rheader *en;    	struct mbuf *m;	int off, resid, s;	int type;	register struct ensw *esp;	extern struct mbuf *if_rnewsget();#if defined(mips) && defined(CPU_SINGLE)	int bxcopy();#endif#ifdef notyet /* KU:XXX */	intrcnt[INTR_ETHER0 + unit]++;#endif	es->es_if.if_ipackets++;	if ((es->es_flags & ENF_RUNNING) == 0)		return;	en = (struct en_rheader *)(es->es_ifnews.ifn_raddr);	if (len < ETHERMIN || len > ETHERMTU) {		es->es_if.if_ierrors++;		return;	}#if NBPFILTER > 0	/*	 * Check if there's a bpf filter listening on this interface.	 * If so, hand off the raw packet to enet.	 */	if (es->es_bpf) {		bpf_tap(es->es_bpf, es->es_ifnews.ifn_raddr,			len + sizeof(struct en_rheader));		/*		 * Note that the interface cannot be in promiscuous mode if		 * there are no bpf listeners.	And if we are in promiscuous		 * mode, we have to check if this packet is really ours.		 *		 * XXX This test does not support multicasts.		 */		 if ((es->es_if.if_flags & IFF_PROMISC)		     && bcmp(en->enr_dhost, es->es_addr,				sizeof(en->enr_dhost)) != 0		     && bcmp(en->enr_dhost, etherbroadcastaddr,				sizeof(en->enr_dhost)) != 0)			return;	}#endif /* NBPFILTER > 0 */	/*	 * Deal with trailer protocol: if type is trailer type	 * get true type from first 16-bit word past data.	 * Remember that type was trailer by setting off.	 */	en->enr_type = ntohs((u_short)en->enr_type);#define	endataaddr(en, off, type)	((type)(((caddr_t)((en)+1)+(off))))	if (en->enr_type >= ETHERTYPE_TRAIL &&

⌨️ 快捷键说明

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