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

📄 iso_pcb.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
			printf("iso_pcbconnect localzero 1\n");		ENDDEBUG		/* 		 * If route is known or can be allocated now,		 * our src addr is taken from the i/f, else punt.		 */		flags = isop->isop_socket->so_options & SO_DONTROUTE;		if (error = clnp_route(&siso->siso_addr, &isop->isop_route, flags,						(struct sockaddr **)0, &ia))			return error;		IFDEBUG(D_ISO)			printf("iso_pcbconnect localzero 2, ro->ro_rt 0x%x",				isop->isop_route.ro_rt);			printf(" ia 0x%x\n", ia);		ENDDEBUG	}	IFDEBUG(D_ISO)		printf("in iso_pcbconnect before lookup isop 0x%x isop->sock 0x%x\n", 			isop, isop->isop_socket);	ENDDEBUG	if (local_zero) {		int nlen, tlen, totlen; caddr_t oldtsel, newtsel;		siso = isop->isop_laddr;		if (siso == 0 || siso->siso_tlen == 0)			(void)iso_pcbbind(isop, (struct mbuf *)0);		/*		 * Here we have problem of squezeing in a definite network address		 * into an existing sockaddr_iso, which in fact may not have room		 * for it.  This gets messy.		 */		siso = isop->isop_laddr;		oldtsel = TSEL(siso);		tlen = siso->siso_tlen;		nlen = ia->ia_addr.siso_nlen;		totlen = tlen + nlen + _offsetof(struct sockaddr_iso, siso_data[0]);		if ((siso == &isop->isop_sladdr) &&			(totlen > sizeof(isop->isop_sladdr))) {			struct mbuf *m = m_get(MT_SONAME, M_DONTWAIT);			if (m == 0)					return ENOBUFS;			m->m_len = totlen;			isop->isop_laddr = siso = mtod(m, struct sockaddr_iso *);		}		siso->siso_nlen = ia->ia_addr.siso_nlen;		newtsel = TSEL(siso);		ovbcopy(oldtsel, newtsel, tlen);		bcopy(ia->ia_addr.siso_data, siso->siso_data, nlen);		siso->siso_tlen = tlen;		siso->siso_family = AF_ISO;		siso->siso_len = totlen;		siso = mtod(nam, struct sockaddr_iso *);	}	IFDEBUG(D_ISO)		printf("in iso_pcbconnect before bcopy isop 0x%x isop->sock 0x%x\n", 			isop, isop->isop_socket);	ENDDEBUG	/*	 * If we had to allocate space to a previous big foreign address,	 * and for some reason we didn't free it, we reuse it knowing	 * that is going to be big enough, as sockaddrs are delivered in	 * 128 byte mbufs.	 * If the foreign address is small enough, we use default space;	 * otherwise, we grab an mbuf to copy into.	 */	if (isop->isop_faddr == 0 || isop->isop_faddr == &isop->isop_sfaddr) {		if (siso->siso_len <= sizeof(isop->isop_sfaddr))			isop->isop_faddr = &isop->isop_sfaddr;		else {			struct mbuf *m = m_get(MT_SONAME, M_DONTWAIT);			if (m == 0)				return ENOBUFS;			isop->isop_faddr = mtod(m, struct sockaddr_iso *);		}	}	bcopy((caddr_t)siso, (caddr_t)isop->isop_faddr, siso->siso_len);	IFDEBUG(D_ISO)		printf("in iso_pcbconnect after bcopy isop 0x%x isop->sock 0x%x\n", 			isop, isop->isop_socket);		printf("iso_pcbconnect connected to addr:\n");		dump_isoaddr(isop->isop_faddr);		printf("iso_pcbconnect end: src addr:\n");		dump_isoaddr(isop->isop_laddr);	ENDDEBUG	return 0;}/* * FUNCTION:		iso_pcbdisconnect() * * PURPOSE:			washes away the peer address info so the socket *					appears to be disconnected. *					If there's no file descriptor associated with the socket *					it detaches the pcb. * * RETURNS:			Nada. * * SIDE EFFECTS:	May detach the pcb. * * NOTES:			 */voidiso_pcbdisconnect(isop)	struct isopcb *isop;{	void iso_pcbdetach();	register struct sockaddr_iso *siso;	IFDEBUG(D_ISO)		printf("iso_pcbdisconnect(isop 0x%x)\n", isop);	ENDDEBUG	/*	 * Preserver binding infnormation if already bound.	 */	if ((siso = isop->isop_laddr) && siso->siso_nlen && siso->siso_tlen) {		caddr_t otsel = TSEL(siso);		siso->siso_nlen = 0;		ovbcopy(otsel, TSEL(siso), siso->siso_tlen);	}	if (isop->isop_faddr && isop->isop_faddr != &isop->isop_sfaddr)		m_freem(dtom(isop->isop_faddr));	isop->isop_faddr = 0;	if (isop->isop_socket->so_state & SS_NOFDREF)		iso_pcbdetach(isop);}/* * FUNCTION:		iso_pcbdetach * * PURPOSE:			detach the pcb at *(isop) from it's socket and free *					the mbufs associated with the pcb.. *					Dequeues (isop) from its head. * * RETURNS:			Nada. * * SIDE EFFECTS:	 * * NOTES:			 */voidiso_pcbdetach(isop)	struct isopcb *isop;{	struct socket *so = isop->isop_socket;	IFDEBUG(D_ISO)		printf("iso_pcbdetach(isop 0x%x socket 0x%x so 0x%x)\n", 			isop, isop->isop_socket, so);	ENDDEBUG#ifdef TPCONS	if (isop->isop_chan) {		register struct pklcd *lcp = (struct pklcd *)isop->isop_chan;		if (--isop->isop_refcnt > 0)			return;		if (lcp && lcp->lcd_state == DATA_TRANSFER) {			lcp->lcd_upper = 0;			lcp->lcd_upnext = 0;			pk_disconnect(lcp);		}		isop->isop_chan = 0;	}#endif	if (so) { /* in the x.25 domain, we sometimes have no socket */		so->so_pcb = 0;		sofree(so); 	}	IFDEBUG(D_ISO)		printf("iso_pcbdetach 2 \n");	ENDDEBUG	if (isop->isop_options)		(void)m_free(isop->isop_options);	IFDEBUG(D_ISO)		printf("iso_pcbdetach 3 \n");	ENDDEBUG	if (isop->isop_route.ro_rt)		rtfree(isop->isop_route.ro_rt);	IFDEBUG(D_ISO)		printf("iso_pcbdetach 3.1\n");	ENDDEBUG	if (isop->isop_clnpcache != NULL) {		struct clnp_cache *clcp =			mtod(isop->isop_clnpcache, struct clnp_cache *);		IFDEBUG(D_ISO)			printf("iso_pcbdetach 3.2: clcp 0x%x freeing clc_hdr x%x\n", 				clcp, clcp->clc_hdr);		ENDDEBUG		if (clcp->clc_hdr != NULL)			m_free(clcp->clc_hdr);		IFDEBUG(D_ISO)			printf("iso_pcbdetach 3.3: freeing cache x%x\n", 				isop->isop_clnpcache);		ENDDEBUG		m_free(isop->isop_clnpcache);	}	IFDEBUG(D_ISO)		printf("iso_pcbdetach 4 \n");	ENDDEBUG	remque(isop);	IFDEBUG(D_ISO)		printf("iso_pcbdetach 5 \n");	ENDDEBUG	if (isop->isop_laddr && (isop->isop_laddr != &isop->isop_sladdr))		m_freem(dtom(isop->isop_laddr));	free((caddr_t)isop, M_PCB);}/* * FUNCTION:		iso_pcbnotify * * PURPOSE:			notify all connections in this protocol's queue (head) *					that have peer address (dst) of the problem (errno) *					by calling (notify) on the connections' isopcbs. * * RETURNS:			Rien. * * SIDE EFFECTS:	 * * NOTES:			(notify) is called at splimp! */voidiso_pcbnotify(head, siso, errno, notify)	struct isopcb *head;	register struct sockaddr_iso *siso;	int errno, (*notify)();{	register struct isopcb *isop;	int s = splimp();	IFDEBUG(D_ISO)		printf("iso_pcbnotify(head 0x%x, notify 0x%x) dst:\n", head, notify);	ENDDEBUG	for (isop = head->isop_next; isop != head; isop = isop->isop_next) {		if (isop->isop_socket == 0 || isop->isop_faddr == 0 ||			!SAME_ISOADDR(siso, isop->isop_faddr)) {			IFDEBUG(D_ISO)				printf("iso_pcbnotify: CONTINUE isop 0x%x, sock 0x%x\n" ,					isop, isop->isop_socket);				printf("addrmatch cmp'd with (0x%x):\n", isop->isop_faddr);				dump_isoaddr(isop->isop_faddr);			ENDDEBUG			continue;		}		if (errno) 			isop->isop_socket->so_error = errno;		if (notify)			(*notify)(isop);	}	splx(s);	IFDEBUG(D_ISO)		printf("END OF iso_pcbnotify\n" );	ENDDEBUG}/* * FUNCTION:		iso_pcblookup * * PURPOSE:			looks for a given combination of (faddr), (fport), *					(lport), (laddr) in the queue named by (head). *					Argument (flags) is ignored. * * RETURNS:			ptr to the isopcb if it finds a connection matching *					these arguments, o.w. returns zero. * * SIDE EFFECTS:	 * * NOTES:			 */struct isopcb *iso_pcblookup(head, fportlen, fport, laddr)	struct isopcb *head;	register struct sockaddr_iso *laddr;	caddr_t fport;	int fportlen;{	register struct isopcb *isop;	register caddr_t lp = TSEL(laddr);	unsigned int llen = laddr->siso_tlen;	IFDEBUG(D_ISO)		printf("iso_pcblookup(head 0x%x laddr 0x%x fport 0x%x)\n", 			head, laddr, fport);	ENDDEBUG	for (isop = head->isop_next; isop != head; isop = isop->isop_next) {		if (isop->isop_laddr == 0 || isop->isop_laddr == laddr)			continue;		if (isop->isop_laddr->siso_tlen != llen)			continue;		if (bcmp(lp, TSEL(isop->isop_laddr), llen))			continue;		if (fportlen && isop->isop_faddr &&			bcmp(fport, TSEL(isop->isop_faddr), (unsigned)fportlen))			continue;		/*	PHASE2		 *	addrmatch1 should be iso_addrmatch(a, b, mask)		 *	where mask is taken from isop->isop_laddrmask (new field)		 *	isop_lnetmask will also be available in isop		if (laddr != &zeroiso_addr &&			!iso_addrmatch1(laddr, &(isop->isop_laddr.siso_addr)))			continue;		*/		if (laddr->siso_nlen && (!SAME_ISOADDR(laddr, isop->isop_laddr)))			continue;		return (isop);	}	return (struct isopcb *)0;}#endif /* ISO */

⌨️ 快捷键说明

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