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

📄 mtp_tpi.c

📁 OpenSS7 This the fourth public release of the OpenSS7 Master Package. See README in the release for
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (!dst.si || !dst.pc)		goto badaddr;	if (dst.si < 3 && mtp->cred.cr_uid != 0)		goto acces;	if (dst.si != mtp->src.si)		goto badaddr;	if (t_parse_opts(&opts, mp->b_rptr + p->OPT_offset, p->OPT_length))		goto badopt;	fixme(("Handle options correctly\n"));	return mtp_transfer_req(mtp, q, mp, &dst, mtp->options.mp, mtp->options.sls, mp->b_cont);      badopt:	mi_strlog(q, 0, SL_TRACE, "bad options");	goto error;      acces:	mi_strlog(q, 0, SL_TRACE, "no permission to address");	goto error;      badaddr:	mi_strlog(q, 0, SL_TRACE, "bad destination address");	goto error;      noaddr:	mi_strlog(q, 0, SL_TRACE, "could not allocate address");	goto error;      baddata:	mi_strlog(q, 0, SL_TRACE, "bad data size %lu", (ulong) dlen);	goto error;      outstate:	mi_strlog(q, 0, SL_TRACE, "would place i/f out of state");	goto error;      badprim:	mi_strlog(q, 0, SL_TRACE, "invalid primitive format");	goto error;      notsupport:	mi_strlog(q, 0, SL_TRACE, "primitive not supported for T_COTS or T_COTS_ORD");	goto error;      error:	return m_error(mtp, q, mp, EPROTO);}/** * t_optmgmt_req: - process T_OPTMGMT_REQ primitive * @mtp: private structure * @q: active queue * @mp: the message */static inline fastcall __unlikely intt_optmgmt_req(struct mtp *mtp, queue_t *q, mblk_t *mp){	int err = 0;	const struct T_optmgmt_req *p = (typeof(p)) mp->b_rptr;	struct mtp_opts opts = { 0L, NULL, };	if (mp->b_wptr < mp->b_rptr + sizeof(*p))		goto badprim;	if (mp->b_wptr < mp->b_rptr + p->OPT_offset + p->OPT_length)		goto badprim;#ifdef TS_WACK_OPTREQ	if (mtp_get_state(mtp) == TS_IDLE)		mtp_set_state(mtp, TS_WACK_OPTREQ);#endif	if (t_parse_opts(&opts, mp->b_rptr + p->OPT_offset, p->OPT_length))		goto badopt;	switch (p->MGMT_flags) {	case T_CHECK:		err = mtp_opt_check(mtp, &opts);		break;	case T_NEGOTIATE:		if (!opts.flags)			mtp_opt_default(mtp, &opts);		else if ((err = mtp_opt_check(mtp, &opts)))			break;		err = mtp_opt_negotiate(mtp, &opts);		break;	case T_DEFAULT:		err = mtp_opt_default(mtp, &opts);		break;	case T_CURRENT:		err = mtp_opt_current(mtp, &opts);		break;	default:		goto badflag;	}	if (err)		goto provspec;	return mtp_optmgmt_req(mtp, q, mp, &opts, p->MGMT_flags);      provspec:	err = err;	mi_strlog(q, 0, SL_TRACE, "provider specific");	goto error;      badflag:	err = TBADFLAG;	mi_strlog(q, 0, SL_TRACE, "bad options flags");	goto error;      badopt:	err = TBADOPT;	mi_strlog(q, 0, SL_TRACE, "bad options");	goto error;      badprim:	err = -EMSGSIZE;	mi_strlog(q, 0, SL_TRACE, "invalid primitive format");	goto error;      error:	return t_error_ack(mtp, q, mp, p->PRIM_type, err);}/** * t_ordrel_req: - process T_ORDREL_REQ primitive * @mtp: private structure * @q: active queue * @mp: the message */static inline fastcall __unlikely intt_ordrel_req(struct mtp *mtp, queue_t *q, mblk_t *mp){	const struct T_ordrel_req *p = (typeof(p)) mp->b_rptr;	if (mtp->prot.SERV_type != T_COTS_ORD)		goto notsupport;	if ((1 << mtp_get_state(mtp)) & ~(TSF_DATA_XFER | TSF_WREQ_ORDREL))		goto outstate;	switch (mtp_get_state(mtp)) {	case TS_DATA_XFER:		mtp_set_state(mtp, TS_WIND_ORDREL);		break;	case TS_WREQ_ORDREL:		goto error;	}	return t_error_ack(mtp, q, mp, T_ORDREL_REQ, TNOTSUPPORT);      outstate:	mi_strlog(q, 0, SL_TRACE, "would place i/f out of state");	goto error;      notsupport:	mi_strlog(q, 0, SL_TRACE, "primitive not supported for T_CLTS or T_COTS");	goto error;      error:	return m_error(mtp, q, mp, EPROTO);}/** * t_optdata_req: - process T_OPTDATA_REQ primitive * @mtp: private structure * @q: active queue * @mp: the message */static inline fastcall __unlikely intt_optdata_req(struct mtp *mtp, queue_t *q, mblk_t *mp){	int err;	const struct T_optdata_req *p = (typeof(p)) mp->b_rptr;	struct mtp_opts opts = { 0L, NULL, };	if (mtp->prot.SERV_type == T_CLTS)		goto notsupport;	if (mtp_get_state(mtp) == TS_IDLE)		goto discard;	if (mp->b_wptr < mp->b_rptr + sizeof(*p)	    || mp->b_wptr < mp->b_rptr + p->OPT_offset + p->OPT_length)		goto einval;	if ((1 << mtp_get_state(mtp)) & ~(TSF_DATA_XFER | TSF_WREQ_ORDREL))		goto outstate;	if (p->DATA_flag & T_ODF_EX || p->DATA_flag & T_ODF_MORE)		goto notsupport;	if (t_parse_opts(&opts, mp->b_rptr + p->OPT_offset, p->OPT_length))		goto badopt;	fixme(("Handle options correctly\n"));	return mtp_transfer_req(mtp, q, mp, &mtp->dst, mtp->options.mp, mtp->options.sls,				mp->b_cont);      badopt:	err = TBADOPT;	mi_strlog(q, 0, SL_TRACE, "bad options");	goto error;      outstate:	err = TOUTSTATE;	mi_strlog(q, 0, SL_TRACE, "would place i/f out of state");	goto error;      einval:	mi_strlog(q, 0, SL_TRACE, "invalid primitive format");	return m_error(mtp, q, mp, EPROTO);      discard:	mi_strlog(q, 0, SL_TRACE, "ignore in idle state");	return (0);      notsupport:	err = TNOTSUPPORT;	mi_strlog(q, 0, SL_TRACE, "primitive not supported for T_CLTS");	goto error;      error:	return t_error_ack(mtp, q, mp, p->PRIM_type, err);}#ifdef T_ADDR_REQ/** * t_addr_req: - process T_ADDR_REQ primitive * @mtp: private structure * @q: active queue * @mp: the message */static inline fastcall __unlikely intt_addr_req(struct mtp *mtp, queue_t *q, mblk_t *mp){	const struct T_addr_req *p = (typeof(p)) mp->b_rptr;	(void) mp;	return mtp_addr_req(mtp, q, mp);}#endif#ifdef T_CAPABILITY_REQ/** * t_capability_req: - process T_CAPABILITY_REQ primitive * @mtp: private structure * @q: active queue * @mp: the message */static inline fastcall __unlikely intt_capability_req(struct mtp *mtp, queue_t *q, mblk_t *mp){	const struct T_capability_req *p = (typeof(p)) mp->b_rptr;	if (mp->b_wptr < mp->b_rptr + sizeof(*p))		goto einval;	return t_capability_ack(mtp, q, mp, p->CAP_bits1);      einval:	mi_strlog(q, 0, SL_TRACE, "invalid primitive format");	return t_error_ack(mtp, q, mp, p->PRIM_type, -EINVAL);}#endif/* *  ------------------------------------------------------------------------- * *  Primitives received from below. * *  ------------------------------------------------------------------------- *//** * mtp_data: - process M_DATA message * @mtp: private structure * @q: active queue * @mp: the message */static inline fastcall __hot_in intmtp_data(struct mtp *mtp, queue_t *q, mblk_t *mp){	if (mtp->prot.SERV_type == T_COTS)		return (QR_PASSALONG);	swerr();	return (-EFAULT);}/** * mtp_ok_ack: - process MTP_OK_ACK primitive * @mtp: private structure * @q: active queue * @mp: the message * * Simply translate the MTP_OK_ACK into a T_OK_ACK. */static inline fastcall __unlikely intmtp_ok_ack(struct mtp *mtp, queue_t *q, mblk_t *mp){	int err;	mtp_ulong prim;	struct MTP_ok_ack *p = (typeof(p)) mp->b_rptr;	if (mp->b_wptr < mp->b_rptr + sizeof(*p))		goto efault;	switch (p->mtp_correct_prim) {	case MTP_BIND_REQ:		swerr();		prim = T_BIND_REQ;		break;	case MTP_UNBIND_REQ:		prim = T_UNBIND_REQ;		break;	case MTP_CONN_REQ:		prim = T_CONN_REQ;		if ((err = t_ok_ack(mtp, q, NULL, prim, 0, 0)) < 0)			return (err);		return t_conn_con(mtp, q, mp, NULL, NULL, NULL);	case MTP_DISCON_REQ:		prim = T_DISCON_REQ;		break;	case MTP_ADDR_REQ:		swerr();		prim = T_ADDR_REQ;		break;	case MTP_INFO_REQ:		swerr();		prim = T_INFO_REQ;		break;	case MTP_OPTMGMT_REQ:		swerr();		prim = T_OPTMGMT_REQ;		break;	case MTP_TRANSFER_REQ:		swerr();		prim = T_OPTDATA_REQ;		break;	default:		swerr();		prim = 0;		break;	}	return t_ok_ack(mtp, q, mp, prim, 0, 0);      efault:	mi_strlog(q, 0, SL_ERROR, "invalid primitive from below");	return (-EFAULT);}/** * mtp_error_ack: - process MTP_ERROR_ACK primitive * @mtp: private structure * @q: active queue * @mp: the message * * Simply translate the MTP_ERROR_ACK into a T_ERROR_ACK. */static inline fastcall __unlikely intmtp_error_ack(struct mtp *mtp, queue_t *q, mblk_t *mp){	int err;	mtp_ulong prim;	struct MTP_error_ack *p = (typeof(p)) mp->b_rptr;	if (mp->b_wptr < mp->b_rptr + sizeof(*p))		goto efault;	switch (p->mtp_primitive) {	case MTP_BIND_REQ:		prim = T_BIND_REQ;		break;	case MTP_UNBIND_REQ:		prim = T_UNBIND_REQ;		break;	case MTP_CONN_REQ:		prim = T_CONN_REQ;		break;	case MTP_DISCON_REQ:		prim = T_DISCON_REQ;		break;	case MTP_ADDR_REQ:		swerr();		prim = T_ADDR_REQ;		break;	case MTP_INFO_REQ:		prim = T_INFO_REQ;		break;	case MTP_OPTMGMT_REQ:		prim = T_OPTMGMT_REQ;		break;	case MTP_TRANSFER_REQ:		swerr();		prim = T_OPTDATA_REQ;		break;	default:		swerr();		prim = 0;		break;	}	switch (p->mtp_mtpi_error) {	case MSYSERR:		err = -p->mtp_unix_error;		break;	case MACCESS:		err = TACCES;		break;	case MBADADDR:		err = TBADADDR;		break;	case MNOADDR:		err = TNOADDR;		break;	case MBADPRIM:		err = -EINVAL;		break;	case MOUTSTATE:		err = TOUTSTATE;		break;	case MNOTSUPP:		err = TNOTSUPPORT;		break;	case MBADFLAG:		err = TBADF;		break;	case MBADOPT:		err = TBADOPT;		break;	default:		swerr();		err = -EFAULT;		break;	}	return t_error_ack(mtp, q, mp, prim, err);      efault:	mi_strlog(q, 0, SL_ERROR, "invalid primitive from below");	return (-EFAULT);}/** * mtp_bind_ack: - process MTP_BIND_ACK primitive * @mtp: private structure * @q: active queue * @mp: the message * * Translate the MTP_BIND_ACK into a T_BIND_ACK. */static inline fastcall __unlikely intmtp_bind_ack(struct mtp *mtp, queue_t *q, mblk_t *mp){	struct MTP_bind_ack *p = (typeof(p)) mp->b_rptr;	struct mtp_addr *add = NULL;	if (mp->b_wptr < mp->b_rptr + sizeof(*p))		goto efault;	if (mp->b_wptr < mp->b_rptr + p->mtp_addr_offset + p->mtp_addr_length)		goto efault;	if (p->mtp_addr_length == sizeof(*add))		add = (typeof(add)) (mp->b_rptr + p->mtp_addr_offset);	return t_bind_ack(mtp, q, mp, add, 0);      efault:	mi_strlog(q, 0, SL_ERROR, "invalid primitive from below");	return (-EFAULT);}/** * mtp_addr_ack: - process MTP_ADDR_ACK primitive * @mtp: private structure * @q: active queue * @mp: the message * * Simply translate MTP_ADDR_ACK to T_ADDR_ACK. */static inline fastcall __unlikely intmtp_addr_ack(struct mtp *mtp, queue_t *q, mblk_t *mp){	struct MTP_addr_ack *p = (typeof(p)) mp->b_rptr;	struct mtp_addr *loc = NULL, *rem = NULL;	if (mp->b_wptr < mp->b_rptr + sizeof(*p))		goto efault;	if (mp->b_wptr < mp->b_rptr + p->mtp_loc_offset + p->mtp_loc_length)		goto efault;	if (mp->b_wptr < mp->b_rptr + p->mtp_rem_offset + p->mtp_rem_length)		goto efault;	if (p->mtp_loc_length == sizeof(*loc))		loc = (typeof(loc)) (mp->b_rptr + p->mtp_loc_offset);	if (p->mtp_rem_length == sizeof(*rem))		rem = (typeof(rem)) (mp->b_rptr + p->mtp_rem_offset);	return t_addr_ack(mtp, q, mp, loc, rem);      efault:	mi_strlog(q, 0, SL_ERROR, "invalid primitive from below");	return (-EFAULT);}/** * mtp_info_ack: - process MTP_INFO_ACK primitive * @mtp: private structure * @q: active queue * @mp: the message * * Simply translate MTP_INFO_ACK to T_INFO_ACK, unless this is the very first info ack to our * MTP_INFO_REQ issues from the mtp_qopen() procedure.  This can be identified by the fact that the * current state is TS_NOSTATES. */static inline fastcall __unlikely intmtp_info_ack(struct mtp *mtp, queue_t *q, mblk_t *mp){	struct MTP_info_ack *p = (typeof(p)) mp->b_rptr;	int first = (mtp->prot.CURRENT_state == -1U);	if (mp->b_wptr < mp->b_rptr + sizeof(*p))		goto protoshort;	if (mp->b_wptr < mp->b_rptr + p->mtp_addr_offset + p->mtp_addr_length)		goto badaddr;	mtp->prot.TSDU_size = p->mtp_msu_size;	mtp->prot.TIDU_size = p->mtp_msu_size;	mtp->prot.ADDR_size = p->mtp_addr_size;	switch (p->mtp_current_state) {	case MTPS_UNBND:	/* 0UL */		mtp->prot.CURRENT_state = TS_UNBND;		break;	case MTPS_WACK_BREQ:	/* 1UL */		mtp->prot.CURRENT_state = TS_WACK_BREQ;		break;	case MTPS_IDLE:	/* 2UL */		mtp->prot.CURRENT_state = TS_IDLE;		break;	case MTPS_WACK_CREQ:	/* 3UL */		mtp->prot.CURRENT_state = TS_WACK_CREQ;		break;	case MTPS_WCON_CREQ:	/* 4UL */		mtp->prot.CURRENT_state = TS_WCON_CREQ;		break;	case MTPS_CONNECTED:	/* 5UL */		mtp->prot.CURRENT_state = TS_DATA_XFER;		break;	case MTPS_WACK_UREQ:	/* 6UL */		mtp->prot.CURRENT_state = TS_WACK_UREQ;		break;	case MTPS_WACK_DREQ6:	/* 7UL */		mtp->prot.CURRENT_state = TS_WACK_DRE

⌨️ 快捷键说明

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