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

📄 if_x25subr.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
		     --lcpp > pkcb->pk_chan;)			if ((lcp = *lcpp) &&			    lcp->lcd_state == DATA_TRANSFER &&			    (lcp->lcd_flags & X25_DG_CIRCUIT) &&			    (lcp->lcd_dg_timer && --lcp->lcd_dg_timer == 0)) {				lcp->lcd_upper(lcp, 0);			}	splx(s);}/* * This routine gets called when validating additions of new routes * or deletions of old ones. */x25_rtrequest(cmd, rt, dst)register struct rtentry *rt;struct sockaddr *dst;{	register struct llinfo_x25 *lx = (struct llinfo_x25 *)rt->rt_llinfo;	register struct sockaddr_x25 *sa =(struct sockaddr_x25 *)rt->rt_gateway;	register struct pklcd *lcp;	/* would put this pk_init, except routing table doesn't	   exist yet. */	if (x25_dgram_sockmask == 0) {		struct radix_node *rn_addmask();		x25_dgram_sockmask =			SA(rn_addmask((caddr_t)&x25_dgmask, 0, 4)->rn_key);	}	if (rt->rt_flags & RTF_GATEWAY) {		if (rt->rt_llinfo)			RTFREE((struct rtentry *)rt->rt_llinfo);		rt->rt_llinfo = (cmd == RTM_ADD) ? 			(caddr_t)rtalloc1(rt->rt_gateway, 1) : 0;		return;	}	if ((rt->rt_flags & RTF_HOST) == 0)		return;	if (cmd == RTM_DELETE) {		while (rt->rt_llinfo)			x25_lxfree((struct llinfo *)rt->rt_llinfo);		x25_rtinvert(RTM_DELETE, rt->rt_gateway, rt);		return;	}	if (lx == 0 && (lx = x25_lxalloc(rt)) == 0)		return;	if ((lcp = lx->lx_lcd) && lcp->lcd_state != READY) {		/*		 * This can only happen on a RTM_CHANGE operation		 * though cmd will be RTM_ADD.		 */		if (lcp->lcd_ceaddr &&		    Bcmp(rt->rt_gateway, lcp->lcd_ceaddr,					 lcp->lcd_ceaddr->x25_len) != 0) {			x25_rtinvert(RTM_DELETE, lcp->lcd_ceaddr, rt);			lcp->lcd_upper = 0;			pk_disconnect(lcp);		}		lcp = 0;	}	x25_rtinvert(RTM_ADD, rt->rt_gateway, rt);}int x25_dont_rtinvert = 0;x25_rtinvert(cmd, sa, rt)register struct sockaddr *sa;register struct rtentry *rt;{	struct rtentry *rt2 = 0;	/*	 * rt_gateway contains PID indicating which proto	 * family on the other end, so will be different	 * from general host route via X.25.	 */	if (rt->rt_ifp->if_type == IFT_X25DDN || x25_dont_rtinvert)		return;	if (sa->sa_family != AF_CCITT)		return;	if (cmd != RTM_DELETE) {		rtrequest(RTM_ADD, sa, rt_key(rt), x25_dgram_sockmask,				RTF_PROTO2, &rt2);		if (rt2) {			rt2->rt_llinfo = (caddr_t) rt;			rt->rt_refcnt++;		}		return;	}	rt2 = rt;	if ((rt = rtalloc1(sa, 0)) == 0 ||	    (rt->rt_flags & RTF_PROTO2) == 0 ||	    rt->rt_llinfo != (caddr_t)rt2) {		printf("x25_rtchange: inverse route screwup\n");		return;	} else		rt2->rt_refcnt--;	rtrequest(RTM_DELETE, sa, rt_key(rt2), x25_dgram_sockmask,				0, (struct rtentry **) 0);}static struct sockaddr_x25 blank_x25 = {sizeof blank_x25, AF_CCITT};/* * IP to X25 address routine copyright ACC, used by permission. */union imp_addr {	struct in_addr  ip;	struct imp {		u_char		s_net;		u_char		s_host;		u_char		s_lh;		u_char		s_impno;	}		    imp;};/* * The following is totally bogus and here only to preserve * the IP to X.25 translation. */x25_ddnip_to_ccitt(src, rt)struct sockaddr_in *src;register struct rtentry *rt;{	register struct sockaddr_x25 *dst = (struct sockaddr_x25 *)rt->rt_gateway;	union imp_addr imp_addr;	int             imp_no, imp_port, temp;	char *x25addr = dst->x25_addr;	imp_addr.ip = src->sin_addr;	*dst = blank_x25;	if ((imp_addr.imp.s_net & 0x80) == 0x00) {	/* class A */	    imp_no = imp_addr.imp.s_impno;	    imp_port = imp_addr.imp.s_host;	} else if ((imp_addr.imp.s_net & 0xc0) == 0x80) {	/* class B */	    imp_no = imp_addr.imp.s_impno;	    imp_port = imp_addr.imp.s_lh;	} else {		/* class C */	    imp_no = imp_addr.imp.s_impno / 32;	    imp_port = imp_addr.imp.s_impno % 32;	}	x25addr[0] = 12; /* length */	/* DNIC is cleared by struct copy above */	if (imp_port < 64) {	/* Physical:  0000 0 IIIHH00 [SS] *//* s_impno				 *  -> III, s_host -> HH */	    x25addr[5] = 0;	/* set flag bit */	    x25addr[6] = imp_no / 100;	    x25addr[7] = (imp_no % 100) / 10;	    x25addr[8] = imp_no % 10;	    x25addr[9] = imp_port / 10;	    x25addr[10] = imp_port % 10;	} else {		/* Logical:   0000 1 RRRRR00 [SS]	 *//* s				 * _host * 256 + s_impno -> RRRRR */	    temp = (imp_port << 8) + imp_no;	    x25addr[5] = 1;	    x25addr[6] = temp / 10000;	    x25addr[7] = (temp % 10000) / 1000;	    x25addr[8] = (temp % 1000) / 100;	    x25addr[9] = (temp % 100) / 10;	    x25addr[10] = temp % 10;	}}/* * This routine is a sketch and is not to be believed!!!!! * * This is a utility routine to be called by x25 devices when a * call request is honored with the intent of starting datagram forwarding. */x25_dg_rtinit(dst, ia, af)struct sockaddr_x25 *dst;register struct x25_ifaddr *ia;{	struct sockaddr *sa = 0;	struct rtentry *rt;	struct in_addr my_addr;	static struct sockaddr_in sin = {sizeof(sin), AF_INET};	if (ia->ia_ifp->if_type == IFT_X25DDN && af == AF_INET) {	/*	 * Inverse X25 to IP mapping copyright and courtesy ACC.	 */		int             imp_no, imp_port, temp;		union imp_addr imp_addr;	    {		/*		 * First determine our IP addr for network		 */		register struct in_ifaddr *ina;		extern struct in_ifaddr *in_ifaddr;		for (ina = in_ifaddr; ina; ina = ina->ia_next)			if (ina->ia_ifp == ia->ia_ifp) {				my_addr = ina->ia_addr.sin_addr;				break;			}	    }	    {		register char *x25addr = dst->x25_addr;		switch (x25addr[5] & 0x0f) {		  case 0:	/* Physical:  0000 0 IIIHH00 [SS]	 */		    imp_no =			((int) (x25addr[6] & 0x0f) * 100) +			((int) (x25addr[7] & 0x0f) * 10) +			((int) (x25addr[8] & 0x0f));		    imp_port =			((int) (x25addr[9] & 0x0f) * 10) +			((int) (x25addr[10] & 0x0f));		    break;		  case 1:	/* Logical:   0000 1 RRRRR00 [SS]	 */		    temp = ((int) (x25addr[6] & 0x0f) * 10000)			+ ((int) (x25addr[7] & 0x0f) * 1000)			+ ((int) (x25addr[8] & 0x0f) * 100)			+ ((int) (x25addr[9] & 0x0f) * 10)			+ ((int) (x25addr[10] & 0x0f));		    imp_port = temp >> 8;		    imp_no = temp & 0xff;		    break;		  default:		    return (0L);		}		imp_addr.ip = my_addr;		if ((imp_addr.imp.s_net & 0x80) == 0x00) {		/* class A */		    imp_addr.imp.s_host = imp_port;		    imp_addr.imp.s_impno = imp_no;		    imp_addr.imp.s_lh = 0;		} else if ((imp_addr.imp.s_net & 0xc0) == 0x80) {		/* class B */		    imp_addr.imp.s_lh = imp_port;		    imp_addr.imp.s_impno = imp_no;		} else {		/* class C */		    imp_addr.imp.s_impno = (imp_no << 5) + imp_port;		}	    }		sin.sin_addr = imp_addr.ip;		sa = (struct sockaddr *)&sin;	} else {		/*		 * This uses the X25 routing table to do inverse		 * lookup of x25 address to sockaddr.		 */		if (rt = rtalloc1(SA(dst), 0)) {			sa = rt->rt_gateway;			rt->rt_refcnt--;		}	}	/* 	 * Call to rtalloc1 will create rtentry for reverse path	 * to callee by virtue of cloning magic and will allocate	 * space for local control block.	 */	if (sa && (rt = rtalloc1(sa, 1)))		rt->rt_refcnt--;}int x25_startproto = 1;pk_init(){	/*	 * warning, sizeof (struct sockaddr_x25) > 32,	 * but contains no data of interest beyond 32	 */	if (x25_startproto) {		pk_protolisten(0xcc, 1, x25_dgram_incoming);		pk_protolisten(0x81, 1, x25_dgram_incoming);	}}struct x25_dgproto {	u_char spi;	u_char spilen;	int (*f)();} x25_dgprototab[] = {#if defined(ISO) && defined(TPCONS){ 0x0, 0, tp_incoming},#endif{ 0xcc, 1, x25_dgram_incoming},{ 0xcd, 1, x25_dgram_incoming},{ 0x81, 1, x25_dgram_incoming},};pk_user_protolisten(info)register u_char *info;{	register struct x25_dgproto *dp = x25_dgprototab		    + ((sizeof x25_dgprototab) / (sizeof *dp));	register struct pklcd *lcp;		while (dp > x25_dgprototab)		if ((--dp)->spi == info[0])			goto gotspi;	return ESRCH;gotspi:	if (info[1])		return pk_protolisten(dp->spi, dp->spilen, dp->f);	for (lcp = pk_listenhead; lcp; lcp = lcp->lcd_listen)		if (lcp->lcd_laddr.x25_udlen == dp->spilen &&		    Bcmp(&dp->spi, lcp->lcd_laddr.x25_udata, dp->spilen) == 0) {			pk_disconnect(lcp);			return 0;		}	return ESRCH;}/* * This routine transfers an X.25 circuit to or from a routing entry. * If the supplied circuit is * in DATA_TRANSFER state, it is added to the * routing entry.  If freshly allocated, it glues back the vc from * the rtentry to the socket. */pk_rtattach(so, m0)register struct socket *so;struct mbuf *m0;{	register struct pklcd *lcp = (struct pklcd *)so->so_pcb;	register struct mbuf *m = m0;	struct sockaddr *dst = mtod(m, struct sockaddr *);	register struct rtentry *rt = rtalloc1(dst, 0);	register struct llinfo_x25 *lx;	caddr_t cp;#define ROUNDUP(a) \	((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))#define transfer_sockbuf(s, f, l) \	while (m = (s)->sb_mb)\		{(s)->sb_mb = m->m_act; m->m_act = 0; sbfree((s), m); f(l, m);}	if (rt)		rt->rt_refcnt--;	cp = (dst->sa_len < m->m_len) ? ROUNDUP(dst->sa_len) + (caddr_t)dst : 0;	while (rt &&	       ((cp == 0 && rt_mask(rt) != 0) ||		(cp != 0 && (rt_mask(rt) == 0 ||			     Bcmp(cp, rt_mask(rt), rt_mask(rt)->sa_len)) != 0)))			rt = (struct rtentry *)rt->rt_nodes->rn_dupedkey;	if (rt == 0 || (rt->rt_flags & RTF_GATEWAY) ||	    (lx = (struct llinfo_x25 *)rt->rt_llinfo) == 0)		return ESRCH;	if (lcp == 0)		return ENOTCONN;	switch (lcp->lcd_state) {	default:		return ENOTCONN;	case READY:		/* Detach VC from rtentry */		if (lx->lx_lcd == 0)			return ENOTCONN;		lcp->lcd_so = 0;		pk_close(lcp);		lcp = lx->lx_lcd;		if (lx->lx_next->lx_rt == rt)			x25_lxfree(lx);		lcp->lcd_so = so;		lcp->lcd_upper = 0;		lcp->lcd_upnext = 0;		transfer_sockbuf(&lcp->lcd_sb, sbappendrecord, &so->so_snd);		soisconnected(so);		return 0;	case DATA_TRANSFER:		/* Add VC to rtentry */		lcp->lcd_so = 0;		lcp->lcd_sb = so->so_snd; /* structure copy */		bzero((caddr_t)&so->so_snd, sizeof(so->so_snd)); /* XXXXXX */		so->so_pcb = 0;		x25_rtattach(lcp, rt);		transfer_sockbuf(&so->so_rcv, x25_ifinput, lcp);		soisdisconnected(so);	}	return 0;}x25_rtattach(lcp0, rt)register struct pklcd *lcp0;struct rtentry *rt;{	register struct llinfo_x25 *lx = (struct llinfo_x25 *)rt->rt_llinfo;	register struct pklcd *lcp;	register struct mbuf *m;	if (lcp = lx->lx_lcd) { /* adding an additional VC */		if (lcp->lcd_state == READY) {			transfer_sockbuf(&lcp->lcd_sb, pk_output, lcp0);			lcp->lcd_upper = 0;			pk_close(lcp);		} else {			lx = x25_lxalloc(rt);			if (lx == 0)				return ENOBUFS;		}	}	lx->lx_lcd = lcp = lcp0;	lcp->lcd_upper = x25_ifinput;	lcp->lcd_upnext = (caddr_t)lx;}

⌨️ 快捷键说明

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