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

📄 tp_iso.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
}/* * CALLED FROM: *  tp_emit() * FUNCTION and ARGUMENTS: *  Take a packet(m0) from tp and package it so that clnp will accept it. *  This means prepending space for the clnp header and filling in a few *  of the fields. *  isop is the isopcb structure; datalen is the length of the data in the *  mbuf string m0. * RETURN VALUE: *  whatever (E*) is returned form the net layer output routine. */inttpclnp_output(isop, m0, datalen, nochksum)	struct isopcb		*isop;	struct mbuf 		*m0;	int 				datalen;	int					nochksum;{	register struct mbuf *m = m0;	IncStat(ts_tpdu_sent);	IFDEBUG(D_TPISO)		struct tpdu *hdr = mtod(m0, struct tpdu *);		printf("abt to call clnp_output: datalen 0x%x, hdr.li 0x%x, hdr.dutype 0x%x nocsum x%x dst addr:\n",			datalen,			(int)hdr->tpdu_li, (int)hdr->tpdu_type, nochksum);		dump_isoaddr(isop->isop_faddr);		printf("\nsrc addr:\n");		dump_isoaddr(isop->isop_laddr);		dump_mbuf(m0, "at tpclnp_output");	ENDDEBUG	return 		clnp_output(m0, isop, datalen,  /* flags */nochksum ? CLNP_NO_CKSUM : 0);}/* * CALLED FROM: *  tp_error_emit() * FUNCTION and ARGUMENTS: *  This is a copy of tpclnp_output that takes the addresses *  instead of a pcb.  It's used by the tp_error_emit, when we *  don't have an iso_pcb with which to call the normal output rtn. * RETURN VALUE: *  ENOBUFS or *  whatever (E*) is returned form the net layer output routine. */inttpclnp_output_dg(laddr, faddr, m0, datalen, ro, nochksum)	struct iso_addr		*laddr, *faddr;	struct mbuf 		*m0;	int 				datalen;	struct route 		*ro;	int					nochksum;{	struct isopcb		tmppcb;	int					err;	int					flags;	register struct mbuf *m = m0;	IFDEBUG(D_TPISO)		printf("tpclnp_output_dg  datalen 0x%x m0 0x%x\n", datalen, m0);	ENDDEBUG	/*	 *	Fill in minimal portion of isopcb so that clnp can send the	 *	packet.	 */	bzero((caddr_t)&tmppcb, sizeof(tmppcb));	tmppcb.isop_laddr = &tmppcb.isop_sladdr;	tmppcb.isop_laddr->siso_addr = *laddr;	tmppcb.isop_faddr = &tmppcb.isop_sfaddr;	tmppcb.isop_faddr->siso_addr = *faddr;	IFDEBUG(D_TPISO)		printf("tpclnp_output_dg  faddr: \n");		dump_isoaddr(&tmppcb.isop_sfaddr);		printf("\ntpclnp_output_dg  laddr: \n");		dump_isoaddr(&tmppcb.isop_sladdr);		printf("\n");	ENDDEBUG	/*	 *	Do not use packet cache since this is a one shot error packet	 */	flags = (CLNP_NOCACHE|(nochksum?CLNP_NO_CKSUM:0));	IncStat(ts_tpdu_sent);	err = clnp_output(m0, &tmppcb, datalen,  flags);		/*	 *	Free route allocated by clnp (if the route was indeed allocated)	 */	if (tmppcb.isop_route.ro_rt)		RTFREE(tmppcb.isop_route.ro_rt);		return(err);}/* * CALLED FROM: * 	clnp's input routine, indirectly through the protosw. * FUNCTION and ARGUMENTS: * Take a packet (m) from clnp, strip off the clnp header and give it to tp * No return value.   */ProtoHooktpclnp_input(m, src, dst, clnp_len, ce_bit)	register struct mbuf *m;	struct sockaddr_iso *src, *dst;	int clnp_len, ce_bit;{	struct mbuf *tp_inputprep();	int tp_input(), cltp_input(), (*input)() = tp_input;	IncStat(ts_pkt_rcvd);	IFDEBUG(D_TPINPUT)		printf("tpclnp_input: m 0x%x clnp_len 0x%x\n", m, clnp_len);		dump_mbuf(m, "at tpclnp_input");	ENDDEBUG	/*	 * CLNP gives us an mbuf chain WITH the clnp header pulled up,	 * and the length of the clnp header.	 * First, strip off the Clnp header. leave the mbuf there for the	 * pullup that follows.	 */	m->m_len -= clnp_len;	m->m_data += clnp_len;	m->m_pkthdr.len -= clnp_len;	/* XXXX: should probably be in clnp_input */	switch (dst->siso_data[dst->siso_nlen - 1]) {#ifdef TUBA	case ISOPROTO_TCP:		return (tuba_tcpinput(m, src, dst));#endif	case 0:		if (m->m_len == 0 && (m = m_pullup(m, 1)) == 0)			return 0;		if (*(mtod(m, u_char *)) == ISO10747_IDRP)			return (idrp_input(m, src, dst));	}	m = tp_inputprep(m);	if (m == 0)		return 0;	if (mtod(m, u_char *)[1] == UD_TPDU_type)		input = cltp_input;	IFDEBUG(D_TPINPUT)		dump_mbuf(m, "after tpclnp_input both pullups");	ENDDEBUG	IFDEBUG(D_TPISO)		printf("calling %sinput : src 0x%x, dst 0x%x, src addr:\n", 			(input == tp_input ? "tp_" : "clts_"), src, dst);		dump_isoaddr(src);		printf(" dst addr:\n");		dump_isoaddr(dst);	ENDDEBUG	(void) (*input)(m, (struct sockaddr *)src, (struct sockaddr *)dst,				0, tpclnp_output_dg, ce_bit);	IFDEBUG(D_QUENCH)		{ 			if(time.tv_usec & 0x4 && time.tv_usec & 0x40) {				printf("tpclnp_input: FAKING %s\n", 					tp_stat.ts_pkt_rcvd & 0x1?"QUENCH":"QUENCH2");				if(tp_stat.ts_pkt_rcvd & 0x1) {					tpclnp_ctlinput(PRC_QUENCH, &src);				} else {					tpclnp_ctlinput(PRC_QUENCH2, &src);				}			}		}	ENDDEBUG	return 0;}ProtoHookiso_rtchange(){	return 0;}/* * CALLED FROM: *  tpclnp_ctlinput() * FUNCTION and ARGUMENTS: *  find the tpcb pointer and pass it to tp_quench */voidtpiso_decbit(isop)	struct isopcb *isop;{	tp_quench((struct tp_pcb *)isop->isop_socket->so_pcb, PRC_QUENCH2);}/* * CALLED FROM: *  tpclnp_ctlinput() * FUNCTION and ARGUMENTS: *  find the tpcb pointer and pass it to tp_quench */voidtpiso_quench(isop)	struct isopcb *isop;{	tp_quench((struct tp_pcb *)isop->isop_socket->so_pcb, PRC_QUENCH);}/* * CALLED FROM: *  The network layer through the protosw table. * FUNCTION and ARGUMENTS: *	When clnp an ICMP-like msg this gets called. *	It either returns an error status to the user or *	it causes all connections on this address to be aborted *	by calling the appropriate xx_notify() routine. *	(cmd) is the type of ICMP error.    * 	(siso) is the address of the guy who sent the ER CLNPDU */ProtoHooktpclnp_ctlinput(cmd, siso)	int cmd;	struct sockaddr_iso *siso;{	extern u_char inetctlerrmap[];	extern ProtoHook tpiso_abort();	extern ProtoHook iso_rtchange();	extern ProtoHook tpiso_reset();	void iso_pcbnotify();	IFDEBUG(D_TPINPUT)		printf("tpclnp_ctlinput1: cmd 0x%x addr: \n", cmd);		dump_isoaddr(siso);	ENDDEBUG	if (cmd < 0 || cmd > PRC_NCMDS)		return 0;	if (siso->siso_family != AF_ISO)		return 0;	switch (cmd) {		case	PRC_QUENCH2:			iso_pcbnotify(&tp_isopcb, siso, 0, (int (*)())tpiso_decbit);			break;		case	PRC_QUENCH:			iso_pcbnotify(&tp_isopcb, siso, 0, (int (*)())tpiso_quench);			break;		case	PRC_TIMXCEED_REASS:		case	PRC_ROUTEDEAD:			iso_pcbnotify(&tp_isopcb, siso, 0, tpiso_reset);			break;		case	PRC_HOSTUNREACH:		case	PRC_UNREACH_NET:		case	PRC_IFDOWN:		case	PRC_HOSTDEAD:			iso_pcbnotify(&tp_isopcb, siso,					(int)inetctlerrmap[cmd], iso_rtchange);			break;		default:		/*		case	PRC_MSGSIZE:		case	PRC_UNREACH_HOST:		case	PRC_UNREACH_PROTOCOL:		case	PRC_UNREACH_PORT:		case	PRC_UNREACH_NEEDFRAG:		case	PRC_UNREACH_SRCFAIL:		case	PRC_REDIRECT_NET:		case	PRC_REDIRECT_HOST:		case	PRC_REDIRECT_TOSNET:		case	PRC_REDIRECT_TOSHOST:		case	PRC_TIMXCEED_INTRANS:		case	PRC_PARAMPROB:		*/		iso_pcbnotify(&tp_isopcb, siso, (int)inetctlerrmap[cmd], tpiso_abort);		break;	}	return 0;}/* * XXX - Variant which is called by clnp_er.c with an isoaddr rather * than a sockaddr_iso. */static struct sockaddr_iso siso = {sizeof(siso), AF_ISO};tpclnp_ctlinput1(cmd, isoa)	int cmd;	struct iso_addr *isoa;{	bzero((caddr_t)&siso.siso_addr, sizeof(siso.siso_addr));	bcopy((caddr_t)isoa, (caddr_t)&siso.siso_addr, isoa->isoa_len);	tpclnp_ctlinput(cmd, &siso);}/* * These next 2 routines are * CALLED FROM: *	xxx_notify() from tp_ctlinput() when *  net level gets some ICMP-equiv. type event. * FUNCTION and ARGUMENTS: *  Cause the connection to be aborted with some sort of error *  reason indicating that the network layer caused the abort. *  Fakes an ER TPDU so we can go through the driver. *  abort always aborts the TP connection. *  reset may or may not, depending on the TP class that's in use. */ProtoHooktpiso_abort(isop)	struct isopcb *isop;{	struct tp_event e;	IFDEBUG(D_CONN)		printf("tpiso_abort 0x%x\n", isop);	ENDDEBUG	e.ev_number = ER_TPDU;	e.ATTR(ER_TPDU).e_reason = ECONNABORTED;	return  tp_driver((struct tp_pcb *)isop->isop_socket->so_pcb, &e);}ProtoHooktpiso_reset(isop)	struct isopcb *isop;{	struct tp_event e;	e.ev_number = T_NETRESET;	return tp_driver((struct tp_pcb *)isop->isop_socket->so_pcb, &e);}#endif /* ISO */

⌨️ 快捷键说明

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