📄 mtp_npi.c
字号:
}/* * N_RESET_REQ: * ------------------------------------------------------------------- */static inline fastcall __unlikely intn_reset_req(struct mtp *mtp, queue_t *q, mblk_t *mp){ (void) q; (void) mp; todo(("Accept resets with reason from the user\n")); rare(); return (0);}/* * N_RESET_RES: * ------------------------------------------------------------------- */static inline fastcall __unlikely intn_reset_res(struct mtp *mtp, queue_t *q, mblk_t *mp){ (void) q; (void) mp; /* ignore. if the user wishes to respond to our reset indications that's fine. */ rare(); return (0);}/* * ------------------------------------------------------------------------- * * 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 == N_CONS) 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 N_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 = N_BIND_REQ; break; case MTP_UNBIND_REQ: prim = N_UNBIND_REQ; break; case MTP_CONN_REQ: prim = N_CONN_REQ; if ((err = n_ok_ack(mtp, q, NULL, prim)) < 0) return (err); return n_conn_con(mtp, q, mp, 0, NULL, NULL, NULL); case MTP_DISCON_REQ: prim = N_DISCON_REQ; break; case MTP_ADDR_REQ: swerr(); prim = N_INFO_REQ; break; case MTP_INFO_REQ: swerr(); prim = N_INFO_REQ; break; case MTP_OPTMGMT_REQ: swerr(); prim = N_OPTMGMT_REQ; break; case MTP_TRANSFER_REQ: swerr(); prim = N_DATA_REQ; break; default: swerr(); prim = 0; break; } return n_ok_ack(mtp, q, mp, prim); 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 N_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 = N_BIND_REQ; break; case MTP_UNBIND_REQ: prim = N_UNBIND_REQ; break; case MTP_CONN_REQ: prim = N_CONN_REQ; break; case MTP_DISCON_REQ: prim = N_DISCON_REQ; break; case MTP_ADDR_REQ: swerr(); prim = N_INFO_REQ; break; case MTP_INFO_REQ: prim = N_INFO_REQ; break; case MTP_OPTMGMT_REQ: prim = N_OPTMGMT_REQ; break; case MTP_TRANSFER_REQ: swerr(); prim = N_DATA_REQ; break; default: swerr(); prim = 0; break; } switch (p->mtp_mtpi_error) { case MSYSERR: err = -p->mtp_unix_error; break; case MACCESS: err = NACCESS; break; case MBADADDR: err = NBADADDR; break; case MNOADDR: err = NNOADDR; break; case MBADPRIM: err = -EINVAL; break; case MOUTSTATE: err = NOUTSTATE; break; case MNOTSUPP: err = NNOTSUPPORT; break; case MBADFLAG: err = NBADFLAG; break; case MBADOPT: err = NBADOPT; break; default: swerr(); err = -EFAULT; break; } return n_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 n_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 n_addr_ack(mtp, q, mp, loc, rem); freemsg(mp); return (0); 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 NS_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.NSDU_size = p->mtp_msu_size; mtp->prot.NIDU_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 = NS_UNBND; break; case MTPS_WACK_BREQ: /* 1UL */ mtp->prot.CURRENT_state = NS_WACK_BREQ; break; case MTPS_IDLE: /* 2UL */ mtp->prot.CURRENT_state = NS_IDLE; break; case MTPS_WACK_CREQ: /* 3UL */ mtp->prot.CURRENT_state = NS_WCON_CREQ; break; case MTPS_WCON_CREQ: /* 4UL */ mtp->prot.CURRENT_state = NS_WCON_CREQ; break; case MTPS_CONNECTED: /* 5UL */ mtp->prot.CURRENT_state = NS_DATA_XFER; break; case MTPS_WACK_UREQ: /* 6UL */ mtp->prot.CURRENT_state = NS_WACK_UREQ; break; case MTPS_WACK_DREQ6: /* 7UL */ mtp->prot.CURRENT_state = NS_WACK_DREQ6; break; case MTPS_WACK_DREQ9: /* 8UL */ mtp->prot.CURRENT_state = NS_WACK_DREQ9; break; case MTPS_WACK_OPTREQ: /* 9UL */ mtp->prot.CURRENT_state = NS_WACK_OPTREQ; break; case MTPS_WREQ_ORDREL: /* 10UL */ mtp->prot.CURRENT_state = NS_WRES_RIND; break; case MTPS_WIND_ORDREL: /* 11UL */ mtp->prot.CURRENT_state = NS_WCON_RREQ; break; case MTPS_WRES_CIND: /* 12UL */ mtp->prot.CURRENT_state = NS_WRES_CIND; break; case MTPS_UNUSABLE: /* 0xffffffffUL */ mtp->prot.CURRENT_state = NS_NOSTATES; break; default: mtp->prot.CURRENT_state = NS_NOSTATES; break; } switch (p->mtp_serv_type) { case M_COMS: mtp->prot.SERV_type = N_CONS; mtp->prot.CDATA_size = p->mtp_msu_size; mtp->prot.DDATA_size = p->mtp_msu_size; break; case M_CLMS: mtp->prot.SERV_type = N_CLNS; mtp->prot.CDATA_size = -2; mtp->prot.DDATA_size = -2; break; default: swerr(); break; } if (!first) return n_info_ack(mtp, q, mp); error: freemsg(mp); return (0); badaddr: mi_strlog(q, 0, SL_ERROR, "bad address or incorrect format"); goto error; protoshort: mi_strlog(q, 0, SL_ERROR, "primitive too short"); goto error;}/** * mtp_optmgmt_ack: - process MTP_OPTMGMT_ACK primitive * @mtp: private structure * @q: active queue * @mp: the message */static inline fastcall __unlikely intmtp_optmgmt_ack(struct mtp *mtp, queue_t *q, mblk_t *mp){ swerr(); return (-EFAULT);}/** * mtp_transfer_ind: - translate MTP_TRANSFER_IND into N_UNITDATA_IND or N_OPTDATA_IND * @mtp: MTP private structure * @q: active queue (read queue) * @mp: the message */static noinline fastcall __unlikely intmtp_transfer_ind(struct mtp *mtp, queue_t *q, mblk_t *mp){ struct MTP_transfer_ind *p = (typeof(p)) mp->b_rptr; struct mtp_addr *src = NULL; if (mp->b_cont == NULL) goto baddata; if (mp->b_wptr < mp->b_rptr + sizeof(*p)) goto protoshort; if (mtp_chk_state(mtp, NSF_WACK)) goto wait; switch (mtp->prot.SERV_type) { case N_CONS: if (mtp_not_state(mtp, (NSF_WCON_RREQ | NSF_DATA_XFER))) goto outstate; return n_data_ind(mtp, q, mp, 0, mp->b_cont); case N_CLNS: if (mtp_not_state(mtp, (NSF_IDLE | NSF_WACK_UREQ))) goto outstate; if (mp->b_wptr < mp->b_rptr + p->mtp_srce_offset + p->mtp_srce_length) goto badaddr; if (p->mtp_srce_length) { if (p->mtp_srce_length < sizeof(*src)) goto badaddr2; src = (typeof(src)) (mp->b_rptr + p->mtp_srce_offset); } mp->b_cont->b_band = mp->b_band; return n_unitdata_ind(mtp, q, mp, src, &mtp->src, mp->b_cont); default: break; } error: freemsg(mp); return (0); outstate: mi_strlog(q, 0, SL_ERROR, "data received in incorrect state %u", mtp_get_state(mtp)); goto error; badaddr2: mi_strlog(q, 0, SL_ERROR, "address of incorrect length"); goto error; badaddr: mi_strlog(q, 0, SL_ERROR, "bad address or incorrect format"); goto error; protoshort: mi_strlog(q, 0, SL_ERROR, "primitive too short"); goto error; baddata: mi_strlog(q, 0, SL_ERROR, "invalid amount of user data"); goto error; wait: mi_strlog(q, 0, SL_ERROR, "primitive received in wack state %u", mtp_get_state(mtp)); qenable(q); return (-EAGAIN);}/** * mtp_pause_ind: - process an MTP_PAUSE_IND primitive * @mtp: private structure * @q: active queue * @mp: the message * * Translate MTP_PAUSE_IND into N_UDERROR_IND or N_DISCON_IND. */static inline fastcall __unlikely intmtp_pause_ind(struct mtp *mtp, queue_t *q, mblk_t *mp){ struct MTP_pause_ind *p = (typeof(p)) mp->b_rptr; struct mtp_addr *dst = NULL; if (mp->b_wptr < mp->b_rptr + sizeof(*p)) goto protoshort; if (mtp_chk_state(mtp, NSF_WACK)) goto wait; switch (mtp->prot.SERV_type) { case N_CONS: if (mtp_not_state(mtp, (NSF_DATA_XFER | NSF_WCON_RREQ))) goto outstate; return n_discon_ind(mtp, q, mp, N_PROVIDER, N_MTP_DEST_PROHIBITED, 0, NULL, mp->b_cont); case N_CLNS: if (mtp_not_state(mtp, NSF_IDLE)) goto outstate; if (mp->b_wptr < mp->b_rptr + p->mtp_addr_offset + p->mtp_addr_length) goto badaddr; if (p->mtp_addr_length) { if (p->mtp_addr_length < sizeof(*dst)) goto badaddr; dst = (typeof(dst)) (mp->b_rptr + p->mtp_addr_offset); } return n_uderror_ind(mtp, q, mp, dst, mp->b_cont, N_MTP_DEST_PROHIBITED); default: goto notsupp; } goto outstate; error: freemsg(mp); return (0); outstate: mi_strlog(q, 0, SL_ERROR, "primitive received in incorrect state %u", mtp_get_state(mtp)); goto error; notsupp: mi_strlog(q, 0, SL_ERROR, "invalid service type %d", (int) mtp->prot.SERV_type); goto error; badaddr: mi_strlog(q, 0, SL_ERROR, "invalid or bad address format"); goto error; protoshort: mi_strlog(q, 0, SL_ERROR, "protocol block too short"); goto error; wait: mi_strlog(q, 0, SL_ERROR, "primitive received in wack state %u", mtp_get_state(mtp)); qenable(q); return (-EAGAIN);}/** * mtp_resume_ind: - process an MTP_RESUME_IND primitive * @mtp: private structure * @q: active queue * @mp: the message * * For
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -