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

📄 if_imp.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef lintstatic	char	*sccsid = "@(#)if_imp.c	4.1.1.1	(ULTRIX)	1/15/88";#endif lint/************************************************************************ *									* *			Copyright (c) 1985 by				* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//************************************************************************ *			Modification History				* *									* *	Larry Cohen  -	09/16/85					* * 		Add 43bsd alpha tape changes for subnet routing		* *									* ************************************************************************//* * Copyright (c) 1982 Regents of the University of California. * All rights reserved.  The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * *	@(#)if_imp.c	6.6 (Berkeley) 6/8/85 */#include "imp.h"#if NIMP > 0/* * ARPANET IMP interface driver. * * The IMP-host protocol is handled here, leaving * hardware specifics to the lower level interface driver. */#include "../machine/pte.h"#include "../h/param.h"#include "../h/systm.h"#include "../h/mbuf.h"#include "../h/buf.h"#include "../h/protosw.h"#include "../h/socket.h"#include "../h/vmmac.h"#include "../h/time.h"#include "../h/kernel.h"#include "../h/errno.h"#include "../h/ioctl.h"#include "../machine/cpu.h"#ifdef vax#include "../machine/mtpr.h"#include "../io/uba/ubareg.h"#include "../io/uba/ubavar.h"#endif vax#include "../net/if.h"#include "../net/route.h"#include "../net/netisr.h"#include "../netinet/in.h"#include "../netinet/in_systm.h"#include "../netinet/in_var.h"#include "../netinet/ip.h"#include "../netinet/ip_var.h"/* define IMPLEADERS here to get leader printing code */#include "../netimp/if_imp.h"#include "../netimp/if_imphost.h"/* * IMP software status per interface. * (partially shared with the hardware specific module) * * Each interface is referenced by a network interface structure, * imp_if, which the routing code uses to locate the interface. * This structure contains the output queue for the interface, its * address, ...  IMP specific structures used in connecting the * IMP software modules to the hardware specific interface routines * are stored here.  The common structures are made visible to the * interface driver by passing a pointer to the hardware routine * at "attach" time. * * NOTE: imp_if and imp_cb are assumed adjacent in hardware code. */struct imp_softc {	struct	ifnet imp_if;		/* network visible interface */	struct	impcb imp_cb;		/* hooks to hardware module */	u_char	imp_state;		/* current state of IMP */	char	imp_dropcnt;		/* used during initialization */} imp_softc[NIMP];/* * Messages from IMP regarding why * it's going down. */static char *impmessage[] = {	"in 30 seconds",	"for hardware PM",	"to reload software",	"for emergency reset"};#define HOSTDEADTIMER	10		/* How long to wait when down */int	impdown(), impinit(), impioctl(), impoutput();/* * IMP attach routine.  Called from hardware device attach routine * at configuration time with a pointer to the UNIBUS device structure. * Sets up local state and returns pointer to base of ifnet+impcb * structures.  This is then used by the device's attach routine * set up its back pointers.  */impattach(ui, reset)	struct uba_device *ui;	int (*reset)();{	struct imp_softc *sc = &imp_softc[ui->ui_unit];	register struct ifnet *ifp = &sc->imp_if;	/* UNIT COULD BE AMBIGUOUS */	ifp->if_unit = ui->ui_unit;	ifp->if_name = "imp";	ifp->if_mtu = IMPMTU - sizeof(struct imp_leader);	ifp->if_reset = reset;	ifp->if_init = impinit;	ifp->if_ioctl = impioctl;	ifp->if_output = impoutput;	/* reset is handled at the hardware level */	if_attach(ifp);	return ((int)&sc->imp_if);}/* * IMP initialization routine: call hardware module to * setup UNIBUS resources, init state and get ready for * NOOPs the IMP should send us, and that we want to drop. */impinit(unit)	int unit;{	int s = splimp();	register struct imp_softc *sc = &imp_softc[unit];	if (sc->imp_if.if_addrlist == 0)		return;	if ((*sc->imp_cb.ic_init)(unit) == 0) {		sc->imp_state = IMPS_DOWN;		sc->imp_if.if_flags &= ~IFF_UP;		splx(s);		return;	}	sc->imp_state = IMPS_INIT;	impnoops(sc);	splx(s);}struct sockproto impproto = { PF_IMPLINK };struct sockaddr_in impdst = { AF_IMPLINK };struct sockaddr_in impsrc = { AF_IMPLINK };#ifdef IMPLEADERSint	impprintfs = 0;#endif/* * ARPAnet 1822 input routine. * Called from hardware input interrupt routine to handle 1822 * IMP-host messages.  Type 0 messages (non-control) are * passed to higher level protocol processors on the basis * of link number.  Other type messages (control) are handled here. */impinput(unit, m)	int unit;	register struct mbuf *m;{	register struct imp_leader *ip;	register struct imp_softc *sc = &imp_softc[unit];	register struct host *hp;	register struct ifqueue *inq;	struct control_leader *cp;	struct in_addr addr;	struct mbuf *next;	struct sockaddr_in *sin;	/* verify leader length. */	if (m->m_len < sizeof(struct control_leader) &&	    (m = m_pullup(m, sizeof(struct control_leader))) == 0)		return;	cp = mtod(m, struct control_leader *);	if (cp->dl_mtype == IMPTYPE_DATA)		if (m->m_len < sizeof(struct imp_leader) &&		    (m = m_pullup(m, sizeof(struct imp_leader))) == 0)			return;	ip = mtod(m, struct imp_leader *);#ifdef IMPLEADERS	if (impprintfs)		printleader("impinput", ip);#endif	/* check leader type */	if (ip->il_format != IMP_NFF) {		sc->imp_if.if_collisions++;	/* XXX */		goto drop;	}	if (ip->il_mtype != IMPTYPE_DATA) {		/* If not data packet, build IP addr from leader (BRL) */		imp_leader_to_addr(&addr, ip, &sc->imp_if);	}	switch (ip->il_mtype) {	case IMPTYPE_DATA:		break;	/*	 * IMP leader error.  Reset the IMP and discard the packet.	 */	case IMPTYPE_BADLEADER:		/*		 * According to 1822 document, this message		 * will be generated in response to the		 * first noop sent to the IMP after		 * the host resets the IMP interface.		 */		if (sc->imp_state != IMPS_INIT) {			impmsg(sc, "leader error");			hostreset(((struct in_ifaddr *)&sc->imp_if.if_addrlist)->ia_net);			impnoops(sc);		}		goto drop;	/*	 * IMP going down.  Print message, and if not immediate,	 * set off a timer to insure things will be reset at the	 * appropriate time.	 */	case IMPTYPE_DOWN:		if (sc->imp_state < IMPS_INIT)			goto drop;		if ((ip->il_link & IMP_DMASK) == 0) {			sc->imp_state = IMPS_GOINGDOWN;			timeout(impdown, (caddr_t)sc, 30 * hz);		}		impmsg(sc, "going down %s",			(u_int)impmessage[ip->il_link&IMP_DMASK]);		goto drop;	/*	 * A NOP usually seen during the initialization sequence.	 * Compare the local address with that in the message.	 * Reset the local address notion if it doesn't match.	 */	case IMPTYPE_NOOP:		if (sc->imp_state == IMPS_DOWN) {			sc->imp_state = IMPS_INIT;			sc->imp_dropcnt = IMP_DROPCNT;		}		if (sc->imp_state == IMPS_INIT && --sc->imp_dropcnt > 0)			goto drop;		sin = (struct sockaddr_in *)&sc->imp_if.if_addrlist->ifa_addr;		if (ip->il_imp != 0) {	/* BRL */			struct in_addr leader_addr;			imp_leader_to_addr(&leader_addr, ip, &sc->imp_if);			if (sin->sin_addr.s_addr != leader_addr.s_addr) {				impmsg(sc, "address reset to x%x (%d/%d)",					htonl(leader_addr.s_addr),					(u_int)ip->il_host,					htons(ip->il_imp));				sin->sin_addr.s_addr = leader_addr.s_addr;			}		}		sc->imp_state = IMPS_UP;		sc->imp_if.if_flags |= IFF_UP;		goto drop;	/*	 * RFNM or INCOMPLETE message, send next	 * message on the q.  We could pass incomplete's	 * up to the next level, but this currently isn't	 * needed.	 */	case IMPTYPE_RFNM:	case IMPTYPE_INCOMPLETE:		if (hp = hostlookup(addr)) {			if (hp->h_rfnm == 0)				hp->h_flags &= ~HF_INUSE;			else if (next = hostdeque(hp))				(void) impsnd(&sc->imp_if, next);		}		goto drop;	/*	 * Host or IMP can't be reached.  Flush any packets	 * awaiting transmission and release the host structure.	 */	case IMPTYPE_HOSTDEAD:	case IMPTYPE_HOSTUNREACH:		impnotify((int)ip->il_mtype, (struct control_leader *)ip,		    hostlookup(addr), &sc->imp_if);		goto rawlinkin;	/*	 * Error in data.  Clear RFNM status for this host and send	 * noops to the IMP to clear the interface.	 */	case IMPTYPE_BADDATA:		impmsg(sc, "data error");		if (hp = hostlookup(addr))			hp->h_rfnm = 0;		impnoops(sc);		goto drop;	/*	 * Interface reset.	 */	case IMPTYPE_RESET:		impmsg(sc, "interface reset");		/* clear RFNM counts */		hostreset(((struct in_ifaddr *)&sc->imp_if.if_addrlist)->ia_net);		impnoops(sc);		goto drop;	default:		sc->imp_if.if_collisions++;		/* XXX */		goto drop;	}	/*	 * Data for a protocol.  Dispatch to the appropriate	 * protocol routine (running at software interrupt).	 * If this isn't a raw interface, advance pointer	 * into mbuf past leader.	 */	switch (ip->il_link) {#ifdef INET	case IMPLINK_IP:		m->m_len -= sizeof(struct imp_leader);		m->m_off += sizeof(struct imp_leader);		schednetisr(NETISR_IP);		inq = &ipintrq;		break;#endif	default:	rawlinkin:		impproto.sp_protocol = ip->il_link;		sin = (struct sockaddr_in *)&sc->imp_if.if_addrlist->ifa_addr;		impdst.sin_addr = sin->sin_addr;		imp_leader_to_addr(&impsrc.sin_addr, ip, &sc->imp_if);		raw_input(m, &impproto, (struct sockaddr *)&impsrc,		  (struct sockaddr *)&impdst);		return;	}	if (IF_QFULL(inq)) {

⌨️ 快捷键说明

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