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

📄 hd_input.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) University of British Columbia, 1984 * Copyright (c) 1990, 1993 *	The Regents of the University of California.  All rights reserved. * * This code is derived from software contributed to Berkeley by * the Laboratory for Computation Vision and the Computer Science Department * of the University of British Columbia. * * 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. * *	@(#)hd_input.c	8.1 (Berkeley) 6/10/93 */#include <sys/param.h>#include <sys/systm.h>#include <sys/mbuf.h>#include <sys/domain.h>#include <sys/socket.h>#include <sys/protosw.h>#include <sys/errno.h>#include <sys/time.h>#include <sys/kernel.h>#include <net/if.h>#include <netccitt/hdlc.h>#include <netccitt/hd_var.h>#include <netccitt/x25.h>static frame_reject();static rej_routine();static free_iframes();/* *      HDLC INPUT INTERFACE * *      This routine is called when the HDLC physical device has *      completed reading a frame. */hdintr (){	register struct mbuf *m;	register struct hdcb *hdp;	register struct ifnet *ifp;	register int s;	static struct ifnet *lastifp;	static struct hdcb *lasthdp;	for (;;) {		s = splimp ();		IF_DEQUEUE (&hdintrq, m);		splx (s);		if (m == 0)			break;		if (m->m_len < HDHEADERLN) {			printf ("hdintr: packet too short (len=%d)\n",				m->m_len);			m_freem (m);			continue;		}		if ((m->m_flags & M_PKTHDR) == 0)			panic("hdintr");		ifp = m->m_pkthdr.rcvif;		/*		 * look up the appropriate hdlc control block		 */		if (ifp == lastifp)			hdp = lasthdp;		else {			for (hdp = hdcbhead; hdp; hdp = hdp->hd_next)				if (hdp->hd_ifp == ifp)					break;			if (hdp == 0) {				printf ("hdintr: unknown interface %x\n", ifp);				m_freem (m);				continue;			}			lastifp = ifp;			lasthdp = hdp;		}		/* Process_rxframe returns FALSE if the frame was NOT queued		   for the next higher layers. */		if (process_rxframe (hdp, m) == FALSE)			m_freem (m);	}}process_rxframe (hdp, fbuf)register struct hdcb *hdp;register struct mbuf *fbuf;{	register int queued = FALSE, frametype, pf;	register struct Hdlc_frame *frame;	frame = mtod (fbuf, struct Hdlc_frame *);	pf = ((struct Hdlc_iframe *) frame) -> pf;	hd_trace (hdp, RX, frame);	if (frame -> address != ADDRESS_A && frame -> address != ADDRESS_B)		return (queued);	switch ((frametype = hd_decode (hdp, frame)) + hdp->hd_state) {	case DM + DISC_SENT:	case UA + DISC_SENT:		/*		 * Link now closed.  Leave timer running		 * so hd_timer() can periodically check the		 * status of interface driver flag bit IFF_UP.		 */		hdp->hd_state = DISCONNECTED;		break;	case DM + INIT:	case UA + INIT:		/*		 * This is a non-standard state change needed for DCEs		 * that do dynamic link selection.  We can't go into the		 * usual "SEND DM" state because a DM is a SARM in LAP.		 */		hd_writeinternal (hdp, SABM, POLLOFF);		hdp->hd_state = SABM_SENT;		SET_TIMER (hdp);		break;	case SABM + DM_SENT: 	case SABM + WAIT_SABM: 		hd_writeinternal (hdp, UA, pf);	case UA + SABM_SENT: 	case UA + WAIT_UA: 		KILL_TIMER (hdp);		hd_initvars (hdp);		hdp->hd_state = ABM;		hd_message (hdp, "Link level operational");		/* Notify the packet level - to send RESTART. */		(void) pk_ctlinput (PRC_LINKUP, hdp->hd_pkp);		break;	case SABM + SABM_SENT: 		/* Got a SABM collision. Acknowledge the remote's SABM		   via UA but still wait for UA. */		hd_writeinternal (hdp, UA, pf);		break;	case SABM + ABM: 		/* Request to reset the link from the remote. */		KILL_TIMER (hdp);		hd_message (hdp, "Link reset");#ifdef HDLCDEBUG		hd_dumptrace (hdp);#endif		hd_flush (hdp->hd_ifp);		hd_writeinternal (hdp, UA, pf);		hd_initvars (hdp);		(void) pk_ctlinput (PRC_LINKRESET, hdp->hd_pkp);		hdp->hd_resets++;		break;	case SABM + WAIT_UA: 		hd_writeinternal (hdp, UA, pf);		break;	case DM + ABM: 		hd_message (hdp, "DM received: link down");#ifdef HDLCDEBUG		hd_dumptrace (hdp);#endif		(void) pk_ctlinput (PRC_LINKDOWN, hdp->hd_pkp);		hd_flush (hdp->hd_ifp);	case DM + DM_SENT: 	case DM + WAIT_SABM: 	case DM + WAIT_UA: 		hd_writeinternal (hdp, SABM, pf);		hdp->hd_state = SABM_SENT;		SET_TIMER (hdp);		break;	case DISC + INIT:	case DISC + DM_SENT: 	case DISC + SABM_SENT: 		/* Note: This is a non-standard state change. */		hd_writeinternal (hdp, UA, pf);		hd_writeinternal (hdp, SABM, POLLOFF);		hdp->hd_state = SABM_SENT;		SET_TIMER (hdp);		break;	case DISC + WAIT_UA: 		hd_writeinternal (hdp, DM, pf);		SET_TIMER (hdp);		hdp->hd_state = DM_SENT;		break;	case DISC + ABM: 		hd_message (hdp, "DISC received: link down");		(void) pk_ctlinput (PRC_LINKDOWN, hdp->hd_pkp);	case DISC + WAIT_SABM: 		hd_writeinternal (hdp, UA, pf);		hdp->hd_state = DM_SENT;		SET_TIMER (hdp);		break;	case UA + ABM: 		hd_message (hdp, "UA received: link down");		(void) pk_ctlinput (PRC_LINKDOWN, hdp->hd_pkp);	case UA + WAIT_SABM: 		hd_writeinternal (hdp, DM, pf);		hdp->hd_state = DM_SENT;		SET_TIMER (hdp);		break;	case FRMR + DM_SENT: 		hd_writeinternal (hdp, SABM, pf);		hdp->hd_state = SABM_SENT;		SET_TIMER (hdp);		break;	case FRMR + WAIT_SABM: 		hd_writeinternal (hdp, DM, pf);		hdp->hd_state = DM_SENT;		SET_TIMER (hdp);		break;	case FRMR + ABM: 		hd_message (hdp, "FRMR received: link down");		(void) pk_ctlinput (PRC_LINKDOWN, hdp->hd_pkp);#ifdef HDLCDEBUG		hd_dumptrace (hdp);#endif		hd_flush (hdp->hd_ifp);		hd_writeinternal (hdp, SABM, pf);		hdp->hd_state = WAIT_UA;		SET_TIMER (hdp);		break;	case RR + ABM: 	case RNR + ABM: 	case REJ + ABM: 		process_sframe (hdp, (struct Hdlc_sframe *)frame, frametype);		break;	case IFRAME + ABM: 		queued = process_iframe (hdp, fbuf, (struct Hdlc_iframe *)frame);		break;	case IFRAME + SABM_SENT: 	case RR + SABM_SENT: 	case RNR + SABM_SENT: 	case REJ + SABM_SENT: 		hd_writeinternal (hdp, DM, POLLON);		hdp->hd_state = DM_SENT;		SET_TIMER (hdp);		break;	case IFRAME + WAIT_SABM: 	case RR + WAIT_SABM: 	case RNR + WAIT_SABM: 	case REJ + WAIT_SABM: 		hd_writeinternal (hdp, FRMR, POLLOFF);		SET_TIMER (hdp);		break;	case ILLEGAL + SABM_SENT: 		hdp->hd_unknown++;		hd_writeinternal (hdp, DM, POLLOFF);		hdp->hd_state = DM_SENT;		SET_TIMER (hdp);		break;	case ILLEGAL + ABM: 		hd_message (hdp, "Unknown frame received: link down");		(void) pk_ctlinput (PRC_LINKDOWN, hdp->hd_pkp);	case ILLEGAL + WAIT_SABM:		hdp->hd_unknown++;#ifdef HDLCDEBUG		hd_dumptrace (hdp);#endif		hd_writeinternal (hdp, FRMR, POLLOFF);		hdp->hd_state = WAIT_SABM;		SET_TIMER (hdp);		break;	}	return (queued);}process_iframe (hdp, fbuf, frame)register struct hdcb *hdp;struct mbuf *fbuf;register struct Hdlc_iframe *frame;{	register int    nr = frame -> nr,	                ns = frame -> ns,	                pf = frame -> pf;	register int    queued = FALSE;	/* 	 *  Validate the iframe's N(R) value. It's N(R) value must be in	 *   sync with our V(S) value and our "last received nr".	 */	if (valid_nr (hdp, nr, FALSE) == FALSE) {		frame_reject (hdp, Z, frame);		return (queued);	}

⌨️ 快捷键说明

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