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

📄 llc_output.c

📁 早期freebsd实现
💻 C
字号:
/*  * Copyright (C) Dirk Husemann, Computer Science Department IV,  * 		 University of Erlangen-Nuremberg, Germany, 1990, 1991, 1992 * Copyright (c) 1992, 1993 *	The Regents of the University of California.  All rights reserved. *  * This code is derived from software contributed to Berkeley by * Dirk Husemann and the Computer Science Department (IV) of * the University of Erlangen-Nuremberg, Germany. * * 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. * *	@(#)llc_output.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 <net/if_dl.h>#include <net/if_llc.h>#include <net/route.h>#include <netccitt/dll.h>#include <netccitt/llc_var.h>/* * llc_output() --- called by an upper layer (network layer) entity whenever *                  there is an INFO frame to be transmitted. We enqueue the *                  info frame and call llc_start() to do the actual sending. */llc_output(struct llc_linkcb *linkp, struct mbuf *m){	register int i;	i = splimp();	LLC_ENQUEUE(linkp, m);	llc_start(linkp);	splx(i);}/* * llc_start() --- We try to subsequently dequeue all the frames available and *                 send them out. */voidllc_start(struct llc_linkcb *linkp){	register int i;	register struct mbuf *m;	int action;	while ((LLC_STATEEQ(linkp, NORMAL) || LLC_STATEEQ(linkp, BUSY) ||		LLC_STATEEQ(linkp, REJECT)) && 	       (linkp->llcl_slotsfree > 0) && 	       (LLC_GETFLAG(linkp, REMOTE_BUSY) == 0)) {		LLC_DEQUEUE(linkp, m);		if (m == NULL)			break;		LLC_SETFRAME(linkp, m);		(void)llc_statehandler(linkp, (struct llc *) 0, NL_DATA_REQUEST, 				       0, 0);	}}/* * llc_send() --- Handles single frames. If dealing with INFO frames we need to *                prepend the LLC header, otherwise we just allocate an mbuf. *                In both cases the actual send is done by llc_rawsend(). */llc_send(struct llc_linkcb *linkp, int frame_kind, int cmdrsp, int pollfinal){	register struct mbuf *m = (struct mbuf *)0;	register struct llc *frame;	if (frame_kind == LLCFT_INFO)		m = linkp->llcl_output_buffers[llc_seq2slot(linkp,							    linkp->llcl_vs)];	LLC_GETHDR(frame, m);	/* pass it on to llc_rawsend() */	llc_rawsend(linkp, m, frame, frame_kind, linkp->llcl_vs, cmdrsp, pollfinal);	if (frame_kind == LLCFT_INFO)		LLC_INC(linkp->llcl_vs);	return 0;}/*  * llc_resend() --- llc_resend() retransmits all unacknowledged INFO frames. */llc_resend(struct llc_linkcb *linkp, int cmdrsp, int pollfinal){	register struct llc *frame;	register struct mbuf *m;	register int seq, slot;	if (linkp->llcl_slotsfree < linkp->llcl_window)		/* assert lock between nr_received & V(S) */		if (linkp->llcl_nr_received != linkp->llcl_vs)			panic("llc: V(S) != N(R) received\n");		for (slot = llc_seq2slot(linkp, linkp->llcl_vs);		     slot != linkp->llcl_freeslot; 		     LLC_INC(linkp->llcl_vs), 		     slot = llc_seq2slot(linkp, linkp->llcl_vs)) {			m = linkp->llcl_output_buffers[slot];			LLC_GETHDR(frame, m);			llc_rawsend(linkp, m, frame, LLCFT_INFO, linkp->llcl_vs, 				    cmdrsp, pollfinal);			pollfinal = 0;		}		return 0;}/* * llc_rawsend() --- constructs an LLC frame and sends it out via the *                   associated interface of the link control block. * * We need to make sure that outgoing frames have the correct length, * in particular the 4 byte ones (RR, RNR, REJ) as LLC_GETHDR() will * set the mbuf len to 3 as default len for non INFO frames ... * * Frame kind             Length (w/o MAC header, {D,S}SAP incl.) * -------------------------------------------------------------- * DISC, SABME, UA, DM    3 bytes  ({D,S}SAP + CONTROL) * RR, RNR, REJ           4 bytes  ({D,S}SAP + CONTROL0 + CONTROL1) * XID                    6 bytes  ({D,S}SAP + CONTROL0 + FI,CLASS,WINDOW) * FRMR                   7 bytes  ({D,S}SAP + CONTROL0 + REJ CONTROL,V(S),V(R),CAUSE) * INFO                   4 -- MTU * UI, TEST               3 -- MTU * */#define LLC_SETLEN(m, l) (m)->m_pkthdr.len = (m)->m_len = (l)llc_rawsend(struct llc_linkcb *linkp, struct mbuf *m, struct llc *frame,	    int frame_kind, int vs, int cmdrsp, int pollfinal){	register short adjust = LLC_UFRAMELEN;	struct ifnet *ifp;	switch (frame_kind) {	/* supervisory and information frames */	case LLCFT_INFO:		frame->llc_control = LLC_INFO;		LLCSBITS(frame->llc_control, i_ns, vs);		LLCSBITS(frame->llc_control_ext, i_nr, linkp->llcl_vr);		adjust = LLC_ISFRAMELEN;		break;	case LLCFT_RR:		frame->llc_control = LLC_RR;		LLC_SETLEN(m, LLC_ISFRAMELEN);		LLCSBITS(frame->llc_control_ext, s_nr, linkp->llcl_vr);		adjust = LLC_ISFRAMELEN;		break;	case LLCFT_RNR:		frame->llc_control = LLC_RNR;		LLC_SETLEN(m, LLC_ISFRAMELEN);		LLCSBITS(frame->llc_control_ext, s_nr, linkp->llcl_vr);		adjust = LLC_ISFRAMELEN;		break;	case LLCFT_REJ:		frame->llc_control = LLC_REJ;		LLC_SETLEN(m, LLC_ISFRAMELEN);		LLCSBITS(frame->llc_control_ext, s_nr, linkp->llcl_vr);		adjust = LLC_ISFRAMELEN;		break;	/* unnumbered frames */	case LLCFT_DM:		frame->llc_control = LLC_DM;		break;	case LLCFT_SABME:		frame->llc_control = LLC_SABME;		break;	case LLCFT_DISC:		frame->llc_control = LLC_DISC;		break;	case LLCFT_UA:		frame->llc_control = LLC_UA;		break;	case LLCFT_UI:		frame->llc_control = LLC_UI;		break;	case LLCFT_FRMR:		frame->llc_control = LLC_FRMR;		/* get more space --- FRMR frame are longer then usual */		LLC_SETLEN(m, LLC_FRMRLEN);		bcopy((caddr_t) &linkp->llcl_frmrinfo, 		      (caddr_t) &frame->llc_frmrinfo,		      sizeof(struct frmrinfo));		break;	default:		/*		 * We don't send {XID, TEST} frames		 */		if (m)			m_freem(m);		return;	} 	/* 	 * Fill in DSAP/SSAP	 */	frame->llc_dsap = frame->llc_ssap = LLSAPADDR(&linkp->llcl_addr);	frame->llc_ssap |= cmdrsp;	/*	 * Check for delayed action pending. ISO 8802-2, 7.9.2 (5)	 * and ISO 8802-2, 7.9.2.3 (32), (34), (36) pertain to this	 * piece of code --- hopefully we got it right here (i.e.	 * in the spirit of (32), (34), and (36) ...	 */	switch (frame_kind) {	case LLCFT_RR:	case LLCFT_RNR:	case LLCFT_REJ:	case LLCFT_INFO:		switch (LLC_GETFLAG(linkp, DACTION)) {		case LLC_DACKCMD:		case LLC_DACKRSP:			LLC_STOPTIMER(linkp, DACTION);			break;		case LLC_DACKCMDPOLL:			if (cmdrsp == LLC_CMD) {				pollfinal = 1;				LLC_STOPTIMER(linkp, DACTION);			}			break;		case LLC_DACKRSPFINAL:			if (cmdrsp == LLC_RSP) {				pollfinal = 1;				LLC_STOPTIMER(linkp, DACTION);			}			break;		}		break;	}	 	if (adjust == LLC_UFRAMELEN)		LLCSBITS(frame->llc_control, u_pf, pollfinal);	else LLCSBITS(frame->llc_control_ext, s_pf, pollfinal);	/*	 * Get interface to send frame onto	 */	ifp = linkp->llcl_if;	if (frame_kind == LLCFT_INFO) {		/* 		 * send out a copy of the frame, retain the		 * original		 */		(*ifp->if_output)(ifp, m_copy(m, 0, (int)M_COPYALL),				  rt_key(linkp->llcl_nlrt),				  linkp->llcl_nlrt);		/*		 * Account for the LLC header and let it ``disappear''		 * as the raw info frame payload is what we hold in		 * the output_buffers of the link.		 */		m_adj(m, LLC_ISFRAMELEN);	} else (*ifp->if_output)(ifp, m, 				 rt_key(linkp->llcl_nlrt),				 linkp->llcl_nlrt);}

⌨️ 快捷键说明

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