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

📄 if_en.c

📁 open bsd vax module -if function
💻 C
📖 第 1 页 / 共 2 页
字号:
	 * backed off 16 times, and give up.	 */	if (es->es_mask == 0) {		printf("en%d: send error\n", unit);		enxint(unit);		return;	}	/*	 * Another backoff.  Restart with delay based on n low bits	 * of the interval timer.	 */	es->es_mask <<= 1;	es->es_delay = mfpr(ICR) &~ es->es_mask;	enstart(unit);}#ifdef notdefstruct	sockproto enproto = { AF_ETHERLINK };struct	sockaddr_en endst = { sizeof(endst), AF_ETHERLINK };struct	sockaddr_en ensrc = { sizeof(ensrc), AF_ETHERLINK };#endif/* * 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)	int unit;{	register struct en_softc *es = &en_softc[unit];	struct endevice *addr = (struct endevice *)eninfo[unit]->ui_addr;	register struct en_header *en;    	struct mbuf *m;	int len; short resid;	register struct ifqueue *inq;	int off, s;	es->es_if.if_ipackets++;	/*	 * Purge BDP; drop if input error indicated.	 */	if (es->es_ifuba.ifu_flags & UBA_NEEDBDP)		UBAPURGE(es->es_ifuba.ifu_uba, es->es_ifuba.ifu_r.ifrw_bdp);	if (addr->en_istat&EN_IERROR) {		es->es_if.if_ierrors++;		goto setup;	}	/*	 * Calculate input data length.	 * Get pointer to ethernet header (in input buffer).	 * Deal with trailer protocol: if type is PUP trailer	 * get true type from first 16-bit word past data.	 * Remember that type was trailer by setting off.	 */	resid = addr->en_iwc;	if (resid)		resid |= 0176000;	len = (((sizeof (struct en_header) + ENMRU) >> 1) + resid) << 1;	len -= sizeof (struct en_header);	if (len > ENMRU)		goto setup;			/* sanity */	en = (struct en_header *)(es->es_ifuba.ifu_r.ifrw_addr);	en->en_type = ntohs(en->en_type);#define	endataaddr(en, off, type)	((type)(((caddr_t)((en)+1)+(off))))	if (en->en_type >= ENTYPE_TRAIL &&	    en->en_type < ENTYPE_TRAIL+ENTYPE_NTRAILER) {		off = (en->en_type - ENTYPE_TRAIL) * 512;		if (off > ENMTU)			goto setup;		/* sanity */		en->en_type = ntohs(*endataaddr(en, off, u_short *));		resid = ntohs(*(endataaddr(en, off+2, u_short *)));		if (off + resid > len)			goto setup;		/* sanity */		len = off + resid;	} else		off = 0;	if (len == 0)		goto setup;#ifdef ENF_SWABIPS	if (es->es_if.if_flags & ENF_SWABIPS && en->en_type == ENTYPE_IP)		enswab((caddr_t)(en + 1), (caddr_t)(en + 1), len);#endif	/*	 * Pull packet off interface.  Off is nonzero if packet	 * has trailing header; if_rubaget will then force this header	 * information to be at the front, but we still have to drop	 * the type and length which are at the front of any trailer data.	 */	m = if_rubaget(&es->es_ifuba, len, off, &es->es_if);	if (m == 0)		goto setup;	switch (en->en_type) {#ifdef INET	case ENTYPE_IP:		schednetisr(NETISR_IP);		inq = &ipintrq;		break;#endif#ifdef PUP	case ENTYPE_PUP:		rpup_input(m);		goto setup;#endif#ifdef NS	case ETHERTYPE_NS:		if (es->es_nsactive) {			schednetisr(NETISR_NS);			inq = &nsintrq;		} else {			m_freem(m);			goto setup;		}		break;#endif	default:#ifdef notdef		enproto.sp_protocol = en->en_type;		endst.sen_host = en->en_dhost;		endst.sen_net = ensrc.sen_net = es->es_if.if_net;		ensrc.sen_host = en->en_shost;		raw_input(m, &enproto,		    (struct sockaddr *)&ensrc, (struct sockaddr *)&endst);#else		m_freem(m);#endif		goto setup;	}	s = splimp();	if (IF_QFULL(inq)) {		IF_DROP(inq);		m_freem(m);	} else		IF_ENQUEUE(inq, m);	splx(s);setup:	/*	 * Reset for next packet.	 */	addr->en_iba = es->es_ifuba.ifu_r.ifrw_info;	addr->en_iwc = -(sizeof (struct en_header) + ENMRU) >> 1;	addr->en_istat = EN_IEN|EN_GO;}/* * Ethernet output routine. * Encapsulate a packet of type family for the local net. * Use trailer local net encapsulation if enough data in first * packet leaves a multiple of 512 bytes of data in remainder. */oldenoutput(ifp, m0, dst)	struct ifnet *ifp;	struct mbuf *m0;	struct sockaddr *dst;{	int type, dest, s, error;	register struct mbuf *m = m0;	register struct en_header *en;	register int off;	if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) {		error = ENETDOWN;		goto bad;	}	switch (dst->sa_family) {#ifdef INET	case AF_INET:		{		struct in_addr in;		in = ((struct sockaddr_in *)dst)->sin_addr;		if (in_broadcast(in))			dest = EN_BROADCAST;		else			dest = in_lnaof(in);		}		if (dest >= 0x100) {			error = EPERM;		/* ??? */			goto bad;		}		off = m->m_pkthdr.len - m->m_len;		/* need per host negotiation */		if ((ifp->if_flags & IFF_NOTRAILERS) == 0)		if (off > 0 && (off & 0x1ff) == 0 &&		    (m->m_flags & M_EXT) == 0 &&		    m->m_data >= m->m_pktdat + 2 * sizeof (u_short)) {			type = ENTYPE_TRAIL + (off>>9);			m->m_data -= 2 * sizeof (u_short);			m->m_len += 2 * sizeof (u_short);			*mtod(m, u_short *) = htons((u_short)ENTYPE_IP);			*(mtod(m, u_short *) + 1) = ntohs((u_short)m->m_len);			goto gottrailertype;		}		type = ENTYPE_IP;		off = 0;		goto gottype;#endif#ifdef NS	case AF_NS:	{		u_char *up;		type = ETHERTYPE_NS;		up = ((struct sockaddr_ns *)dst)->sns_addr.x_host.c_host;		if (*up & 1)			dest = EN_BROADCAST;		else			dest = up[5];		off = 0;		goto gottype;	}#endif#ifdef PUP	case AF_PUP:		dest = ((struct sockaddr_pup *)dst)->spup_host;		type = ENTYPE_PUP;		off = 0;		goto gottype;#endif#ifdef notdef	case AF_ETHERLINK:		goto gotheader;#endif	default:		printf("en%d: can't handle af%d\n", ifp->if_unit,			dst->sa_family);		error = EAFNOSUPPORT;		goto bad;	}gottrailertype:	/*	 * Packet to be sent as trailer: move first packet	 * (control information) to end of chain.	 */	while (m->m_next)		m = m->m_next;	m->m_next = m0;	m = m0->m_next;	m0->m_next = 0;	m0 = m;gottype:	/*	 * Add local net header.  If no space in first mbuf,	 * allocate another.	 */	M_PREPEND(m, sizeof (struct en_header), M_DONTWAIT);	if (m == NULL)		return (ENOBUFS);	en = mtod(m, struct en_header *);	/* add en_shost later */	en->en_dhost = dest;	en->en_type = htons((u_short)type);#ifdef notdefgotheader:#endif	/*	 * Queue message on interface, and start output if interface	 * not yet active.	 */	s = splimp();	if (IF_QFULL(&ifp->if_snd)) {		IF_DROP(&ifp->if_snd);		error = ENOBUFS;		goto qfull;	}	IF_ENQUEUE(&ifp->if_snd, m);	if (en_softc[ifp->if_unit].es_oactive == 0)		enstart(ifp->if_unit);	splx(s);	return (0);qfull:	m0 = m;	splx(s);bad:	m_freem(m0);	return (error);}/* * Process an ioctl request. */enioctl(ifp, cmd, data)	register struct ifnet *ifp;	int cmd;	caddr_t data;{	register struct en_softc *es = ((struct en_softc *)ifp);	struct ifaddr *ifa = (struct ifaddr *) data;	int s = splimp(), error = 0;	struct endevice *enaddr;	switch (cmd) {	case SIOCSIFADDR:		enaddr = (struct endevice *)eninfo[ifp->if_unit]->ui_addr;		es->es_host = (~enaddr->en_addr) & 0xff;		/*		 * Attempt to check agreement of protocol address		 * and board address.		 */		switch (ifa->ifa_addr->sa_family) {		case AF_INET:			if (in_lnaof(IA_SIN(ifa)->sin_addr) != es->es_host)				return (EADDRNOTAVAIL);			break;#ifdef NS		case AF_NS:			if (IA_SNS(ifa)->sns_addr.x_host.c_host[5]							!= es->es_host)				return (EADDRNOTAVAIL);			es->es_nsactive = 1;			break;#endif		}		ifp->if_flags |= IFF_UP;		if ((ifp->if_flags & IFF_RUNNING) == 0)			eninit(ifp->if_unit);		break;	default:		error = EINVAL;		break;	}	splx(s);	return (error);}#ifdef ENF_SWABIPS/* * Swab bytes * Jeffrey Mogul, Stanford */enswab(from, to, n)	register unsigned char *from, *to;	register int n;{	register unsigned long temp;	if ((n <= 0) || (n > 0xFFFF)) {		printf("enswab: bad len %d\n", n);		return;	}		n >>= 1; n++;#define	STEP	{temp = *from++;*to++ = *from++;*to++ = temp;}	/* round to multiple of 8 */	while ((--n) & 07)		STEP;	n >>= 3;	while (--n >= 0) {		STEP; STEP; STEP; STEP;		STEP; STEP; STEP; STEP;	}}#endif#endif

⌨️ 快捷键说明

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