📄 mtp_npi.c
字号:
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 + -