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

📄 dli_subr.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef	lintstatic char *sccsid = "@(#)dli_subr.c	4.4	(DECnet-ULTRIX)	4/30/91";#endif/* * Program dli_subr.c,  Module DLI  * * Copyright (C) 1985, 1988 by * Digital Equipment Corporation, Maynard, Mass. * * 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. * * 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. * * * Networks & Communications Software Engineering * * IDENT HISTORY: * * 1.00 22-May-1986 *      DECnet-ULTRIX   V2.0 * * 2.01 18-Mar-1988 *      DECnet-ULTRIX   V2.4 *		- Allowed use of reserved bit in individual and group SAPs * *	29-Apr-1991	Matt Thomas *	staticly allocate m_ar array.  Fix gsap to seach all 128 isaps. */#include "../../h/param.h"#include "../../h/systm.h"#include "../../h/mbuf.h"#include "../../h/socket.h"#include "../../h/socketvar.h"#include "../../h/protosw.h"#include "../../h/errno.h"#include "../../h/smp_lock.h"#include "../../h/cpudata.h"#include "../../h/user.h"#include "../../h/buf.h"#include "../../h/conf.h"#include "../../h/proc.h"#include "../../net/net/if.h"#include "../../net/net/if_to_proto.h"#include "../../net/netinet/in.h"#include "../../net/netinet/if_ether.h"#include "../../net/netdnet/dli_var.h"extern struct lock_t lk_dli;extern struct if_isapt if_isapt[];extern struct protosw *iftype_to_proto(), *iffamily_to_proto();extern int xti_debug;u_int dlidebug = 0;#define printd if(dlidebug)printf/* * initialize the system data structure * for 802.3 support. * * Note:  Since this is part of DLI init at boot time, *	  all necessary locks taken out before this *	  routine is called. */osi_802init(ifp)struct ifnet *ifp;{	static int k = 0;	if(k >= MAX_BROADCSTDEV)	{		return(-1);	}	bzero(&if_isapt[k], sizeof(struct if_isapt));	if_isapt[k++].ifp = ifp;	return(NULL);}/* * enable an isap in the system wide table * * Note: DLI line table entry and socke locks *	 taken out before this routine called. */osi_ena_802isap(ifp, so, socket)struct ifnet *ifp;struct sockaddr_802 *so;struct socket *socket;{	int i, n, byte, error;	u_char bit;	if((so->eh_802.ssap & VSAP) || (so->eh_802.ssap >= 255) )		return(EINVAL);	n = so->eh_802.ssap>>VSAP;    /* throw out low bit */	byte = n>>3;               /* byte in table = sap / 8 */	bit = 1<<(n%8);            /* bit to set/clear = sap mod 8 */	smp_lock(&lk_dli, LK_RETRY);	for(i = 0; i < MAX_BROADCSTDEV; i++)	{		if(if_isapt[i].ifp != ifp)			continue;		if(if_isapt[i].so[n] != 0)		{			smp_unlock(&lk_dli);			return(EADDRINUSE);		}		if(so->svc == TYPE1)  			if_isapt[i].svc[byte] |= bit;       /* set class 1 svc */		else			if_isapt[i].svc[byte] &= ~bit;      /* clear for user svc */		if_isapt[i].so[n] = socket;		smp_unlock(&lk_dli);		return(NULL);	}	smp_unlock(&lk_dli);	return(ENOTFND);}/* * disable an isap in the system wide table * and any gsaps that this isap has enabled * * Note: DLI line table entry and socke locks *	 taken out before this routine called. */osi_dis_802isap(ifp, sap, sop)struct ifnet *ifp;u_char sap;struct socket *sop;{	int error, j, i, byte, bit, vsap;	if( (sap & VSAP) || (sap >= 255) )		return(EINVAL);	vsap = sap >> VSAP;	byte = vsap/8;	bit = 1 << vsap%8;	smp_lock(&lk_dli, LK_RETRY);	for(i = 0; i < MAX_BROADCSTDEV; i++)	{		if(if_isapt[i].ifp != ifp)			continue;		if(if_isapt[i].so[vsap] == 0)		{			smp_unlock(&lk_dli);			return(EINVAL);		}		if(if_isapt[i].so[vsap] != sop)		{			smp_unlock(&lk_dli);			return(EINVAL);		}		if_isapt[i].so[vsap] = NULL;		/* look for and disable any gsaps this isap has enabled */		for(j = 0; j < NISAPS; j++)              		{			if(if_isapt[i].gsap[j][byte] & bit)				if(error = osi_dis_802gsap(ifp, ((j<<VSAP)|1), sap))				{					smp_unlock(&lk_dli);					return(error);				}		}		smp_unlock(&lk_dli);		return(NULL);	}	smp_unlock(&lk_dli);	return(ENOTFND);}/* * enable gsap in the system wide table * * Note: DLI line table entry and socket locks *	 taken out before this routine called. */osi_ena_802gsap(ifp, gsap, sap)struct ifnet *ifp;int gsap, sap;{	int i, byte, bit;	if( (sap >= 255) || (sap & VSAP))		return(EINVAL);	if( (gsap <= NULL) || !(gsap & VSAP) || (gsap > 255) )	    return(EINVAL);	byte = (sap >> VSAP) / 8; 	bit = (sap >> VSAP) % 8;	smp_lock(&lk_dli, LK_RETRY);	for(i = 0; i < MAX_BROADCSTDEV; i++)	{		if(if_isapt[i].ifp != ifp)			continue;		if_isapt[i].gsap[gsap>>VSAP][byte] |= 1 << bit;		smp_unlock(&lk_dli);		return(NULL);	}	smp_unlock(&lk_dli);	return(ENOTFND);}/* * disable gsap in system wide table * * Note: DLI line table entry and socke locks *	 taken out before this routine called. */osi_dis_802gsap(ifp, gsap, sap)struct ifnet *ifp;int gsap, sap;{	int i, byte, bit;	u_char lk_dli_asserted_locally = 0;	if( (sap >= 255) || (sap & VSAP))		return(EINVAL);	if( (gsap <= NULL) || !(gsap & 1) || (gsap > 255) )	    return(EINVAL);	byte = (sap >> VSAP) / 8;	bit = (sap >> VSAP) % 8;	if ( smp_owner(&lk_dli) == LK_FALSE )	{		smp_lock(&lk_dli, LK_RETRY);		lk_dli_asserted_locally = 1;	}	for(i = 0; i < MAX_BROADCSTDEV; i++)	{		if(if_isapt[i].ifp != ifp)			continue;		if_isapt[i].gsap[gsap>>VSAP][byte]  &= ~(1<< bit);		if ( lk_dli_asserted_locally )			smp_unlock(&lk_dli);		return(NULL);	}	if ( lk_dli_asserted_locally )		smp_unlock(&lk_dli);	return(ENOTFND);}/* * test if an isap has this gsap enabled in system wide table * * Note: DLI line table entry and socket locks *	 taken out before this routine called. */osi_tst_802gsap(ifp, gsap, sap)struct ifnet *ifp;int gsap, sap;{	int i, byte, bit;	if( (sap >= 255) || (sap & VSAP))		return(EINVAL);	if( (gsap <= 0) || !(gsap & 1) || (gsap > 255) )	    return(EINVAL);	byte = (sap >> VSAP) / 8;	bit = (sap >> VSAP) % 8;	smp_lock(&lk_dli, LK_RETRY);	for(i = 0; i < MAX_BROADCSTDEV; i++)	{		if(if_isapt[i].ifp != ifp)			continue;		if(if_isapt[i].gsap[gsap>>VSAP][byte]  & (1<< bit))		{			smp_unlock(&lk_dli);			return(1);		}		else		{			smp_unlock(&lk_dli);			return(NULL);		}	}	smp_unlock(&lk_dli);	return(ENOTFND);}/* * enable an 802.3 protocol (5 byte field) * for someone using the snap sap * * Note: DLI line table entry lock *	 taken out before this routine called. *	 No socket locks must be asserted! */osi_ena_802pi(so_802, ifp, ue)register struct sockaddr_802 *so_802;struct ifnet *ifp;struct dli_line *ue;{	u_char dmy_pi[5];	extern struct dli_line dli_ltable[];	register int i, error;	register struct sockaddr_802 *search_eaddr;	u_char	flags = so_802->ioctl;	bzero(dmy_pi, 5);	if(bcmp(so_802->eh_802.osi_pi, dmy_pi, 5) == 0) 		return(EINVAL);	/*	 * Only one control flag should be set.	 */	switch (flags)	{		case DLI_EXCLUSIVE:		case DLI_NORMAL:		case DLI_DEFAULT:			break;		default:			return(EINVAL);			break;	}	/*	 * Make sure address structure is unique per device.	 */	for ( i = 0; i < dli_maxline; i++ )	{		if ( &dli_ltable[i] == ue )			continue;		smp_lock(&dli_ltable[i].dli_lk, LK_RETRY);		if (dli_ltable[i].dli_lineid.dli_substructype != DLI_802 ||			dli_ltable[i].dli_so == NULL ||			ifp != dli_ltable[i].dli_if )		{			smp_unlock(&dli_ltable[i].dli_lk);			continue;		}		search_eaddr = &dli_ltable[i].dli_lineid.choose_addr.dli_802addr;		error = NULL;		switch (search_eaddr->ioctl)		{			case NULL:				break;			case DLI_EXCLUSIVE:				error = (bcmp(search_eaddr->eh_802.osi_pi, so_802->eh_802.osi_pi, 5) == NULL) ? EADDRINUSE : NULL;				break;			case DLI_NORMAL:				switch (flags)				{					case DLI_EXCLUSIVE:						error = (bcmp(search_eaddr->eh_802.osi_pi, so_802->eh_802.osi_pi, 5) == NULL) ? EADDRINUSE : NULL;						break;					case DLI_NORMAL:						if(bcmp(search_eaddr->eh_802.osi_pi, so_802->eh_802.osi_pi, 5) == NULL)						{							error = match_targets(search_eaddr->eh_802.dst, so_802->eh_802.dst);						}						else 						{							error = NULL;						}						break;					default:						break;				}				break;			case DLI_DEFAULT:				switch (flags)				{					case DLI_EXCLUSIVE:					case DLI_DEFAULT:						error = (bcmp(search_eaddr->eh_802.osi_pi, so_802->eh_802.osi_pi, 5) == NULL) ? EADDRINUSE : NULL;						break;					default:						break;				}				break;			default:				panic( "dli_bind: osi_ena_802pi:" );				break;		}		smp_unlock(&dli_ltable[i].dli_lk);		if (error != NULL)		{			return(error);		}	}	return(NULL);}/*  * build an 802 header for transmission */struct mbuf *osi_buildhdr(dst_addr)struct sockaddr_dl *dst_addr;{	struct mbuf *temp, *m = NULL;	u_char *cp;	MGET(m, M_DONTWAIT, MT_DATA);	if ( m )	{		cp = mtod(m,u_char *);		PUT8B(cp, dst_addr->choose_addr.dli_802addr.eh_802.dsap);		PUT8B(cp, dst_addr->choose_addr.dli_802addr.eh_802.ssap);		if((dst_addr->choose_addr.dli_802addr.eh_802.ctl.U_fmt & 3) == 3)		{			PUT8B(cp, dst_addr->choose_addr.dli_802addr.eh_802.ctl.U_fmt);			if(dst_addr->choose_addr.dli_802addr.eh_802.ssap == SNAP_SAP)			{				PUT8B(cp, dst_addr->choose_addr.dli_802addr.eh_802.osi_pi[0]);				PUT8B(cp, dst_addr->choose_addr.dli_802addr.eh_802.osi_pi[1]);				PUT8B(cp, dst_addr->choose_addr.dli_802addr.eh_802.osi_pi[2]);				PUT8B(cp, dst_addr->choose_addr.dli_802addr.eh_802.osi_pi[3]);				PUT8B(cp, dst_addr->choose_addr.dli_802addr.eh_802.osi_pi[4]);				m->m_len = 8;			}			else				m->m_len = 3;		}		else		{			PUT16B(cp, dst_addr->choose_addr.dli_802addr.eh_802.ctl.I_S_fmt);			m->m_len = 4;		}	}	return(m);}/* * handle 802 incoming packets * otherwise drop packet  * otherwise drop packet  * pull any header information from the 2nd mbuf to * guarantee that only data is there * * input packet as a chain of mbufs, first mbuf has garbage * 2nd mbuf will have the rest of the 802 header  * return nothing */osi_802input(m, rcv)struct mbuf *m;struct dli_recv *rcv;{    u_char *cp, bit;     int len, cnt, byte, i, j, k;    struct osi_802hdr *eh;    struct ifnet *ifp;    /*     * This structure is protected by the dliintrq queue ownership code     * in dliintr().  That code assures that only one cpu at a time will     * process input packets.     */    static struct {              /* used for gsaps to make copies of packet */    	int sap;    	struct mbuf *m;    	struct socket *so;    } m_ar[NISAPS];    register struct socket *so = NULL;    u_char svc;    struct dli_line *ue, *dli_getlte_notrust();    eh = &rcv->rcv_hdr.osi_header;#ifdef IFT_FDDI    eh->len = m_length(m->m_next);#else    len = m_length(m->m_next);    if ( len != eh->len && len != DLI_MINPKT )    {    	printd("osi_802input: invalid length, indicated = %d, actual = %d\n", eh->len, len);        goto dropit;

⌨️ 快捷键说明

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