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

📄 sctp_msg.c

📁 No7信令,我需要交换类似的代码, 请店长审核,谢谢了,急着交换,谢谢
💻 C
📖 第 1 页 / 共 5 页
字号:
		}		rare(); return(-ENOBUFS);	}	rare(); return(-EFAULT);}/* *  SEND SHUTDOWN COMPLETE *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */static void sctp_send_shutdown_complete(sp)	sctp_t *sp;{	mblk_t *mp;	sctp_daddr_t *sd;		assert(sp);	if ( (sd = sctp_route_response(sp)) )	{		struct sctp_shutdown_comp *m;		size_t clen = sizeof(*m);		size_t plen = PADC(clen);				if ( (mp = sctp_alloc_msg(sp, clen)) )		{			m = (struct sctp_shutdown_comp *)mp->b_wptr;			m->ch.type  = SCTP_CTYPE_SHUTDOWN_COMPLETE;			m->ch.flags = 0;			m->ch.len   = __constant_htons(clen);			mp->b_wptr += plen;			sctp_send_msg(sp, sd, mp);			freechunks(mp);		}	}	sp->s_state = sp->conind?SCTP_LISTEN:SCTP_CLOSED;}/* *  SENDING WITHOUT TCB  (Responding to OOTB packets) *  ------------------------------------------------------------------------- *  When sending without an SCTP TCB, we only have the IP header and the SCTP *  header from which to work.  We have no associated STREAM.  These are *  usually used for replying to OOTB messages. * *  SEND ABORT (Without TCB) *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */void sctp_send_abort_ootb(daddr, saddr, sh)	uint32_t daddr;	uint32_t saddr;	struct sctphdr *sh;{	mblk_t *mp;	struct sctp_abort *m;	size_t clen = sizeof(*m);	size_t plen = PADC(clen);		assert( sh );	if ( (mp = sctp_alloc_reply(sh, clen)) )	{		m = (struct sctp_abort *)mp->b_wptr;		m->ch.type  = SCTP_CTYPE_ABORT;		m->ch.flags = 1;		m->ch.len   = __constant_htons(clen);		mp->b_wptr += plen;				sctp_xmit_ootb(daddr, saddr, mp);	} else rare();}/* *  SEND ABORT (w/ERROR CAUSE) (Without TCB) *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */static void sctp_send_abort_error_ootb(daddr, saddr, sh, errn, aptr, alen)	uint32_t daddr;	uint32_t saddr;	struct sctphdr *sh;	int errn;	caddr_t aptr; /* argument ptr */	size_t  alen; /* argument len */{	assert( sh );	if ( errn )	{		mblk_t *mp;		struct sctp_abort *m;		struct sctpehdr *eh;		size_t elen = sizeof(*eh)+alen;		size_t clen = sizeof(*m)+elen;		size_t plen = PADC(clen);				if ( (mp = sctp_alloc_reply(sh, clen)) )		{			m = (struct sctp_abort *)mp->b_wptr;			m->ch.type  = SCTP_CTYPE_ABORT;			m->ch.flags = 1;			m->ch.len   = htons(clen);			eh = (struct sctpehdr *)(m+1);			eh->code    = htons(errn);			eh->len	    = htons(elen);			bcopy(aptr, (eh+1), alen);			mp->b_wptr += plen;							sctp_xmit_ootb(daddr, saddr, mp);		} else rare();		return;	}	sctp_send_abort_ootb(daddr, saddr, sh);}/* *  SEND SHUTDOWN COMPLETE (Without TCB) *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */void sctp_send_shutdown_complete_ootb(daddr, saddr, sh)	uint32_t daddr;	uint32_t saddr;	struct sctphdr *sh;{	mblk_t *mp;	struct sctp_shutdown_comp *m;	size_t clen = sizeof(*m);	size_t plen = PADC(clen);		assert( sh );	if ( (mp = sctp_alloc_reply(sh, clen)) )	{		m = (struct sctp_shutdown_comp *)mp->b_wptr;		m->ch.type  = SCTP_CTYPE_SHUTDOWN_COMPLETE;		m->ch.flags = 1;		m->ch.len   = __constant_htons(clen);		mp->b_wptr += plen;		sctp_xmit_ootb(daddr, saddr, mp);	} else rare();}/* *  BIND_REQ: *  ------------------------------------------------------------------------- *  Bind the stream to the addresses provided in its bound address lists. *  There are some errors that may be returned here: * *  Any UNIX error. * *  NOADDR	- A wildcard address was specified and we don't support *		  wildcards (maybe we will). * *  ADDRBUSY	-  * */int sctp_bind_req(sp, sport, sptr, snum, cons)	sctp_t *sp;	uint16_t sport;	uint32_t *sptr;	size_t   snum;	ulong cons;{	int err;	assert( sp );	if ( !cons && !sport ) {		rare(); return(-EADDRNOTAVAIL);	}	if ( (err = sctp_alloc_saddrs(sp, sport, sptr, snum)) ) {		rare(); return(err);	}	if ( cons && (!sp->sanum || !sp->saddr) ) {		rare(); return(-EADDRNOTAVAIL);	}	if ( cons )		sp->s_state = SCTP_LISTEN;	else	sp->s_state = SCTP_CLOSED;	if ( (err = sctp_bind_hash(sp, cons)) ) {		rare(); return(err);	}	sp->conind = cons;	return(0);}/* *  CONN_REQ: *  ------------------------------------------------------------------------- *  Connect to the peer.  This launches the INIT process. */int sctp_conn_req(sp, dport, dptr, dnum, dp)	sctp_t *sp;	uint16_t dport;	uint32_t *dptr;	size_t   dnum;	mblk_t *dp;{	int err;	assert( sp );	if ( !dport ) {		rare(); return(-EADDRNOTAVAIL);	}	if ( (err = sctp_alloc_daddrs(sp, dport, dptr, dnum)) ) {		rare(); return(err);	}	if ( !sp->daddr || !sp->danum ) {		rare(); return(-EADDRNOTAVAIL);	}	sp->v_tag   = sctp_get_vtag(sp->daddr->daddr, sp->saddr->saddr, sp->dport, sp->sport);	sp->p_tag   = 0;	if ( (err = sctp_conn_hash(sp)) ) {		rare(); return(err);	}	/* XXX */	if ( (err = sctp_update_routes(sp,1)) ) {		rare(); return(err);	}	sctp_reset(sp);	/* clear old information */	sp->n_istr  = 0;	sp->n_ostr  = 0;	sp->t_tsn   = sp->v_tag;	sp->t_ack   = sp->v_tag-1;	sp->r_ack   = 0;	/* fake a data request if data in conn req */	if ( dp ) {		seldom();		if ( (err = sctp_data_req(sp, sp->ppi, sp->sid, 0, 0, 0, dp)) ) {			rare(); return(err);		}		sctp_send_init(sp);		return(0);	}	if ( (err = sctp_send_init(sp)) ) {		rare(); return(err);	}	return(0);}/* *  CONN_RES: *  ------------------------------------------------------------------------- */static int sctp_return_more(mblk_t *mp);int sctp_conn_res(sp, cp, ap, dp)	sctp_t *sp;	mblk_t *cp;	sctp_t *ap;	mblk_t *dp;{	int err;	struct sctp_cookie_echo *m;	struct sctp_cookie *ck;	uint32_t *daddrs;	uint32_t *saddrs;	assert( sp );	assert( cp );	assert( ap );	m = (struct sctp_cookie_echo *)cp->b_rptr;	ck = (struct sctp_cookie *)m->cookie;	daddrs = (uint32_t *)(ck+1);	saddrs = daddrs + ck->danum;	sctp_unbind(ap);    /* we need to rebind the accepting stream */	if ( (err = sctp_alloc_saddrs(ap, ck->sport, saddrs, ck->sanum)) ) {		rare(); return(err);	}	if ( !sctp_saddr_include(ap, ck->saddr, &err) && err ) {		rare(); return(err);	}	if ( (err = sctp_bind_hash(ap, ap->conind)) ) {		rare(); return(err);	}	if ( (err = sctp_alloc_daddrs(ap, ck->dport, daddrs, ck->danum)) ) {		rare(); return(err);	}	if ( !sctp_daddr_include(ap, ck->daddr, &err) && err ) {		rare(); return(err);	}	ap->v_tag   = ck->v_tag;	ap->p_tag   = ck->p_tag;	if ( (err = sctp_conn_hash(ap)) ) {		rare(); return(err);	}	/* XXX */	if ( (err = sctp_update_routes(ap,1)) ) {		rare(); return(err);	}	sctp_reset(ap);	/* clear old information */	ap->n_istr  = ck->n_istr;	ap->n_ostr  = ck->n_ostr;	ap->t_tsn   = ck->v_tag;	ap->t_ack   = ck->v_tag-1;	ap->r_ack   = ck->p_tsn-1;	ap->p_rwnd  = ck->p_rwnd;	ap->s_state = SCTP_ESTABLISHED;	/* process any chunks bundled with cookie echo on accepting stream */	if ( sctp_return_more(cp) > 0 )		sctp_recv_msg(ap, cp);	/* fake a data request if data in conn res */	if ( dp ) {		if ( (err = sctp_data_req(ap, ap->ppi, ap->sid, 0, 0, 0, dp)) ) {			rare(); return(err);		}	}	sctp_send_cookie_ack(ap);	/* caller will unlink connect indication */	return(0);}/* *  DATA_REQ: *  ------------------------------------------------------------------------- */int sctp_data_req(sp, ppi, sid, ord, more, rcpt, mp)	sctp_t *sp;	uint32_t ppi;	uint16_t sid;	uint ord;	/* when non-zero, indicates ordered delivery	    */	uint more;	/* when non-zero, indicates more data to follow	    */	uint rcpt;	/* when non-zero, indicates receipt conf requested  */	mblk_t *mp;{	uint err = 0, flags = 0;	sctp_strm_t  *st;	ensure( mp, return(-EFAULT) );	/* don't allow zero-length data through */	if ( !msgdsize(mp) ) {		freemsg(mp);		return(0);	}	if ( !(st = sctp_ostrm_find(sp, sid, &err)) ) {		rare(); return(err);	}	/* we probably want to data ack out of order as well */#if 0	if ( rcpt || (ord && (sp->flags & SCTP_FLAG_DEFAULT_RC_SEL)) )#else	if ( rcpt )#endif		flags |= SCTPCB_FLAG_CONF;	if ( !ord )	{		flags |= SCTPCB_FLAG_URG;		if ( !st->x.more ) {			flags |= SCTPCB_FLAG_FIRST_FRAG;			st->x.ppi = ppi;		}	}	else	{		if ( !st->n.more ) {			flags |= SCTPCB_FLAG_FIRST_FRAG;			st->n.ppi = ppi;		}	}	if ( !more )		flags |= SCTPCB_FLAG_LAST_FRAG;	return sctp_send_data(sp, st, flags, mp);}/* *  RESET_REQ: *  ------------------------------------------------------------------------- *  Don't know what to do here, probably nothing... * *  Gee we could keep a copy of the old cookie against the stream of we *  actively connected and send a COOKIE ECHO to generate a RESTART at the *  other end???? */int sctp_reset_req(sp)	sctp_t *sp;{	int err;	/* do nothing */	if ( sp->ops->sctp_reset_con && (err = sp->ops->sctp_reset_con(sp)) ) {		rare(); return(err);	}	return(0);}/* *  RESET_RES: *  ------------------------------------------------------------------------- */int sctp_reset_res(sp)	sctp_t *sp;{	mblk_t *cp;		if ( !(cp = bufq_dequeue(&sp->conq)) ) {		rare(); return(-EFAULT);	}	return sctp_conn_res(sp, cp, sp, NULL);}/* *  DISCON_REQ: *  ------------------------------------------------------------------------- */int sctp_discon_req(sp, cp)	sctp_t *sp;	mblk_t *cp;{	/*	 *  Caller must ensure that sp and cp (if any) are correct and	 *  appropriate.	 */	if ( cp )	{		struct iphdr *iph = (struct iphdr *)cp->b_datap->db_base;		struct sctphdr *sh = (struct sctphdr *)(cp->b_datap->db_base + (iph->ihl<<2));		sctp_send_abort_ootb(iph->saddr, iph->daddr, sh);		/* conn ind will be unlinked by caller */		return(0);	}	if ( (1<<sp->s_state)&(SCTPF_NEEDABORT) ) {		sctp_send_abort(sp);	} else rare();	sctp_disconnect(sp);	return(0);}/* *  ORDREL_REQ: *  ------------------------------------------------------------------------- */int sctp_ordrel_req(sp)	sctp_t *sp;{	switch ( sp->s_state )	{		case SCTP_ESTABLISHED:			if ( !bufq_head(&sp->sndq) && !bufq_head(&sp->rtxq) )				sctp_send_shutdown(sp);			else	sp->s_state = SCTP_SHUTDOWN_PENDING;			return(0);		case SCTP_SHUTDOWN_RECEIVED:			if ( !bufq_head(&sp->sndq) && !bufq_head(&sp->rtxq) )				sctp_send_shutdown_ack(sp);			else	sp->s_state = SCTP_SHUTDOWN_RECVWAIT;			return(0);	}	rare();//	ptrace(("sp->s_state = %d\n", sp->s_state));	return(-EPROTO);}/* *  UNBIND_REQ: *  ------------------------------------------------------------------------- */int sctp_unbind_req(sp)	sctp_t *sp;{	switch ( sp->s_state )	{		case SCTP_SHUTDOWN_ACK_SENT:			/* can't wait for SHUTDOWN COMPLETE any longer */			sctp_disconnect(sp);		case SCTP_CLOSED:		case SCTP_LISTEN:			sctp_unbind(sp);			return(0);	}	rare();	return(-EPROTO);}/* *  ========================================================================= * *  SCTP Peer --> SCTP Primitives (Receive Messages) * *  ========================================================================= *//* *  RETURN VALUE FUNCTIONS *  ------------------------------------------------------------------------- * *  RETURN VALUE when expecting more chunks *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */static int sctp_return_more(mp)	mblk_t *mp;{	int ret;	struct sctpchdr *ch;	assert(mp);	ch = (struct sctpchdr *)mp->b_rptr;	mp->b_rptr += PADC(ntohs(ch->len));	ret = mp->b_wptr - mp->b_rptr;	ret = ( ret < 0 || (0 < ret && ret < sizeof(struct sctpchdr)) ) ? -EMSGSIZE : ret;	unusual( ret < 0

⌨️ 快捷键说明

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