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

📄 if_x25subr.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1990, 1993 *	The Regents of the University of California.  All rights reserved. * * 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. * *	@(#)if_x25subr.c	8.1 (Berkeley) 6/10/93 */#include <sys/param.h>#include <sys/systm.h>#include <sys/malloc.h>#include <sys/mbuf.h>#include <sys/protosw.h>#include <sys/socket.h>#include <sys/socketvar.h>#include <sys/ioctl.h>#include <sys/errno.h>#include <sys/syslog.h>#include <machine/mtpr.h>#include <net/if.h>#include <net/if_types.h>#include <net/netisr.h>#include <net/route.h>#include <netccitt/x25.h>#include <netccitt/x25err.h>#include <netccitt/pk.h>#include <netccitt/pk_var.h>#ifdef INET#include <netinet/in.h>#include <netinet/in_var.h>#endif#ifdef NS#include <netns/ns.h>#include <netns/ns_if.h>#endif#ifdef ISOint tp_incoming();#include <netiso/argo_debug.h>#include <netiso/iso.h>#include <netiso/iso_var.h>#endifextern	struct ifnet loif;struct llinfo_x25 llinfo_x25 = {&llinfo_x25, &llinfo_x25};#ifndef _offsetof#define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m))#endifstruct sockaddr *x25_dgram_sockmask;struct sockaddr_x25 x25_dgmask = { _offsetof(struct sockaddr_x25, x25_udata[1]),			/* _len */ 0,								/* _family */ 0,								/* _net */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* _addr */ {0},								/* opts */ -1,								/* _udlen */ {-1}								/* _udata */}; struct if_x25stats {	int	ifx_wrongplen;	int	ifx_nophdr;} if_x25stats;int x25_autoconnect = 0;#define senderr(x) {error = x; goto bad;}/* * Ancillary routines */static struct llinfo_x25 *x25_lxalloc(rt)register struct rtentry *rt;{	register struct llinfo_x25 *lx;	register struct sockaddr *dst = rt_key(rt);	register struct ifaddr *ifa;	MALLOC(lx, struct llinfo_x25 *, sizeof (*lx), M_PCB, M_NOWAIT);	if (lx == 0)		return lx;	Bzero(lx, sizeof(*lx));	lx->lx_rt = rt;	lx->lx_family = dst->sa_family;	rt->rt_refcnt++;	if (rt->rt_llinfo)		insque(lx, (struct llinfo_x25 *)rt->rt_llinfo);	else {		rt->rt_llinfo = (caddr_t)lx;		insque(lx, &llinfo_x25);	}	for (ifa = rt->rt_ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {		if (ifa->ifa_addr->sa_family == AF_CCITT)			lx->lx_ia = (struct x25_ifaddr *)ifa;	}	return lx;}x25_lxfree(lx)register struct llinfo_x25 *lx;{	register struct rtentry *rt = lx->lx_rt;	register struct pklcd *lcp = lx->lx_lcd;	if (lcp) {		lcp->lcd_upper = 0;		pk_disconnect(lcp);	}	if ((rt->rt_llinfo == (caddr_t)lx) && (lx->lx_next->lx_rt == rt))		rt->rt_llinfo = (caddr_t)lx->lx_next;	else		rt->rt_llinfo = 0;	RTFREE(rt);	remque(lx);	FREE(lx, M_PCB);}/* * Process a x25 packet as datagram; */x25_ifinput(lcp, m)struct pklcd *lcp;register struct mbuf *m;{	struct llinfo_x25 *lx = (struct llinfo_x25 *)lcp->lcd_upnext;	register struct ifnet *ifp;	struct ifqueue *inq;	extern struct timeval time;	int s, len, isr; 	if (m == 0 || lcp->lcd_state != DATA_TRANSFER) {		x25_connect_callback(lcp, 0);		return;	}	pk_flowcontrol(lcp, 0, 1); /* Generate RR */	ifp = m->m_pkthdr.rcvif;	ifp->if_lastchange = time;	switch (m->m_type) {	default:		if (m)			m_freem(m);		return;	case MT_DATA:		/* FALLTHROUGH */;	}	switch (lx->lx_family) {#ifdef INET	case AF_INET:		isr = NETISR_IP;		inq = &ipintrq;		break;#endif#ifdef NS	case AF_NS:		isr = NETISR_NS;		inq = &nsintrq;		break;#endif#ifdef	ISO	case AF_ISO:		isr = NETISR_ISO;		inq = &clnlintrq;		break;#endif	default:		m_freem(m);		ifp->if_noproto++;		return;	}	s = splimp();	schednetisr(isr);	if (IF_QFULL(inq)) {		IF_DROP(inq);		m_freem(m);	} else {		IF_ENQUEUE(inq, m);		ifp->if_ibytes += m->m_pkthdr.len;	}	splx(s);}x25_connect_callback(lcp, m)register struct pklcd *lcp;register struct mbuf *m;{	register struct llinfo_x25 *lx = (struct llinfo_x25 *)lcp->lcd_upnext;	int do_clear = 1;	if (m == 0)		goto refused;	if (m->m_type != MT_CONTROL) {		printf("x25_connect_callback: should panic\n");		goto refused;	}	switch (pk_decode(mtod(m, struct x25_packet *))) {	case CALL_ACCEPTED:		lcp->lcd_upper = x25_ifinput;		if (lcp->lcd_sb.sb_mb)			lcp->lcd_send(lcp); /* XXX start queued packets */		return;	default:		do_clear = 0;	refused:		lcp->lcd_upper = 0;		lx->lx_lcd = 0;		if (do_clear)			pk_disconnect(lcp);		return;	}}#define SA(p) ((struct sockaddr *)(p))#define RT(p) ((struct rtentry *)(p))x25_dgram_incoming(lcp, m0)register struct pklcd *lcp;struct mbuf *m0;{	register struct rtentry *rt, *nrt;	register struct mbuf *m = m0->m_next; /* m0 has calling sockaddr_x25 */	void x25_rtrequest();	rt = rtalloc1(SA(&lcp->lcd_faddr), 0);	if (rt == 0) {refuse: 	lcp->lcd_upper = 0;		pk_close(lcp);		return;	}	rt->rt_refcnt--;	if ((nrt = RT(rt->rt_llinfo)) == 0 || rt_mask(rt) != x25_dgram_sockmask)		goto refuse;	if ((nrt->rt_flags & RTF_UP) == 0) {		rt->rt_llinfo = (caddr_t)rtalloc1(rt->rt_gateway, 0);		rtfree(nrt);		if ((nrt = RT(rt->rt_llinfo)) == 0)			goto refuse;		nrt->rt_refcnt--;	}	if (nrt->rt_ifa == 0 || nrt->rt_ifa->ifa_rtrequest != x25_rtrequest)		goto refuse;	lcp->lcd_send(lcp); /* confirm call */	x25_rtattach(lcp, nrt);	m_freem(m);}/* * X.25 output routine. */x25_ifoutput(ifp, m0, dst, rt)struct	ifnet *ifp;struct	mbuf *m0;struct	sockaddr *dst;register struct	rtentry *rt;{	register struct	mbuf *m = m0;	register struct	llinfo_x25 *lx;	struct pklcd *lcp;	int             s, error = 0;int plen;for (plen = 0; m; m = m->m_next)	plen += m->m_len;m = m0;	if ((ifp->if_flags & IFF_UP) == 0)		senderr(ENETDOWN);	while (rt == 0 || (rt->rt_flags & RTF_GATEWAY)) {		if (rt) {			if (rt->rt_llinfo) {				rt = (struct rtentry *)rt->rt_llinfo;				continue;			}			dst = rt->rt_gateway;		}		if ((rt = rtalloc1(dst, 1)) == 0)			senderr(EHOSTUNREACH);		rt->rt_refcnt--;	}	/*	 * Sanity checks.	 */	if ((rt->rt_ifp != ifp) ||	    (rt->rt_flags & (RTF_CLONING | RTF_GATEWAY)) ||	    ((lx = (struct llinfo_x25 *)rt->rt_llinfo) == 0)) {		senderr(ENETUNREACH);	}if ((m->m_flags & M_PKTHDR) == 0) {	if_x25stats.ifx_nophdr++;	m = m_gethdr(M_NOWAIT, MT_HEADER);	if (m == 0)		senderr(ENOBUFS);	m->m_pkthdr.len = plen;	m->m_next = m0;}if (plen != m->m_pkthdr.len) {	if_x25stats.ifx_wrongplen++;	m->m_pkthdr.len = plen;}next_circuit:	lcp = lx->lx_lcd;	if (lcp == 0) {		lx->lx_lcd = lcp = pk_attach((struct socket *)0);		if (lcp == 0)			senderr(ENOBUFS);		lcp->lcd_upper = x25_connect_callback;		lcp->lcd_upnext = (caddr_t)lx;		lcp->lcd_packetsize = lx->lx_ia->ia_xc.xc_psize;		lcp->lcd_flags = X25_MBS_HOLD;	}	switch (lcp->lcd_state) {	case READY:		if (dst->sa_family == AF_INET &&		    ifp->if_type == IFT_X25DDN &&		    rt->rt_gateway->sa_family != AF_CCITT)			x25_ddnip_to_ccitt(dst, rt);		if (rt->rt_gateway->sa_family != AF_CCITT) {			if ((rt->rt_flags & RTF_XRESOLVE) == 0)				senderr(EHOSTUNREACH);		} else if (x25_autoconnect)			error = pk_connect(lcp,					(struct sockaddr_x25 *)rt->rt_gateway);		if (error)			senderr(error);		/* FALLTHROUGH */	case SENT_CALL:	case DATA_TRANSFER:		if (sbspace(&lcp->lcd_sb) < 0) {			lx = lx->lx_next;			if (lx->lx_rt != rt)				senderr(ENOSPC);			goto next_circuit;		}		if (lx->lx_ia)			lcp->lcd_dg_timer =				       lx->lx_ia->ia_xc.xc_dg_idletimo;		pk_send(lcp, m);		break;	default:		/*		 * We count on the timer routine to close idle		 * connections, if there are not enough circuits to go		 * around.		 *		 * So throw away data for now.		 * After we get it all working, we'll rewrite to handle		 * actively closing connections (other than by timers),		 * when circuits get tight.		 *		 * In the DDN case, the imp itself closes connections		 * under heavy load.		 */		error = ENOBUFS;	bad:		if (m)			m_freem(m);	}	return (error);}/* * Simpleminded timer routine. */x25_iftimeout(ifp)struct ifnet *ifp;{	register struct pkcb *pkcb = 0;	register struct pklcd **lcpp, *lcp;	int s = splimp();	FOR_ALL_PKCBS(pkcb)	    if (pkcb->pk_ia->ia_ifp == ifp)		for (lcpp = pkcb->pk_chan + pkcb->pk_maxlcn;

⌨️ 快捷键说明

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