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

📄 tp_input.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
			break;		case DR_TPDU_type: 			IFTRACE(D_TPINPUT)				tptrace(TPPTmisc, "DR recvd", hdr->tpdu_DRreason, 0, 0, 0);			ENDTRACE			if (sref != tpcb->tp_fref) {				printf("INPUT: inv sufx DRsref 0x%x tp_fref 0x%x\n",					sref, tpcb->tp_fref);			}								CHECK( (sref != 0 && sref != tpcb->tp_fref &&					tpcb->tp_state != TP_CRSENT), 				(TP_ERROR_SNDC | E_TP_MISM_REFS),ts_inv_sufx, respond,				(1 + (caddr_t)&hdr->tpdu_DRsref - (caddr_t)hdr))			e.ATTR(DR_TPDU).e_reason = hdr->tpdu_DRreason;			e.ATTR(DR_TPDU).e_sref =  (u_short)sref;			takes_data = TRUE;			e.ev_number = DR_TPDU;			IncStat(ts_DR_rcvd);			break;		case ER_TPDU_type:			IFTRACE(D_TPINPUT)				tptrace(TPPTmisc, "ER recvd", hdr->tpdu_ERreason,0,0,0);			ENDTRACE			e.ev_number = ER_TPDU;			e.ATTR(ER_TPDU).e_reason = hdr->tpdu_ERreason;			IncStat(ts_ER_rcvd);			break;		case AK_TPDU_type: 			e.ATTR(AK_TPDU).e_subseq = subseq;			e.ATTR(AK_TPDU).e_fcc_present = fcc_present;			if (tpcb->tp_xtd_format) {#ifdef BYTE_ORDER				union seq_type seqeotX;				seqeotX.s_seqeot = ntohl(hdr->tpdu_seqeotX);				e.ATTR(AK_TPDU).e_seq = seqeotX.s_seq;				e.ATTR(AK_TPDU).e_cdt = ntohs(hdr->tpdu_AKcdtX);#else				e.ATTR(AK_TPDU).e_cdt = hdr->tpdu_AKcdtX;				e.ATTR(AK_TPDU).e_seq = hdr->tpdu_AKseqX;#endif /* BYTE_ORDER */			} else {				e.ATTR(AK_TPDU).e_cdt = hdr->tpdu_AKcdt;				e.ATTR(AK_TPDU).e_seq = hdr->tpdu_AKseq;			}			IFTRACE(D_TPINPUT)				tptrace(TPPTmisc, "AK recvd seq cdt subseq fcc_pres", 					e.ATTR(AK_TPDU).e_seq, e.ATTR(AK_TPDU).e_cdt,					subseq, fcc_present);			ENDTRACE			e.ev_number = AK_TPDU;			IncStat(ts_AK_rcvd);			IncPStat(tpcb, tps_AK_rcvd);			break;		case XAK_TPDU_type: 			if (tpcb->tp_xtd_format) {#ifdef BYTE_ORDER				union seq_type seqeotX;				seqeotX.s_seqeot = ntohl(hdr->tpdu_seqeotX);				e.ATTR(XAK_TPDU).e_seq = seqeotX.s_seq;#else				e.ATTR(XAK_TPDU).e_seq = hdr->tpdu_XAKseqX;#endif /* BYTE_ORDER */			} else {				e.ATTR(XAK_TPDU).e_seq = hdr->tpdu_XAKseq;			}			e.ev_number = XAK_TPDU;			IncStat(ts_XAK_rcvd);			IncPStat(tpcb, tps_XAK_rcvd);			break;		case XPD_TPDU_type: 			if (tpcb->tp_xtd_format) {#ifdef BYTE_ORDER				union seq_type seqeotX;				seqeotX.s_seqeot = ntohl(hdr->tpdu_seqeotX);				e.ATTR(XPD_TPDU).e_seq = seqeotX.s_seq;#else				e.ATTR(XPD_TPDU).e_seq = hdr->tpdu_XPDseqX;#endif /* BYTE_ORDER */			} else {				e.ATTR(XPD_TPDU).e_seq = hdr->tpdu_XPDseq;			}			takes_data = TRUE;			e.ev_number = XPD_TPDU;			IncStat(ts_XPD_rcvd);			IncPStat(tpcb, tps_XPD_rcvd);			break;		case DT_TPDU_type:			{ /* the y option will cause occasional packets to be dropped.			   * A little crude but it works.			   */				IFDEBUG(D_DROP)					if(time.tv_usec & 0x4 && hdr->tpdu_DTseq & 0x1) {						IncStat(ts_ydebug);						goto discard;					}				ENDDEBUG			}			if (tpcb->tp_class == TP_CLASS_0) {			tp0_data:				e.ATTR(DT_TPDU).e_seq = 0; /* actually don't care */				e.ATTR(DT_TPDU).e_eot = (((struct tp0du *)hdr)->tp0du_eot);			} else if (tpcb->tp_xtd_format) {#ifdef BYTE_ORDER				union seq_type seqeotX;				seqeotX.s_seqeot = ntohl(hdr->tpdu_seqeotX);				e.ATTR(DT_TPDU).e_seq = seqeotX.s_seq;				e.ATTR(DT_TPDU).e_eot = seqeotX.s_eot;#else				e.ATTR(DT_TPDU).e_seq = hdr->tpdu_DTseqX;				e.ATTR(DT_TPDU).e_eot = hdr->tpdu_DTeotX;#endif /* BYTE_ORDER */			} else {				e.ATTR(DT_TPDU).e_seq = hdr->tpdu_DTseq;				e.ATTR(DT_TPDU).e_eot = hdr->tpdu_DTeot;			}			if(e.ATTR(DT_TPDU).e_eot)				IncStat(ts_eot_input);			takes_data = TRUE;			e.ev_number = DT_TPDU;			IncStat(ts_DT_rcvd);			IncPStat(tpcb, tps_DT_rcvd);			break;		case GR_TPDU_type: 			tp_indicate(T_DISCONNECT, tpcb, ECONNABORTED);			/* drop through */		default:			/* this should NEVER happen because there is a			 * check for dutype well above here			 */			error = E_TP_INV_TPDU; /* causes an ER  */			IFDEBUG(D_TPINPUT)				printf("INVALID dutype 0x%x\n", hdr->tpdu_type);			ENDDEBUG			IncStat(ts_inv_dutype);			goto respond;		}	}	/* peel off the tp header; 	 * remember that the du_li doesn't count itself.	 * This may leave us w/ an empty mbuf at the front of a chain.	 * We can't just throw away the empty mbuf because hdr still points	 * into the mbuf's data area and we're still using hdr (the tpdu header)	 */	m->m_len -= ((int)hdr->tpdu_li + 1);	m->m_data += ((int)hdr->tpdu_li + 1);	if (takes_data) {		int max = tpdu_info[ hdr->tpdu_type ] [TP_MAX_DATA_INDEX];		int datalen = tpdu_len - hdr->tpdu_li - 1, mbtype = MT_DATA;		struct {			struct tp_disc_reason dr;			struct cmsghdr x_hdr;		} x;#define c_hdr x.x_hdr		register struct mbuf *n;		CHECK( (max && datalen > max), E_TP_LENGTH_INVAL,		        ts_inv_length, respond, (max + hdr->tpdu_li + 1) );		switch( hdr->tpdu_type ) {		case CR_TPDU_type:			c_hdr.cmsg_type = TPOPT_CONN_DATA;			goto make_control_msg;		case CC_TPDU_type:			c_hdr.cmsg_type = TPOPT_CFRM_DATA;			goto make_control_msg;		case DR_TPDU_type:			x.dr.dr_hdr.cmsg_len = sizeof(x) - sizeof(c_hdr);			x.dr.dr_hdr.cmsg_type = TPOPT_DISC_REASON;			x.dr.dr_hdr.cmsg_level = SOL_TRANSPORT;			x.dr.dr_reason = hdr->tpdu_DRreason;			c_hdr.cmsg_type = TPOPT_DISC_DATA;		make_control_msg:			datalen += sizeof(c_hdr);			c_hdr.cmsg_len = datalen;			c_hdr.cmsg_level = SOL_TRANSPORT;			mbtype = MT_CONTROL;			MGET(n, M_DONTWAIT, MT_DATA);			if (n == 0)				{m_freem(m); m = 0; datalen = 0; goto invoke; }			if (hdr->tpdu_type == DR_TPDU_type) {				datalen += sizeof(x) - sizeof(c_hdr);				bcopy((caddr_t)&x, mtod(n, caddr_t), n->m_len = sizeof(x));			} else				bcopy((caddr_t)&c_hdr, mtod(n, caddr_t),					  n->m_len = sizeof(c_hdr));			n->m_next = m;			m = n;			/* FALLTHROUGH */		case XPD_TPDU_type:			if (mbtype != MT_CONTROL)				mbtype = MT_OOBDATA;			m->m_flags |= M_EOR;			/* FALLTHROUGH */		case DT_TPDU_type:			for (n = m; n; n = n->m_next) { 				MCHTYPE(n, mbtype);			}		invoke:			e.ATTR(DT_TPDU).e_datalen = datalen;			e.ATTR(DT_TPDU).e_data =  m;			break;		default:			printf(				"ERROR in tp_input! hdr->tpdu_type 0x%x takes_data 0x%x m 0x%x\n",				hdr->tpdu_type, takes_data, m);			break;		}		/* prevent m_freem() after tp_driver() from throwing it all away */		m = MNULL;	}	IncStat(ts_tpdu_rcvd);	IFDEBUG(D_TPINPUT)		printf( "tp_input: before driver, state 0x%x event 0x%x m 0x%x",			tpcb->tp_state, e.ev_number, m );		printf(" e.e_data 0x%x\n", e.ATTR(DT_TPDU).e_data);		printf("takes_data 0x%x m_len 0x%x, tpdu_len 0x%x\n",			takes_data, (m==MNULL)?0:m->m_len,  tpdu_len);	ENDDEBUG	error = tp_driver(tpcb, &e);	ASSERT(tpcb != (struct tp_pcb *)0);	ASSERT(tpcb->tp_sock != (struct socket *)0);	if( tpcb->tp_sock->so_error == 0 )		tpcb->tp_sock->so_error = error;	/* Kludge to keep the state tables under control (adding	 * data on connect & disconnect & freeing the mbuf containing	 * the data would have exploded the tables and made a big mess ).	 */	switch(e.ev_number) {		case CC_TPDU:		case DR_TPDU:		case CR_TPDU:			m = e.ATTR(CC_TPDU).e_data; /* same field for all three dutypes */			IFDEBUG(D_TPINPUT)				printf("after driver, restoring m to 0x%x, takes_data 0x%x\n", 				m, takes_data);			ENDDEBUG			break;		default:			break;	}	/* Concatenated sequences are terminated by any tpdu that 	 * carries data: CR, CC, DT, XPD, DR.	 * All other tpdu types may be concatenated: AK, XAK, DC, ER.	 */separate:	if ( takes_data == 0 )  {		ASSERT( m != MNULL );		/* 		 * we already peeled off the prev. tp header so 		 * we can just pull up some more and repeat		 */		if( m = tp_inputprep(m) ) {		IFDEBUG(D_TPINPUT)			hdr = mtod(m, struct tpdu *);			printf("tp_input @ separate: hdr 0x%x size %d m 0x%x\n", 			hdr, (int) hdr->tpdu_li + 1, m);			dump_mbuf(m, "tp_input after driver, at separate");		ENDDEBUG			IncStat(ts_concat_rcvd);			goto again;		}	}	if ( m != MNULL ) {		IFDEBUG(D_TPINPUT)			printf("tp_input : m_freem(0x%x)\n", m);		ENDDEBUG		m_freem(m);		IFDEBUG(D_TPINPUT)			printf("tp_input : after m_freem 0x%x\n", m);		ENDDEBUG	}	return (ProtoHook) tpcb;discard:	/* class 4: drop the tpdu */	/* class 2,0: Should drop the net connection, if you can figure out	 * to which connection it applies	 */	IFDEBUG(D_TPINPUT)		printf("tp_input DISCARD\n");	ENDDEBUG	IFTRACE(D_TPINPUT)		tptrace(TPPTmisc, "tp_input DISCARD m",  m,0,0,0);	ENDTRACE	m_freem(m);	IncStat(ts_recv_drop);	return (ProtoHook)0;nonx_dref:	switch (dutype) {	default:		goto discard;	case CC_TPDU_type:		/* error = E_TP_MISM_REFS; */		break;	case DR_TPDU_type:		error |= TP_ERROR_SNDC;	}respond:	IFDEBUG(D_TPINPUT)		printf("RESPOND: error 0x%x, errlen 0x%x\n", error, errlen);	ENDDEBUG	IFTRACE(D_TPINPUT)		tptrace(TPPTmisc, "tp_input RESPOND m error sref", m, error, sref, 0);	ENDTRACE	if (sref == 0)		goto discard;	(void) tp_error_emit(error, (u_long)sref, (struct sockaddr_iso *)faddr,				(struct sockaddr_iso *)laddr, m, errlen, tpcb,				cons_channel, dgout_routine);	IFDEBUG(D_ERROR_EMIT)		printf("tp_input after error_emit\n");	ENDDEBUG#ifdef lint	printf("",sref,opt);#endif /* lint */	IncStat(ts_recv_drop);	return (ProtoHook)0;}/* * NAME: tp_headersize() * * CALLED FROM: *  tp_emit() and tp_sbsend() *  TP needs to know the header size so it can figure out how *  much data to put in each tpdu. * * FUNCTION, ARGUMENTS, and RETURN VALUE: *  For a given connection, represented by (tpcb), and  *  tpdu type (dutype), return the size of a tp header. * * RETURNS:	  the expected size of the heade in bytesr * * SIDE EFFECTS:	 * * NOTES:	 It would be nice if it got the network header size as well. */inttp_headersize(dutype, tpcb) 	int 			dutype;	struct tp_pcb 	*tpcb;{	register int size = 0;	IFTRACE(D_CONN)		tptrace(TPPTmisc, "tp_headersize dutype class xtd_format",			dutype, tpcb->tp_class, tpcb->tp_xtd_format, 0);	ENDTRACE	if( !( (tpcb->tp_class == TP_CLASS_0) || 			(tpcb->tp_class == TP_CLASS_4) || 			(dutype == DR_TPDU_type) || 			(dutype == CR_TPDU_type) )) {				printf("tp_headersize:dutype 0x%x, class 0x%x", 			dutype, tpcb->tp_class);	/* TODO: identify this and GET RID OF IT */	}	ASSERT( (tpcb->tp_class == TP_CLASS_0) || 			(tpcb->tp_class == TP_CLASS_4) || 			(dutype == DR_TPDU_type) || 			(dutype == CR_TPDU_type) );	if( tpcb->tp_class == TP_CLASS_0 ) {		size =  tpdu_info[ dutype ] [TP_LEN_CLASS_0_INDEX];	} else  {		size = tpdu_info[ dutype ] [tpcb->tp_xtd_format];	} 	return size;	/* caller must get network level header size separately */}

⌨️ 快捷键说明

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