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

📄 sctp_t.c

📁 No7信令,我需要交换类似的代码, 请店长审核,谢谢了,急着交换,谢谢
💻 C
📖 第 1 页 / 共 5 页
字号:
	mblk_t *mp;	struct T_exdata_ind *p;	ensure( ((1<<sp->i_state) & (TSF_DATA_XFER|TSF_WIND_ORDREL)), return(-EFAULT) );	if ( canputnext(sp->rq) ) {	if ( (mp = allocb(sizeof(*p), BPRI_MED)) ) {		mp->b_datap->db_type = M_PROTO;		mp->b_band = 1;	/* expedite */		p = ((struct T_exdata_ind *)mp->b_wptr)++;		p->PRIM_type		= T_EXDATA_IND;		p->MORE_flag		= more;		mp->b_cont = dp;		putnext(sp->rq, mp);		return(0);	} seldom(); return(-ENOBUFS);	} seldom(); return(-EBUSY);}/* *  T_INFO_ACK	    16 - information acknowledgement *  ----------------------------------------------------------------- *  Although there is no limit on CDATA and DDATA size, if these are too large then we will *  IP fragment the message. */static int t_info_ack(sctp_t *sp){	mblk_t *mp;	struct T_info_ack *p;	if ( (mp = allocb(sizeof(*p), BPRI_MED)) ) {		mp->b_datap->db_type = M_PCPROTO;		p = ((struct T_info_ack *)mp->b_wptr)++;		p->PRIM_type		= T_INFO_ACK;		p->TSDU_size		= -1;		/* no limit on TSDU size	*/		p->ETSDU_size		= -1;		/* no limit on ETSDU size	*/		p->CDATA_size		= -1;		/* no limit on CDATA size	*/		p->DDATA_size		= -1;		/* no limit on DDATA size	*/		p->ADDR_size		= -1;		/* no limit on ADDR size	*/		p->OPT_size		= -1;		/* no limit on OPTIONS size	*/		p->TIDU_size		= -1;		/* no limit on TIDU size	*/		p->SERV_type		= T_COTS_ORD;	/* COTS with orderly release	*/		p->CURRENT_state	= sp->i_state;		p->PROVIDER_flag	= XPG4_1&~T_SNDZERO;		putnext(sp->rq, mp);		return(0);	} seldom(); return(-ENOBUFS);}/* *  T_BIND_ACK	    17 - bind acknowledgement *  ----------------------------------------------------------------- */static int t_bind_ack(sctp_t *sp){	mblk_t *mp;	struct T_bind_ack *p;	struct sctp_saddr *ss = sp->saddr;	size_t add_len = sp->sanum?sizeof(sp->sport)+sp->sanum*sizeof(ss->saddr):0;	ensure( (sp->i_state == TS_WACK_BREQ), return(-EFAULT) );	if ( (mp = allocb(sizeof(*p)+add_len, BPRI_MED)) ) {		mp->b_datap->db_type = M_PCPROTO;		p = ((struct T_bind_ack *)mp->b_wptr)++;		p->PRIM_type		= T_BIND_ACK;		p->ADDR_length		= add_len;		p->ADDR_offset		= add_len?sizeof(*p):0;		p->CONIND_number	= sp->conind;		if ( ss )			*((typeof(sp->sport) *)mp->b_wptr)++ = sp->sport;		for ( ; ss; ss = ss->next )			*((typeof(ss->saddr) *)mp->b_wptr)++ = ss->saddr;		sp->i_state = TS_IDLE;		putnext(sp->rq, mp);		return(0);	} seldom(); return(-ENOBUFS);}/* *  T_ERROR_ACK	    18 - error acknowledgement *  ----------------------------------------------------------------- */static int t_error_ack(sctp_t *sp, ulong prim, long err){	mblk_t *mp;	struct T_error_ack *p;	switch ( err )	{		case -EBUSY:		case -EAGAIN:		case -ENOMEM:		case -ENOBUFS:			seldom(); return(err);		case 0: never(); return (err);	}	if ( (mp = allocb(sizeof(*p), BPRI_MED)) ) {		mp->b_datap->db_type = M_PCPROTO;		p = ((struct T_error_ack *)mp->b_wptr)++;		p->PRIM_type		= T_ERROR_ACK;		p->ERROR_prim		= prim;		p->TLI_error		= err<0 ? TSYSERR : err;		p->UNIX_error		= err<0 ? -err    : 0;		switch ( sp->i_state )		{#ifdef TS_WACK_OPTREQ			case TS_WACK_OPTREQ:#endif			case TS_WACK_UREQ:			case TS_WACK_CREQ:	sp->i_state = TS_IDLE;		break;			case TS_WACK_BREQ:	sp->i_state = TS_UNBND;		break;			case TS_WACK_CRES:	sp->i_state = TS_WRES_CIND;	break;			case TS_WACK_DREQ6:	sp->i_state = TS_WCON_CREQ;	break;			case TS_WACK_DREQ7:	sp->i_state = TS_WRES_CIND;	break;			case TS_WACK_DREQ9:	sp->i_state = TS_DATA_XFER;	break;			case TS_WACK_DREQ10:	sp->i_state = TS_WIND_ORDREL;	break;			case TS_WACK_DREQ11:	sp->i_state = TS_WREQ_ORDREL;	break;			/*			 *  Note: if we are not in a WACK state we simply do			 *  not change state.  This occurs normally when we			 *  send TOUTSTATE or TNOTSUPPORT or are responding to			 *  a T_OPTMGMT_REQ in other then TS_IDLE state.			 */		}		putnext(sp->rq, mp);		return(0);	} seldom(); return(-ENOBUFS);}/* *  T_OK_ACK	    19 - success acknowledgement *  ----------------------------------------------------------------- */static int t_ok_ack(sctp_t *sp, ulong prim, ulong seq, ulong tok){	mblk_t *mp;	struct T_ok_ack *p;	if ( (mp = allocb(sizeof(*p), BPRI_MED)) ) {		mp->b_datap->db_type = M_PCPROTO;		p = ((struct T_ok_ack *)mp->b_wptr)++;		p->PRIM_type		= T_OK_ACK;		p->CORRECT_prim		= prim;		switch ( sp->i_state )		{			case TS_WACK_CREQ:	sp->i_state = TS_WCON_CREQ;	break;			case TS_WACK_UREQ:	sp->i_state = TS_UNBND;		break;			case TS_WACK_CRES:			{				queue_t *aq = (queue_t *)tok;				sctp_t *ap = (sctp_t *)aq->q_ptr;				if ( ap ) {					ap->i_state = TS_DATA_XFER;					sctp_cleanup_read(sp);	    /* deliver to user what is possible */					sctp_transmit_wakeup(ap);   /* reply to peer what is necessary */				}				if ( seq ) {					bufq_unlink(&sp->conq, (mblk_t *)seq);					freemsg((mblk_t *)seq);				}				if ( aq != sp->rq ) {					if ( bufq_length(&sp->conq) )						sp->i_state = TS_WRES_CIND;					else	sp->i_state = TS_IDLE;				}				break;			}			case TS_WACK_DREQ7:				if ( seq )					bufq_unlink(&sp->conq, (mblk_t *)seq);			case TS_WACK_DREQ6:			case TS_WACK_DREQ9:			case TS_WACK_DREQ10:			case TS_WACK_DREQ11:				if ( bufq_length(&sp->conq) )					sp->i_state = TS_WRES_CIND;				else	sp->i_state = TS_IDLE;				break;			/*			 *  Note: if we are not in a WACK state we simply do			 *  not change state.  This occurs normally when we			 *  are responding to a T_OPTMGMT_REQ in other than			 *  the TS_IDLE state.			 */		}		putnext(sp->rq, mp);		return(0);	} seldom(); return(-ENOBUFS);}/* *  T_OPTMGMT_ACK   22 - options management acknowledgement *  ----------------------------------------------------------------- */static int t_optmgmt_ack(sctp_t *sp, ulong flags, sctp_opts_t *ops){	mblk_t *mp;	size_t opt_len = sctp_opts_size(flags, sp, ops);	struct T_optmgmt_ack *p;	if ( (mp = allocb(sizeof(*p)+opt_len, BPRI_MED)) ) {		mp->b_datap->db_type = M_PCPROTO;		p = ((struct T_optmgmt_ack *)mp->b_wptr)++;		p->PRIM_type		= T_OPTMGMT_ACK;		p->OPT_length		= opt_len;		p->OPT_offset		= opt_len?sizeof(*p):0;		p->MGMT_flags		= flags;		sctp_build_opts(flags, sp, ops, &mp->b_wptr);#ifdef TS_WACK_OPTREQ		if ( sp->i_state == TS_WACK_OPTREQ )			sp->i_state = TS_IDLE;#endif		putnext(sp->rq, mp);		return(0);	} seldom(); return(-ENOBUFS);}/* *  T_ORDREL_IND    23 - orderly release indication *  ----------------------------------------------------------------- */static int t_ordrel_ind(sctp_t *sp){	mblk_t *mp;	struct T_ordrel_ind *p;	ensure( ((1<<sp->i_state) & ( TSF_DATA_XFER|TSF_WIND_ORDREL)), return(-EFAULT) );	if ( canputnext(sp->rq) ) {	if ( (mp = allocb(sizeof(*p), BPRI_MED)) )	{		mp->b_datap->db_type = M_PROTO;		p = ((struct T_ordrel_ind *)mp->b_wptr)++;		p->PRIM_type		= T_ORDREL_IND;		switch ( sp->i_state )		{			case TS_DATA_XFER:	sp->i_state = TS_WREQ_ORDREL;	break;			case TS_WIND_ORDREL:	sp->i_state = TS_IDLE;		break;		}		putnext(sp->rq, mp);		return(0);	} seldom(); return(-ENOBUFS);	} seldom(); return(-EBUSY);}/* *  T_OPTDATA_IND   26 - data with options indication *  ----------------------------------------------------------------- */static int t_optdata_ind(sctp_t *sp, uint32_t ppi, uint16_t sid, uint16_t ssn,		uint32_t tsn, uint ord, uint more, mblk_t *dp){	mblk_t *mp;	struct t_opthdr *oh;	struct T_optdata_ind *p;	size_t str_len = sizeof(*oh)+sizeof(t_scalar_t);	size_t opt_len = 0;	ensure( ((1<<sp->i_state) & (TSF_DATA_XFER|TSF_WREQ_ORDREL)), return(-EFAULT) );	if ( canputnext(sp->rq) ) {	if ( sp->i_flags & TF_SCTP_RECVOPT ) opt_len = 4*str_len;	if ( (mp = allocb(sizeof(*p)+opt_len, BPRI_MED)) ) {		mp->b_datap->db_type = M_PROTO;		mp->b_band = ord?0:1;	/* expedite */		p = ((struct T_optdata_ind *)mp->b_wptr)++;		p->PRIM_type		= T_OPTDATA_IND;		p->DATA_flag		= (more?T_ODF_MORE:0)|(ord?0:T_ODF_EX);		p->OPT_length		= opt_len;		p->OPT_offset		= opt_len?sizeof(*p):0;		/* indicate options */		if ( sp->i_flags & TF_SCTP_RECVOPT )		{			oh = ((struct t_opthdr *)mp->b_wptr)++;			oh->len	    = str_len;			oh->level   = T_INET_SCTP;			oh->name    = T_SCTP_PPI;			oh->status  = T_SUCCESS;			*((t_uscalar_t *)mp->b_wptr)++ = ppi;			oh = ((struct t_opthdr *)mp->b_wptr)++;			oh->len	    = str_len;			oh->level   = T_INET_SCTP;			oh->name    = T_SCTP_SID;			oh->status  = T_SUCCESS;			*((t_uscalar_t *)mp->b_wptr)++ = sid;			oh = ((struct t_opthdr *)mp->b_wptr)++;			oh->len	    = str_len;			oh->level   = T_INET_SCTP;			oh->name    = T_SCTP_SSN;			oh->status  = T_SUCCESS;			*((t_uscalar_t *)mp->b_wptr)++ = ssn;			oh = ((struct t_opthdr *)mp->b_wptr)++;			oh->len	    = str_len;			oh->level   = T_INET_SCTP;			oh->name    = T_SCTP_TSN;			oh->status  = T_SUCCESS;			*((t_uscalar_t *)mp->b_wptr)++ = tsn;		}		mp->b_cont = dp;		putnext(sp->rq, mp);		return(0);	} seldom(); return(-ENOBUFS);	} seldom(); return(-EBUSY);}/* *  T_ADDR_ACK	    27 - address acknowledgement *  ----------------------------------------------------------------- */static int t_addr_ack(sctp_t *sp){	mblk_t *mp;	struct T_addr_ack *p;	struct sctp_saddr *ss = sp->saddr;	struct sctp_daddr *sd = sp->daddr;	size_t loc_len = sp->sanum?sizeof(sp->sport)+sp->sanum*sizeof(ss->saddr):0;	size_t rem_len = sp->danum?sizeof(sp->dport)+sp->danum*sizeof(sd->daddr):0;	if ( (mp = allocb(sizeof(*p)+loc_len+rem_len, BPRI_MED)) ) {		mp->b_datap->db_type = M_PCPROTO;		p = ((struct T_addr_ack *)mp->b_wptr)++;		p->PRIM_type		= T_ADDR_ACK;		p->LOCADDR_length	= loc_len;		p->LOCADDR_offset	= loc_len?sizeof(*p):0;		p->REMADDR_length	= rem_len;		p->REMADDR_offset	= rem_len?sizeof(*p)+loc_len:0;		if (ss)			*((typeof(sp->sport) *)mp->b_wptr)++ = sp->sport;		for ( ; ss; ss = ss->next )			*((typeof(ss->saddr) *)mp->b_wptr)++ = ss->saddr;		if (sd)			*((typeof(sp->dport) *)mp->b_wptr)++ = sp->dport;		for ( ; sd; sd = sd->next )			*((typeof(sd->daddr) *)mp->b_wptr)++ = sd->daddr;		putnext(sp->rq, mp);		return(0);	} seldom(); return(-ENOBUFS);}#if 0/* *  T_CAPABILITY_ACK ?? - protocol capability ack *  ----------------------------------------------------------------- */static int t_capability_ack(sctp_t *sp, ulong caps){	mblk_t *mp;	struct T_capability_ack *p;	uint caps = (acceptor?TC1_ACCEPTOR:0)|(info?TC1_INFO:0);	if ( (mp = allocb(sizeof(*p), BPRI_MED)) )	{		mp->b_datap->db_type = M_PCPROTO;		p = ((struct T_capability_ack *)mp->b_wptr)++;		p->PRIM_type		= T_CAPABILITY_ACK;		p->CAP_bits1		= caps;		p->ACCEPTOR_id		= (caps&TC1_ACCEPTOR)?(ulong)sp->rq:0;		if ( caps & TC1_INFO ) {			p->INFO_ack.PRIM_type		= T_INFO_ACK;			p->INFO_ack.TSDU_size		= sp->tsdu;			p->INFO_ack.ETSDU_size		= sp->etsdu;			p->INFO_ack.CDATA_size		= sp->cdata;			p->INFO_ack.DDATA_size		= sp->ddata;			p->INFO_ack.ADDR_size		= sp->addlen;			p->INFO_ack.OPT_size		= sp->optlen;			p->INFO_ack.TIDU_size		= sp->tidu;			p->INFO_ack.SERV_type		= sp->stype;			p->INFO_ack.CURRENT_state	= sp->i_state;			p->INFO_ack.PROVIDER_flag	= sp->ptype;		} else			bzero(&p->INFO_ack, sizeof(p->INFO_ack));		putnext(sp->rq, mp);		return(0);	} return(-ENOBUFS);}#endif/* *  NOTES:- TPI cannot do data acknowledgements, resets or retrieval.  Data *  acknowledgements and retrieval are different forms of the same service. *  For data acknowledgement, use the NPI interface.  For reset support (SCTP *  Restart indication different from SCTP CDI), use the NPI interface. */static int sctp_conn_ind  (sctp_t *sp, mblk_t *cp){//ptrace(("sp = %x, CONN_IND: seq = %x\n", (uint)sp, (uint)cp));	return t_conn_ind(sp, cp);}static int sctp_conn_con  (sctp_t *sp){//ptrace(("sp = %x, CONN_CONF\n", (uint)sp));	return t_conn_con(sp);}static int sctp_data_ind  (sctp_t *sp, uint32_t ppi, uint16_t sid,		uint16_t ssn, uint32_t tsn, uint ord, uint more, mblk_t *dp){//ptrace(("sp = %x, DATA_IND: ppi=%u,sid=%u,ssn=%u,tsn=%u,ord=%u,more=%u\n", (uint)sp, ppi,sid,ssn,tsn,ord,more));	if ( sp->i_flags & TF_SCTP_RECVOPT )		    return t_optdata_ind(sp, ppi, sid, ssn, tsn, ord, more, dp);	if ( ord )  return t_data_ind(sp, more, dp);	else	    return t_exdata_ind(sp, more, dp);}static int sctp_discon_ind(sctp_t *sp, ulong orig, long reason, mblk_t *cp){//ptrace(("sp = %x, DISCON_IND\n", (uint)sp));	(void)orig;	return t_discon_ind(sp, reason, cp);}static int sctp_ordrel_ind(sctp_t *sp){//ptrace(("sp = %x, ORDREL_IND\n", (uint)sp));	return t_ordrel_ind(sp);}static struct sctp_ifops t_ops ={	sctp_conn_ind,	sctp_conn_con,	sctp_data_ind,	NULL,	NULL,	NULL,	sctp_discon_ind,	sctp_ordrel_ind,	NULL,	NULL};/* *  ========================================================================= * *  SCTP T-User --> T-Provider Primitives (Request and Response) * *  ========================================================================= *  These represent primitive requests and responses from the Transport Provider Interface *  (TPI) transport user.  Each of these requests or responses invoked a

⌨️ 快捷键说明

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