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

📄 dli_output.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
字号:
#ifndef	lintstatic char *sccsid = "@(#)dli_output.c	4.2	ULTRIX	9/4/90";#endif	lint/* * Program dli_output.c,  Module DLI  * * Copyright (C) 1985 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 10-Jul-1985 *      DECnet-ULTRIX   V1.0 * * 2.00 18-Apr-1986 *		DECnet-Ultrix	V2.0 * * Added sysid and point-to-point support * */#include "../../h/param.h"#include "../../h/systm.h"#include "../../h/mbuf.h"#include "../../h/protosw.h"#include "../../h/socket.h"#include "../../h/socketvar.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/netinet/in.h"#include "../../net/netinet/if_ether.h"#include "../../net/netdnet/dli_var.h"#include "../../net/dli/csmacd_if.h"/* * DLI output subroutine. * * * * * Attempt to transmit all pending messages for the specified virtual circuit. * * Outputs:		None. * * Inputs: *	user_line	= Pointer to the user's line descriptor. *	m		= Pointer to mbuf chain to be transmitted. *	dst_addr	= Pointer to structure containing target address. */dli_output( user_line, m, dst_addr )register struct dli_line *user_line;struct mbuf *m;struct sockaddr_dl *dst_addr;{	register struct ifnet *ifp;	register struct sockaddr_dl *out_addr;	struct ifnet *match_device();	register struct mbuf *m0 = NULL;	struct mbuf *osi_buildhdr();	int len;	int error;	int saveaffinity;  /* for nonsymm drivers.  8.18.88.us  */	u_int port;	if ( dst_addr )	{		if ( dst_addr->dli_family != AF_DLI )		{			m_freem(m);			return(EAFNOSUPPORT);		}		switch (dst_addr->dli_substructype)		{			case DLI_ETHERNET:			case DLI_POINTOPOINT:				m0 = m;			case DLI_802:				ifp = match_device(&dst_addr->dli_device);				break;			default:				m_freem(m);				return(EOPNOTSUPP);				break;		}		out_addr = dst_addr;	}	else	{		if ( (out_addr = &user_line->dli_lineid )->dli_substructype != DLI_802 )			m0 = m;		ifp = user_line->dli_if;	}	if(ifp == NULL)	{		m_freem(m);		return(ENODEV);	}	if ( ! (ifp->if_flags & IFF_RUNNING) || ! user_line->dli_sockopt.dli_state )	{		m_freem(m);		return(ENETDOWN);	}	/*	 * for 802 packets, validate user data length	 * and then build the 802 header for transmission	 */	len = m_length(m);	if(m0 == NULL)	{		if(user_line->dli_lineid.choose_addr.dli_802addr.eh_802.ssap == SNAP_SAP && len > ifp->if_mtu - MAX802DATAP)		{			m_freem(m);			return(EMSGSIZE);		}		else if (len > ifp->if_mtu - MAX802DATANP)		{			m_freem(m);			return(EMSGSIZE);		}		if( (m0 = osi_buildhdr(out_addr)) == NULL)		{			m_freem(m);			return(ENOBUFS);		}		m0->m_next = m;	}	else	{#ifdef IFT_FDDI		if ( ifp->if_flags & IFF_802HDR )		{			if ( len > ETHERMTU - MAX802DATAP)			{				m_freem(m);				return(EMSGSIZE);			}		}		else#endif		{			if ( len > ifp->if_mtu )			{				m_freem(m);				return(EMSGSIZE);			}		}	}	port = user_line->dli_portid;	len = m_length(m0);	/*	 * No need to keep dli line table entry and socket locked	 * while in driver. 	 */	smp_unlock(&user_line->dli_so->lk_socket);	smp_unlock(&user_line->dli_lk);	CALL_TO_NONSMP_DRIVER( (*ifp), saveaffinity);	error = ( (*ifp->if_output)(ifp, m0, out_addr) );	RETURN_FROM_NONSMP_DRIVER( (*ifp), saveaffinity);	if ( !error && port && ( out_addr->dli_substructype == DLI_ETHERNET || 		out_addr->dli_substructype == DLI_802) )	{		struct dli_ifincout ic;		ic.port = (caddr_t) port;		ic.octets_sent = len;		if ( out_addr->dli_substructype == DLI_ETHERNET )		    ic.mcast = out_addr->choose_addr.dli_eaddr.dli_target[0] & 1;		else		    ic.mcast = out_addr->choose_addr.dli_802addr.eh_802.dst[0] & 1;		(*user_line->dli_proto->pr_ctloutput)(PRCO_PIF, NULL, 0, CSMACD_INCOUT, &ic);	}	smp_lock(&user_line->dli_lk, LK_RETRY);	if ( user_line->dli_so != NULL )		smp_lock(&user_line->dli_so->lk_socket, LK_RETRY);	return( error );}

⌨️ 快捷键说明

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