?? mtp_tpi.c
字號:
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 + -