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

📄 mtp_npi.c

📁 OpenSS7 This the fourth public release of the OpenSS7 Master Package. See README in the release for
💻 C
📖 第 1 页 / 共 5 页
字号:
			p->PRIM_type = N_CONN_IND;			p->SRC_length = src_len;			p->SRC_offset = sizeof(*p);			p->DEST_length = dst_len;			p->DEST_offset = sizeof(*p) + src_len;			p->QOS_length = qos_len;			p->QOS_offset = sizeof(*p) + src_len + dst_len;			p->SEQ_number = seq;			p->CONN_flags = flags;			mp->b_wptr += sizeof(*p);			n_build_addr(src, mp->b_wptr);			mp->b_wptr += src_len;			n_build_addr(dst, mp->b_wptr);			mp->b_wptr += dst_len;			n_build_opts(qos, mp->b_wptr);			mp->b_wptr += qos_len;			mp->b_cont = dp;			if (bp)				freeb(bp);			mi_strlog(q, STRLOGRX, SL_TRACE, "<- N_CONN_IND");			putnext(mtp->rq, mp);			return (0);		}		freeb(mp);		return (-EBUSY);	}	return (-ENOBUFS);}/** * n_conn_con: - issue a N_CONN_CON primitive upstream * @mtp: private structure * @q: active queue * @bp: message block to free upon success * @res: responding address * @opt: options * @dp: user data */static inline fastcall __unlikely intn_conn_con(struct mtp *mtp, queue_t *q, mblk_t *bp,	   np_ulong flags, struct mtp_addr *res, union N_qos_mtp *qos, mblk_t *dp){	N_conn_con_t *p;	mblk_t *mp;	const size_t res_len = n_addr_size(res);	const size_t qos_len = n_opts_size(qos);	const size_t msg_len = sizeof(*p) + res_len + qos_len;	if (likely((mp = mi_allocb(q, msg_len, BPRI_MED)) != NULL)) {		if (likely(canputnext(mtp->rq))) {			DB_TYPE(mp) = M_PROTO;			p = (typeof(p)) mp->b_wptr;			p->PRIM_type = N_CONN_CON;			p->RES_length = res_len;			p->RES_offset = sizeof(*p);			p->CONN_flags = flags;			p->QOS_length = qos_len;			p->QOS_offset = sizeof(*p) + res_len;			mp->b_wptr += sizeof(*p);			n_build_addr(res, mp->b_wptr);			mp->b_wptr += res_len;			n_build_opts(qos, mp->b_wptr);			mp->b_wptr += qos_len;			mp->b_cont = dp;			if (bp)				freeb(bp);			mi_strlog(q, STRLOGRX, SL_TRACE, "<- N_CONN_CON");			if (mtp_get_state(mtp) != NS_WCON_CREQ)				swerr();			mtp_set_state(mtp, NS_DATA_XFER);			putnext(mtp->rq, mp);			return (0);		}		freeb(mp);		return (-EBUSY);	}	return (-ENOBUFS);}/** * n_discon_ind: - issue a N_DISCON_IND primitive upstream * @mtp: private structure * @q: active queue * @bp: message block to free upon success * @reason: reason for disconnection * @dp: user data */static inline fastcall __unlikely intn_discon_ind(struct mtp *mtp, queue_t *q, mblk_t *bp,	     np_ulong orig, np_ulong reason, np_ulong seq, struct mtp_addr *res, mblk_t *dp){	N_discon_ind_t *p;	mblk_t *mp;	const size_t res_len = n_addr_size(res);	const size_t msg_len = sizeof(*p) + res_len;	if (mtp_chk_state	    (mtp,	     (NSF_WCON_CREQ | NSF_WRES_CIND | NSF_DATA_XFER | NSF_WCON_RREQ | NSF_WRES_RIND))) {		if (likely((mp = mi_allocb(q, msg_len, BPRI_MED)) != NULL)) {			if (likely(canputnext(mtp->rq))) {				DB_TYPE(mp) = M_PROTO;				p = (typeof(p)) mp->b_wptr;				p->PRIM_type = N_DISCON_IND;				p->DISCON_orig = orig;				p->DISCON_reason = reason;				p->RES_length = res_len;				p->RES_offset = sizeof(*p);				p->SEQ_number = seq;				mp->b_wptr += sizeof(*p);				n_build_addr(res, mp->b_wptr);				mp->b_wptr += res_len;				mp->b_cont = dp;				if (bp)					freeb(bp);				mi_strlog(q, STRLOGRX, SL_TRACE, "<- N_DISCON_IND");				putnext(mtp->rq, mp);				return (0);			}			freeb(mp);			return (-EBUSY);		}		return (-ENOBUFS);	}	mi_strlog(q, 0, SL_ERROR, "unexpected indication for state %u", mtp_get_state(mtp));	freeb(bp);	freemsg(dp);	return (0);}/** * n_data_ind: - issue a N_DATA_IND primitive upstream * @mtp: private structure * @q: active queue * @bp: message block to free upon success * @more: more data flag * @dp: user data */static inline fastcall __unlikely intn_data_ind(struct mtp *mtp, queue_t *q, mblk_t *bp, np_ulong flags, mblk_t *dp){	N_data_ind_t *p;	mblk_t *mp;	if (mtp_chk_state(mtp, (NSF_DATA_XFER | NSF_WCON_RREQ))) {		if (likely((mp = mi_allocb(q, sizeof(*p), BPRI_MED)) != NULL)) {			if (likely(canputnext(mtp->rq))) {				DB_TYPE(mp) = M_PROTO;				p = (typeof(p)) mp->b_wptr;				p->PRIM_type = N_DATA_IND;				p->DATA_xfer_flags = flags;				mp->b_wptr += sizeof(*p);				mp->b_cont = dp;				if (bp)					freeb(bp);				mi_strlog(q, STRLOGRX, SL_TRACE, "<- N_DATA_IND");				putnext(mtp->rq, mp);				return (0);			}			freeb(mp);			return (-EBUSY);		}		return (-ENOBUFS);	}	mi_strlog(q, 0, SL_ERROR, "unexpected indication for state %u", mtp_get_state(mtp));	freeb(bp);	freemsg(dp);	return (0);}/** * t_exdata_ind: - issue a T_EXDATA_IND primitive upstream * @mtp: private structure * @q: active queue * @bp: message block to free upon success * @more: more data flag * @dp: user data */static inline fastcall __unlikely intn_exdata_ind(struct mtp *mtp, queue_t *q, mblk_t *bp, mblk_t *dp){	N_exdata_ind_t *p;	mblk_t *mp;	if (mtp_chk_state(mtp, (NSF_DATA_XFER | NSF_WCON_RREQ))) {		if (likely((mp = mi_allocb(q, sizeof(*p), BPRI_MED)) != NULL)) {			if (likely(canputnext(mtp->rq))) {				DB_TYPE(mp) = M_PROTO;				mp->b_band = 1;				p = (typeof(p)) mp->b_wptr;				p->PRIM_type = N_EXDATA_IND;				mp->b_wptr += sizeof(*p);				mp->b_cont = dp;				if (bp)					freeb(bp);				mi_strlog(q, STRLOGRX, SL_TRACE, "<- N_EXDATA_IND");				putnext(mtp->rq, mp);				return (0);			}			freeb(mp);			return (-EBUSY);		}		return (-ENOBUFS);	}	mi_strlog(q, 0, SL_ERROR, "unexpected indication for state %u", mtp_get_state(mtp));	freeb(bp);	freemsg(dp);	return (0);}/** * n_info_ack: - issue a N_INFO_ACK primitive upstream * @mtp: private structure * @q: active queue * @msg: message to free upon success */static inline fastcall __unlikely intn_info_ack(struct mtp *mtp, queue_t *q, mblk_t *msg){	N_info_ack_t *p;	mblk_t *mp;	size_t src_len, dst_len, msg_len;	N_qos_sel_info_mtp_t *qos;	N_qos_range_info_mtp_t *qor;	size_t qos_len = sizeof(*qos);	size_t qor_len = sizeof(*qor);	switch (mtp_get_state(mtp)) {	default:	case NS_UNBND:		src_len = 0;		dst_len = 0;		break;	case NS_IDLE:		src_len = sizeof(mtp->src);		dst_len = 0;		break;	case NS_DATA_XFER:		src_len = sizeof(mtp->src);		dst_len = sizeof(mtp->dst);		break;	}	msg_len = sizeof(*p) + src_len + dst_len + qos_len + qor_len;	if (likely((mp = mi_allocb(q, msg_len, BPRI_MED)) != NULL)) {		DB_TYPE(mp) = M_PCPROTO;		p = (typeof(p)) mp->b_wptr;		mp->b_wptr += sizeof(*p);		*p = mtp->prot;		p->ADDR_size = sizeof(struct mtp_addr);		p->ADDR_length = src_len + dst_len;		p->ADDR_offset = src_len + dst_len ? sizeof(*p) : 0;		p->QOS_length = qos_len;		p->QOS_offset = qos_len ? sizeof(*p) + src_len + dst_len : 0;		p->QOS_range_length = qor_len;		p->QOS_range_offset = qor_len ? sizeof(*p) + src_len + dst_len + qos_len : 0;		p->PROTOID_length = 0;		p->PROTOID_offset = 0;		if (src_len) {			bcopy(&mtp->src, mp->b_wptr, sizeof(mtp->src));			mp->b_wptr += sizeof(mtp->src);		}		if (dst_len) {			bcopy(&mtp->dst, mp->b_wptr, sizeof(mtp->dst));			mp->b_wptr += sizeof(mtp->dst);		}		if (qos_len) {			qos = (typeof(qos)) mp->b_wptr;			mp->b_wptr += sizeof(*qos);			qos->n_qos_type = N_QOS_SEL_INFO_MTP;			qos->pvar = mtp->options.pvar;			qos->popt = mtp->options.popt;		}		if (qor_len) {			qor = (typeof(qor)) mp->b_wptr;			mp->b_wptr += sizeof(*qor);			qor->n_qos_type = N_QOS_RANGE_INFO_MTP;			qor->sls_range = mtp->options.sls_mask;			qor->mp_range = (mtp->options.popt & SS7_POPT_MPLEV) ? 3 : 0;		}		mi_strlog(q, STRLOGRX, SL_TRACE, "<- N_INFO_ACK");		putnext(mtp->rq, mp);		return (0);	}	return (-ENOBUFS);}/* * n_bind_ack: - issue a N_BIND_ACK primitive upstream * @mtp: private structure * @q: active queue * @msg: message to free upon success * @add: bound address * @cons: negotiated number of oustanding connection indications */static inline fastcall __unlikely intn_bind_ack(struct mtp *mtp, queue_t *q, mblk_t *msg, struct mtp_addr *add, np_ulong cons){	N_bind_ack_t *p;	mblk_t *mp;	size_t add_len = n_addr_size(add);	size_t msg_len = sizeof(*p) + add_len;	if (mtp_get_state(mtp) == NS_WACK_BREQ) {		if (likely((mp = mi_allocb(q, msg_len, BPRI_MED)) != NULL)) {			DB_TYPE(mp) = M_PCPROTO;			p = (typeof(p)) mp->b_wptr;			p->PRIM_type = N_BIND_ACK;			p->ADDR_length = add_len;			p->ADDR_offset = add_len ? sizeof(*p) : 0;			p->CONIND_number = cons;			p->TOKEN_value = (np_ulong) (long) mtp->rq;			p->PROTOID_length = 0;			p->PROTOID_offset = 0;			mp->b_wptr += sizeof(*p);			n_build_addr(add, mp->b_wptr);			mp->b_wptr += add_len;			mtp_bind(mtp, add);			mtp_set_state(mtp, NS_IDLE);			freemsg(msg);			mi_strlog(q, STRLOGRX, SL_TRACE, "<- N_BIND_ACK");			putnext(mtp->rq, mp);			return (0);		}		return (-ENOBUFS);	}	mi_strlog(q, 0, SL_ERROR, "unexpected indication for state %u", mtp_get_state(mtp));	freemsg(msg);	return (0);}/* * n_error_ack: - issue a N_ERROR_ACK primitive upstream * @mtp: private structure * @q: active queue * @msg: message to free upon success * @prim: primitive in error * @etypr: error type */static inline fastcall __unlikely intn_error_ack(struct mtp *mtp, queue_t *q, mblk_t *msg, np_ulong prim, np_long etype){	N_error_ack_t *p;	mblk_t *mp;	size_t msg_len = sizeof(*p);	if (likely((mp = mi_allocb(q, msg_len, BPRI_MED)) != NULL)) {		DB_TYPE(mp) = M_PCPROTO;		p = (typeof(p)) mp->b_wptr;		p->PRIM_type = N_ERROR_ACK;		p->ERROR_prim = prim;		p->NPI_error = etype < 0 ? NSYSERR : etype;		p->UNIX_error = etype < 0 ? -etype : 0;		mp->b_wptr += sizeof(*p);		switch (mtp_get_state(mtp)) {#ifdef NS_WACK_OPTREQ		case NS_WACK_OPTREQ:#endif		case NS_WACK_UREQ:			mtp_set_state(mtp, NS_IDLE);			break;		case NS_WACK_BREQ:			mtp_set_state(mtp, NS_UNBND);			break;		case NS_WACK_CRES:			mtp_set_state(mtp, NS_WRES_CIND);			break;		case NS_WACK_DREQ6:			mtp_set_state(mtp, NS_WCON_CREQ);			break;		case NS_WACK_DREQ7:			mtp_set_state(mtp, NS_WRES_CIND);			break;		case NS_WACK_DREQ9:			mtp_set_state(mtp, NS_DATA_XFER);			break;		case NS_WACK_DREQ10:			mtp_set_state(mtp, NS_WCON_RREQ);			break;		case NS_WACK_DREQ11:			mtp_set_state(mtp, NS_WRES_RIND);			break;		default:			/* Note: if we are not in a WACK state we simply do not change state.  This 			   occurs normally when we send NOUTSTATE or NNOTSUPPORT or are responding			   to a N_OPTMGMT_REQ in other than NS_IDLE state. */			break;		}		freemsg(msg);		mi_strlog(q, STRLOGRX, SL_TRACE, "<- N_ERROR_ACK");		putnext(mtp->rq, mp);		/* Retruning -EPROTO here will make sure that the old state is restored correctly.		   If we return 0, then the state will never be restored. */		if (etype >= 0)			return (-EPROTO);		return (0);	}	return (-ENOBUFS);}/** * n_ok_ack: - issue a N_OK_ACK primitive upstream * @mtp: private structure * @q: active queue * @msg: message to free upon success * @prim: correct primitive * @seq: sequence number * @tok: stream token */static inline fastcall __unlikely intn_ok_ack(struct mtp *mtp, queue_t *q, mblk_t *msg, np_ulong prim){	N_ok_ack_t *p;	mblk_t *mp;	size_t msg_len = sizeof(*p);	if (likely((mp = mi_allocb(q, msg_len, BPRI_MED)) != NULL)) {		DB_TYPE(mp) = M_PCPROTO;		p = (typeof(p)) mp->b_wptr;		p->PRIM_type = N_OK_ACK;		p->CORRECT_prim = prim;		mp->b_wptr += sizeof(*p);		switch (mtp_get_state(mtp)) {		case NS_WACK_RRES:			mtp_set_state(mtp, NS_DATA_XFER);			break;		case NS_WACK_UREQ:			mtp_unbind(mtp);			mtp_set_state(mtp, NS_UNBND);			break;		case NS_WACK_OPTREQ:			mtp_set_state(mtp, NS_IDLE);			break;		case NS_WACK_CRES:			/* FIXME: need to use sequence and token */			mtp_set_state(mtp, NS_DATA_XFER);			break;		case NS_WACK_DREQ6:		case NS_WACK_DREQ7:			/* FIXME: need to handle sequence numbers */		case NS_WACK_DREQ9:		case NS_WACK_DREQ10:		case NS_WACK_DREQ11:			mtp_disconnect(mtp);			mtp_set_state(mtp, NS_IDLE);			break;		default:			/* Note: if we are not in a WACK state we simply do not change state.  This 			   occurs normally when we are responding to a N_OPTMGMT_REQ in other than			   the NS_IDLE state. */			break;		}		mi_strlog(q, STRLOGRX, SL_TRACE, "<- N_OK_ACK");		putnext(mtp->rq, mp);		return (0);	}	return (-ENOBUFS);}/** * n_unitdata_ind: - issue a N_UNITDATA_IND primitive * @mtp: MTP private data * @q: active queue * @bp: message block to free upon success * @src: source address (or NULL) * @opt: options (or NULL) * @dp: user data */static inline fastcall __unlikely intn_unitdata_ind(struct mtp *mtp, queue_t *q, mblk_t *bp,	       struct mtp_addr *src, struct mtp_addr *dst, mblk_t *dp){	N_unitdata_ind_t *p;	mblk_t *mp;	size_t src_len = n_addr_size(src);	size_t dst_len = n_addr_size(dst);	size_t msg_len = sizeof(*p) + src_len + dst_len;	if (likely((mp = mi_allocb(q, msg_len, BPRI_MED)) != NULL)) {		if (likely(bcanputnext(mtp->rq, dp->b_band))) {			DB_TYPE(mp) = M_PROTO;			p = (typeof(p)) mp->b_wptr;			p->PRIM_type = N_UNITDATA_IND;			p->SRC_length = src_len;			p->SRC_offset = src_len ? sizeof(*p) : 0;			p->DEST_length = dst_len;			p->DEST_offset = dst_len ? sizeof(*p) + src_len : 0;			mp->b_wptr += sizeof(*p);			n_build_addr(src, mp->b_wptr);			mp->b_wptr += src_len;			n_build_addr(dst, mp->b_wptr);			mp->b_wptr += dst_len;			mp->b_cont = dp;			if (bp)				freeb(bp);			mi_strlog(q, STRLOGRX, SL_TRACE, "<- N_UNITDATA_IND");			putnext(mtp->rq, mp);

⌨️ 快捷键说明

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