📄 sctp_n.c
字号:
{ int rtn; ulong prim; sctp_t *sp = (sctp_t *)q->q_ptr; ulong oldstate = sp->i_state; switch ( (prim = *((ulong *)mp->b_rptr)) ) { case N_CONN_REQ: rtn = n_conn_req (sp, mp); break; case N_CONN_RES: rtn = n_conn_res (sp, mp); break; case N_DISCON_REQ: rtn = n_discon_req (sp, mp); break; case N_DATA_REQ: rtn = n_data_req (sp, mp); break; case N_EXDATA_REQ: rtn = n_exdata_req (sp, mp); break; case N_INFO_REQ: rtn = n_info_req (sp, mp); break; case N_BIND_REQ: rtn = n_bind_req (sp, mp); break; case N_UNBIND_REQ: rtn = n_unbind_req (sp, mp); break; case N_OPTMGMT_REQ: rtn = n_optmgmt_req(sp, mp); break; case N_RESET_REQ: rtn = n_reset_req (sp, mp); break; case N_RESET_RES: rtn = n_reset_res (sp, mp); break; default: rtn = -EOPNOTSUPP; break; } if ( rtn < 0 ) { seldom(); sp->i_state = oldstate; } return( rtn );}/* * ------------------------------------------------------------------------- * * M_DATA Handling * * ------------------------------------------------------------------------- */static intsctp_w_data(queue_t *q, mblk_t *mp){ sctp_t *sp = (sctp_t *)q->q_ptr; return n_write(sp, mp);}static intsctp_r_data(queue_t *q, mblk_t *mp){ sctp_t *sp = (sctp_t *)q->q_ptr; return sctp_recv_msg(sp, mp);}/* * ------------------------------------------------------------------------- * * M_ERROR Handling * * ------------------------------------------------------------------------- */static intsctp_r_error(queue_t *q, mblk_t *mp){ sctp_t *sp = (sctp_t *)q->q_ptr; rare(); return sctp_recv_err(sp, mp);}/* * ------------------------------------------------------------------------- * * M_FLUSH Handling * * ------------------------------------------------------------------------- * This is complete flush handling in both directions. Standard stuff. */static intsctp_m_flush(queue_t *q, mblk_t *mp, const uint8_t mflag, const uint8_t oflag){ if ( *mp->b_rptr & mflag ) { if ( *mp->b_rptr & FLUSHBAND ) flushband(q, mp->b_rptr[1], FLUSHALL); else flushq(q, FLUSHALL); if ( q->q_next ) { putnext(q, mp); return(1); } *mp->b_rptr &= ~mflag; } if ( *mp->b_rptr & oflag && !(mp->b_flag & MSGNOLOOP) ) { queue_t *oq = q->q_other; if ( *mp->b_rptr & FLUSHBAND ) flushband(oq, mp->b_rptr[1], FLUSHALL); else flushq(oq, FLUSHALL); if ( oq->q_next ) { mp->b_flag |= MSGNOLOOP; putnext(oq, mp); return(1); } } return(0);}static intsctp_w_flush(queue_t *q, mblk_t *mp){ return sctp_m_flush(q, mp, FLUSHW, FLUSHR);}/* * ------------------------------------------------------------------------- * * Other messages (e.g. M_IOCACK) * * ------------------------------------------------------------------------- */static intsctp_r_other(queue_t *q, mblk_t *mp){ sctp_t *sp = SCTP_PRIV(q); rare(); cmn_err(CE_WARN, "Unsupported block type %d on RD(q) %d\n", mp->b_datap->db_type, sp->cminor); putnext(q, mp); return(1);}static intsctp_w_other(queue_t *q, mblk_t *mp){ sctp_t *sp = SCTP_PRIV(q); rare(); cmn_err(CE_WARN, "Unsupported block type %d on WR(q) %d\n", mp->b_datap->db_type, sp->cminor); return(-EOPNOTSUPP);}/* * ========================================================================= * * STREAMS PUTQ and SRVQ routines * * ========================================================================= *//* * IP Read Put and Service */static INTsctp_rput(queue_t *q, mblk_t *mp){ int rtn; sctp_t *sp = (sctp_t *)q->q_ptr; ensure( q, return((INT)(-EFAULT)) ); ensure( sp, return((INT)(-EFAULT)) ); ensure( mp, return((INT)(-EFAULT)) ); if ( sctp_locked(sp) || (mp->b_datap->db_type < QPCTL && q->q_count) ) { seldom(); putq(q, mp); return(INT)(0); } switch ( mp->b_datap->db_type ) { case M_DATA: rtn = sctp_r_data (q, mp); break; case M_ERROR: rtn = sctp_r_error(q, mp); break; default: rtn = sctp_r_other(q, mp); break; } switch ( rtn ) { case 0: freemsg(mp); case 1: break; case 2: freeb(mp); break; case -ENOBUFS: /* should set up bufcall */ case -EBUSY: case -EAGAIN: case -ENOMEM: seldom(); if ( mp->b_datap->db_type >= QPCTL || canput(q) ) { putq(q, mp); return(INT)(0); } /* fall thru */ default: rare(); freemsg(mp); return(INT)(rtn); } sctp_cleanup_read(sp); /* deliver to user what is possible */ sctp_transmit_wakeup(sp); /* send to peer what is necessary */ return(INT)(0);}static INTsctp_rsrv(queue_t *q){ int rtn; mblk_t *mp; sctp_t *sp = (sctp_t *)q->q_ptr; ensure( q, return((INT)(-EFAULT)) ); ensure( sp, return((INT)(-EFAULT)) ); while ( (mp = getq(q)) ) { switch ( mp->b_datap->db_type ) { case M_DATA: rtn = sctp_r_data (q, mp); break; case M_ERROR: rtn = sctp_r_error(q, mp); break; default: rtn = sctp_r_other(q, mp); break; } switch ( rtn ) { case 0: freemsg(mp); case 1: continue; case 2: freeb(mp); continue; case -ENOBUFS: /* should set up bufcall */ case -EBUSY: case -EAGAIN: case -ENOMEM: seldom(); if ( mp->b_datap->db_type < QPCTL ) { putbq(q, mp); sctp_cleanup_read(sp); sctp_transmit_wakeup(sp); return(INT)(0); } default: rare(); freemsg(mp); continue; } } sctp_cleanup_read(sp); /* deliver to user what is possible */ sctp_transmit_wakeup(sp); /* reply to peer what is necessary */ return(INT)(0);}/* * NPI Write Put and Service */static INTsctp_wput(queue_t *q, mblk_t *mp){ int rtn; sctp_t *sp = (sctp_t *)q->q_ptr; ensure( q, return((INT)(-EFAULT)) ); ensure( sp, return((INT)(-EFAULT)) ); ensure( mp, return((INT)(-EFAULT)) ); if ( mp->b_datap->db_type < QPCTL && q->q_count ) { seldom(); putq(q, mp); return(INT)(0); } switch ( mp->b_datap->db_type ) { case M_DATA: rtn = sctp_w_data (q, mp); break; case M_PROTO: case M_PCPROTO: rtn = sctp_w_proto(q, mp); break; case M_FLUSH: rtn = sctp_w_flush(q, mp); break; default: rtn = sctp_w_other(q, mp); break; } switch ( rtn ) { case 0: freemsg(mp); case 1: break; case 2: freeb(mp); break; case -ENOBUFS: /* should set up bufcall */ case -EBUSY: case -EAGAIN: case -ENOMEM: seldom(); putq(q, mp); sctp_transmit_wakeup(sp); return(INT)(0); default: rare(); freemsg(mp); sctp_transmit_wakeup(sp); return(INT)(rtn); } sctp_transmit_wakeup(sp); /* send to peer what is necessary */ return(INT)(0);}static INTsctp_wsrv(queue_t *q){ int rtn; mblk_t *mp; sctp_t *sp = (sctp_t *)q->q_ptr; ensure( q, return((INT)(-EFAULT)) ); ensure( sp, return((INT)(-EFAULT)) ); while ( (mp = getq(q)) ) { switch ( mp->b_datap->db_type ) { case M_DATA: rtn = sctp_w_data (q, mp); break; case M_PROTO: case M_PCPROTO: rtn = sctp_w_proto(q, mp); break; case M_FLUSH: rtn = sctp_w_flush(q, mp); break; default: rtn = sctp_w_other(q, mp); break; } switch ( rtn ) { case 0: freemsg(mp); case 1: continue; case 2: freeb(mp); continue; case -ENOBUFS: /* should set up bufcall */ case -EBUSY: case -EAGAIN: case -ENOMEM: seldom(); if ( mp->b_datap->db_type < QPCTL ) { putbq(q, mp); sctp_transmit_wakeup(sp); return(INT)(0); } default: rare(); freemsg(mp); continue; } } sctp_transmit_wakeup(sp); return(INT)(0);}/* * ========================================================================= * * OPEN and CLOSE * * ========================================================================= */sctp_t *sctp_n_list = NULL;static intsctp_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *crp){ int cmajor = getmajor(*devp); int cminor = getminor(*devp); sctp_t *sp, **spp = &sctp_n_list; (void)crp; if ( q->q_ptr != NULL ) return(0); /* already open */ if ( sflag == MODOPEN || WR(q)->q_next ) { rare(); return(EIO); /* can't open as module */ } if ( !cminor ) sflag = CLONEOPEN; if ( sflag == CLONEOPEN ) cminor = 1; for ( ; *spp && (*spp)->cmajor < cmajor; spp = &(*spp)->next ); for ( ; *spp && cminor <= SCTP_NMINOR; spp = &(*spp)->next ) { ushort dminor = (*spp)->cminor; if ( cminor < dminor ) break; if ( cminor == dminor ) { if ( sflag != CLONEOPEN ) { rare(); return(ENXIO); /* requested device in use */ } cminor++; } } if ( cminor > SCTP_NMINOR ) { rare(); return(ENXIO); } *devp = makedevice(cmajor, cminor); if ( !(sp = sctp_alloc_priv(q, spp, cmajor, cminor, &n_ops)) ) { rare(); return(ENOMEM); } return(0);}static intsctp_close(queue_t *q, int flag, cred_t *crp){ (void)flag; (void)crp; sctp_free_priv(q); return(0);}/* * ========================================================================= * * LiS Module Initialization * * ========================================================================= */void sctp_n_init(void){ int cmajor; if ( (cmajor = lis_register_strdev(SCTP_N_CMAJOR, &sctp_info, SCTP_NMINOR, sctp_minfo.mi_idname)) < 0 ) { sctp_minfo.mi_idnum = 0; rare(); cmn_err(CE_NOTE, "sctp: couldn't register driver\n"); return; } sctp_minfo.mi_idnum = cmajor;}void sctp_n_term(void){ if ( sctp_minfo.mi_idnum ) { if ( (sctp_minfo.mi_idnum = lis_unregister_strdev(sctp_minfo.mi_idnum)) ) { sctp_minfo.mi_idnum = 0; rare(); cmn_err(CE_WARN, "sdt: couldn't unregister driver!\n"); } }};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -