void handle_dump(queue_t *q, mblk_t *mp) { struct ctrl_args *ctrl_args; struct ctrl_device *ctrlfd; minor_t minor; int sum; unsigned char *buf; if ((mp->b_cont = allocb(MAXPRINTBUF, BPRI_MED)) == NULL) { printf("handle_ctrl: out of message blocks\n"); qreply(q, mp); return; } buf = DB_BASE(mp->b_cont); sum = rpc_dump(buf, buf + MAXPRINTBUF); sum += port_dump(buf + sum, buf + MAXPRINTBUF); sum += kid_dump(buf + sum, buf + MAXPRINTBUF); sum += flip_netdump(buf + sum, buf + MAXPRINTBUF); sum += int_dump(buf + sum, buf + MAXPRINTBUF); sum += adr_dump(buf + sum, buf + MAXPRINTBUF); sum += ff_dump(buf + sum, buf + MAXPRINTBUF); mp->b_cont->b_rptr = DB_BASE(mp->b_cont); mp->b_cont->b_wptr = mp->b_cont->b_rptr + sum; ctrl_args = (struct ctrl_args *) DB_BASE(mp); ctrl_args->ctrl_status = sum; mp->b_rptr = DB_BASE(mp); mp->b_wptr = mp->b_rptr + sizeof(struct ctrl_args); DB_TYPE(mp) = M_PROTO; qreply(q, mp); }
static int logi_wput(queue_t *q, mblk_t *mp) { struct iocblk *iocbp; struct strmseinfo *logiptr; #ifdef LOGI_DEBUG if (logi_debug) printf("logi_wput:entered\n"); #endif logiptr = q->q_ptr; if (logiptr == 0) { freemsg(mp); #ifdef LOGI_DEBUG if (logi_debug) printf("logi_wput:logiptr == NULL\n"); #endif return (0); } iocbp = (struct iocblk *)mp->b_rptr; switch (mp->b_datap->db_type) { case M_FLUSH: #ifdef LOGI_DEBUG if (logi_debug) printf("logi_wput:M_FLUSH\n"); #endif if (*mp->b_rptr & FLUSHW) flushq(q, FLUSHDATA); qreply(q, mp); break; case M_IOCTL: #ifdef LOGI_DEBUG if (logi_debug) printf("logi_wput:M_IOCTL\n"); #endif mp->b_datap->db_type = M_IOCNAK; iocbp->ioc_rval = 0; iocbp->ioc_error = EINVAL; qreply(q, mp); break; case M_IOCDATA: #ifdef LOGI_DEBUG if (logi_debug) printf("logi_wput:M_IOCDATA\n"); #endif mp->b_datap->db_type = M_IOCNAK; iocbp->ioc_rval = 0; iocbp->ioc_error = EINVAL; qreply(q, mp); break; default: freemsg(mp); break; } #ifdef LOGI_DEBUG if (logi_debug) printf("logi_wput:leaving\n"); #endif return (0); }
/* * generic query lookup. The query is of one of the following * forms: * * attr1=val1 attr2=val2 attr3=val3 ... * * returns the matching tuple * * ipinfo attr=val attr1 attr2 attr3 ... * * is like ipinfo and returns the attr{1-n} * associated with the ip address. */ static char *genquery(struct mfile *mf, char *query) { int i, n; char *p; char *attr[Maxattr]; char *val[Maxattr]; struct ndbtuple *t; struct ndbs s; n = getfields(query, attr, COUNT_OF(attr), 1, " "); if (n == 0) return "bad query"; if (strcmp(attr[0], "ipinfo") == 0) return ipinfoquery(mf, attr, n); /* parse pairs */ for (i = 0; i < n; i++) { p = strchr(attr[i], '='); if (p == 0) return "bad query"; *p++ = 0; val[i] = p; } /* give dns a chance */ if ((strcmp(attr[0], "dom") == 0 || strcmp(attr[0], "ip") == 0) && val[0]) { t = dnsiplookup(val[0], &s); if (t) { if (qmatch(t, attr, val, n)) { qreply(mf, t); ndbfree(t); return 0; } ndbfree(t); } } /* first pair is always the key. It can't be a '*' */ t = ndbsearch(db, &s, attr[0], val[0]); /* search is the and of all the pairs */ while (t) { if (qmatch(t, attr, val, n)) { qreply(mf, t); ndbfree(t); return 0; } ndbfree(t); t = ndbsnext(&s, attr[0], val[0]); } return "no match"; }
/* * Flush handle for read side stream * * Requires lock ( M: mandatory P: prohibited A: allowed * -. uinst_t->lock : M [RW_READER] * -. uinst_t->u_lock : P * -. uinst_t->l_lock : P * -. uinst_t->c_lock : P */ void oplmsu_rcmn_flush_hndl(queue_t *q, mblk_t *mp) { queue_t *dst_queue = NULL; ctrl_t *ctrl; ASSERT(RW_READ_HELD(&oplmsu_uinst->lock)); if (*mp->b_rptr & FLUSHR) { /* Remove only data messages from read queue */ flushq(q, FLUSHDATA); } mutex_enter(&oplmsu_uinst->c_lock); if ((ctrl = oplmsu_uinst->user_ctrl) != NULL) { dst_queue = RD(ctrl->queue); mutex_exit(&oplmsu_uinst->c_lock); if (dst_queue != NULL) { putq(dst_queue, mp); } else { if (*mp->b_rptr & FLUSHW) { flushq(WR(q), FLUSHDATA); *mp->b_rptr &= ~FLUSHR; rw_exit(&oplmsu_uinst->lock); OPLMSU_TRACE(q, mp, MSU_TRC_LO); qreply(q, mp); rw_enter(&oplmsu_uinst->lock, RW_READER); } else { freemsg(mp); } } } else { mutex_exit(&oplmsu_uinst->c_lock); if (*mp->b_rptr & FLUSHW) { flushq(WR(q), FLUSHDATA); *mp->b_rptr &= ~FLUSHR; rw_exit(&oplmsu_uinst->lock); OPLMSU_TRACE(q, mp, MSU_TRC_LO); qreply(q, mp); rw_enter(&oplmsu_uinst->lock, RW_READER); } else { freemsg(mp); } } }
/* * Flush handle for write side stream * * Requires Lock (( M: Mandatory, P: Prohibited, A: Allowed )) * -. uinst_t->lock : M [RW_READER or RW_WRITER] * -. uinst_t->u_lock : P * -. uinst_t->l_lock : P * -. uinst_t->c_lock : P */ void oplmsu_wcmn_flush_hndl(queue_t *q, mblk_t *mp, krw_t rw) { queue_t *dst_queue = NULL; ASSERT(RW_LOCK_HELD(&oplmsu_uinst->lock)); if (*mp->b_rptr & FLUSHW) { /* Write side */ flushq(q, FLUSHDATA); } dst_queue = oplmsu_uinst->lower_queue; if (dst_queue == NULL) { if (*mp->b_rptr & FLUSHR) { flushq(RD(q), FLUSHDATA); *mp->b_rptr &= ~FLUSHW; rw_exit(&oplmsu_uinst->lock); OPLMSU_TRACE(q, mp, MSU_TRC_UO); qreply(q, mp); rw_enter(&oplmsu_uinst->lock, rw); } else { freemsg(mp); } } else { putq(WR(dst_queue), mp); } }
/* * ------------------------------------------------------------------------- * * M_FLUSH Handling * * ------------------------------------------------------------------------- */ STATIC inline void sscop_w_flush(queue_t *q, mblk_t *mp) { if (*mp->b_rptr & FLUSHW) { if (*mp->b_rptr & FLUSHBAND) flushband(q, mp->b_rptr[1], FLUSHDATA); else flushq(q, FLUSHDATA); if (q - q_next) { putnext(q, mp); return; } *mp->b_rptr &= ~FLUSHW; } if (*mp->b_rptr & FLUSHR) { if (*mp->b_rptr & FLUSHBAND) flushband(RD(q), mp->b_rptr[1], FLUSHDATA); else flushq(RD(q), FLUSHDATA); qreply(q, mp); return; } if (q->q_next) { putnext(q, mp); return; } }
/* * N_DATA_IND * ------------------------------------------------------------------------- * This is translated into SUA messages and fed to the state machines. */ static int n_data_ind(queue_t *q, mblk_t *pdu) { int err; mblk_t *mp; N_data_ind_t *p; p = (N_data_ind_t *) pdu->b_rptr; if (p->DATA_xfer_flags & N_MORE_DATA_FLAG) { /* aaargh! */ /* give it to management */ if ((err = lm_event_ind(q, pdu))) return (err); if ((err = m3ua_sp_down(q))) return (err); qdisable(q); return (0); } if (p->DATA_xfer_flags & N_RC_FLAG) { /* need to send receipt confirmation */ if (!(mp = n_datack_ind())) return (-ENOBUFS); qreply(q, mp); } /* only need the M_DATA block */ mp = pdu->b_cont; mp->b_band = 0; freeb(pdu); if ((err = m3ua_recv_msg(q, mp))) return (err); return (0); }
/* * LMI_INFO_ACK * ----------------------------------- */ STATIC INLINE int lmi_info_ack(queue_t *q, long state, caddr_t ppa_ptr, size_t ppa_len) { mblk_t *mp; lmi_info_ack_t *p; if ((mp = ss7_allocb(q, sizeof(*p) + ppa_len, BPRI_MED))) { mp->b_datap->db_type = M_PCPROTO; p = (typeof(p)) mp->b_wptr; p->lmi_primitive = LMI_INFO_ACK; p->lmi_version = 1; p->lmi_state = state; p->lmi_max_sdu = 8; p->lmi_min_sdu = 8; p->lmi_header_len = 0; p->lmi_ppa_style = LMI_STYLE1; p->lmi_ppa_length = ppa_len; p->lmi_ppa_offset = sizeof(*p); p->lmi_prov_state = SDL_CONNECTED; p->lmi_prov_flags = SDL_RX_DIRECTION | SDL_TX_DIRECTION; mp->b_wptr += sizeof(*p); bcopy(ppa_ptr, mp->b_wptr, ppa_len); mp->b_wptr += ppa_len; qreply(q, mp); return (QR_DONE); } rare(); return (-ENOBUFS); }
static int mouse8042_process_msg(queue_t *q, mblk_t *mp, struct mouse_state *state) { struct iocblk *iocbp; int rv = 0; iocbp = (struct iocblk *)mp->b_rptr; switch (mp->b_datap->db_type) { case M_FLUSH: if (*mp->b_rptr & FLUSHW) { flushq(q, FLUSHDATA); *mp->b_rptr &= ~FLUSHW; } if (*mp->b_rptr & FLUSHR) { qreply(q, mp); } else freemsg(mp); break; case M_IOCTL: mouse8042_iocnack(q, mp, iocbp, EINVAL, 0); break; case M_IOCDATA: mouse8042_iocnack(q, mp, iocbp, EINVAL, 0); break; case M_DATA: rv = mouse8042_process_data_msg(q, mp, state); break; default: freemsg(mp); break; } return (rv); }
void miocnak(queue_t *pWriteQueue, mblk_t *pMBlk, int cbData, int iErr) { struct iocblk *pIOCBlk = (struct iocblk *)pMBlk->b_rptr; pMBlk->b_datap->db_type = M_IOCNAK; pIOCBlk->ioc_count = cbData; pIOCBlk->ioc_error = iErr ? iErr : EINVAL; pIOCBlk->ioc_rval = 0; qreply(pWriteQueue, pMBlk); }
void miocack(queue_t *pWriteQueue, mblk_t *pMBlk, int cbData, int rc) { struct iocblk *pIOCBlk = (struct iocblk *)pMBlk->b_rptr; pMBlk->b_datap->db_type = M_IOCACK; pIOCBlk->ioc_count = cbData; pIOCBlk->ioc_rval = rc; pIOCBlk->ioc_error = 0; qreply(pWriteQueue, pMBlk); }
/* * vml_iocdata() - * Handle the M_IOCDATA messages associated with * a request to validate a module list. */ static void vml_iocdata( queue_t *qp, /* pointer to write queue */ mblk_t *mp) /* message pointer */ { long i; int nmods; struct copyresp *csp; struct str_mlist *lp; STRUCT_HANDLE(str_list, slp); struct saddev *sadp; csp = (struct copyresp *)mp->b_rptr; if (csp->cp_rval) { /* if there was an error */ freemsg(mp); return; } ASSERT(csp->cp_cmd == SAD_VML); sadp = (struct saddev *)qp->q_ptr; switch ((long)csp->cp_private) { case GETSTRUCT: STRUCT_SET_HANDLE(slp, csp->cp_flag, (struct str_list *)mp->b_cont->b_rptr); nmods = STRUCT_FGET(slp, sl_nmods); if (nmods <= 0) { miocnak(qp, mp, 0, EINVAL); break; } sadp->sa_addr = (caddr_t)(uintptr_t)nmods; mcopyin(mp, (void *)GETLIST, nmods * sizeof (struct str_mlist), STRUCT_FGETP(slp, sl_modlist)); qreply(qp, mp); break; case GETLIST: lp = (struct str_mlist *)mp->b_cont->b_rptr; for (i = 0; i < (long)sadp->sa_addr; i++, lp++) { lp->l_name[FMNAMESZ] = '\0'; if (fmodsw_find(lp->l_name, FMODSW_LOAD) == NULL) { miocack(qp, mp, 0, 1); return; } } miocack(qp, mp, 0, 0); break; default: cmn_err(CE_WARN, "vml_iocdata: invalid cp_private value: %p", (void *)csp->cp_private); freemsg(mp); break; } /* switch (cp_private) */ }
/* * ========================================================================= * * SCCP-User --> SUA (ASP) Downstream Primitives * * ========================================================================= */ static inline ss7_error_reply(queue_t *q, mblk_t *pdu, int prim, int err) { mblk_t *mp; if ((mp = sccp_error_ack(prim, err))) { freemsg(pdu); qreply(q, mp); return (0); } return (-ENOBUFS); }
static void mouse8042_iocnack( queue_t *qp, mblk_t *mp, struct iocblk *iocp, int error, int rval) { mp->b_datap->db_type = M_IOCNAK; iocp->ioc_rval = rval; iocp->ioc_error = error; qreply(qp, mp); }
STATIC int m_error(queue_t *q, int err) { mblk_t *mp; if ((mp = ss7_allocb(q, 2, BPRI_MED))) { mp->b_datap->db_type = M_ERROR; *(mp->b_wptr)++ = err < 0 ? -err : err; *(mp->b_wptr)++ = err < 0 ? -err : err; qreply(q, mp); return (QR_DONE); } rare(); return (-ENOBUFS); }
/* * Send M_IOCACK(or M_IOCNAK) message to stream * * Requires Lock (( M: Mandatory, P: Prohibited, A: Allowed )) * -. uinst_t->lock : P * -. uinst_t->u_lock : P * -. uinst_t->l_lock : P * -. uinst_t->c_lock : P */ void oplmsu_iocack(queue_t *q, mblk_t *mp, int errno) { struct iocblk *iocp = NULL; ASSERT(mp != NULL); iocp = (struct iocblk *)mp->b_rptr; iocp->ioc_error = errno; if (errno) { /* Error */ mp->b_datap->db_type = M_IOCNAK; iocp->ioc_rval = FAILURE; OPLMSU_TRACE(q, mp, MSU_TRC_UO); qreply(q, mp); } else { /* Good */ mp->b_datap->db_type = M_IOCACK; iocp->ioc_rval = SUCCESS; OPLMSU_TRACE(q, mp, MSU_TRC_UO); qreply(q, mp); } }
/* * vml_ioctl() - * Handle the M_IOCTL message associated with a request * to validate a module list. */ static void vml_ioctl( queue_t *qp, /* pointer to write queue */ mblk_t *mp) /* message pointer */ { struct iocblk *iocp; iocp = (struct iocblk *)mp->b_rptr; if (iocp->ioc_count != TRANSPARENT) { miocnak(qp, mp, 0, EINVAL); return; } ASSERT(iocp->ioc_cmd == SAD_VML); mcopyin(mp, (void *)GETSTRUCT, SIZEOF_STRUCT(str_list, iocp->ioc_flag), NULL); qreply(qp, mp); }
static int kb8042_wsrv(queue_t *qp) { struct kb8042 *kb8042; mblk_t *mp; kb8042 = (struct kb8042 *)qp->q_ptr; while ((mp = getq(qp))) { switch (kbtrans_streams_message(kb8042->hw_kbtrans, mp)) { case KBTRANS_MESSAGE_HANDLED: continue; case KBTRANS_MESSAGE_NOT_HANDLED: break; } switch (mp->b_datap->db_type) { case M_IOCTL: kb8042_ioctlmsg(kb8042, qp, mp); continue; case M_IOCDATA: kb8042_iocdatamsg(qp, mp); continue; case M_DELAY: case M_STARTI: case M_STOPI: case M_READ: /* ignore, no buffered data */ freemsg(mp); continue; case M_FLUSH: *mp->b_rptr &= ~FLUSHW; if (*mp->b_rptr & FLUSHR) qreply(qp, mp); else freemsg(mp); continue; default: cmn_err(CE_NOTE, "kb8042_wsrv: bad msg %x", mp->b_datap->db_type); freemsg(mp); continue; } } return (0); }
/* * LMI_DISABLE_CON * ----------------------------------- */ STATIC INLINE int lmi_disable_con(queue_t *q, long state) { mblk_t *mp; lmi_disable_con_t *p; if ((mp = ss7_allocb(q, sizeof(*p), BPRI_MED))) { mp->b_datap->db_type = M_PCPROTO; p = (typeof(p)) mp->b_wptr; mp->b_wptr += sizeof(*p); p->lmi_primitive = LMI_DISABLE_CON; p->lmi_state = state; qreply(q, mp); return (QR_DONE); } rare(); return (-ENOBUFS); }
static void rds_info_req(queue_t *q, mblk_t *omp) { rds_t *rds = (rds_t *)q->q_ptr; struct T_info_ack *tap; mblk_t *mp; /* Create a T_INFO_ACK message. */ mp = tpi_ack_alloc(omp, sizeof (struct T_info_ack), M_PCPROTO, T_INFO_ACK); if (mp == NULL) return; tap = (struct T_info_ack *)(uintptr_t)mp->b_rptr; *tap = rds_g_t_info_ack_ipv4; tap->CURRENT_state = rds->rds_state; tap->OPT_size = 128; qreply(q, mp); }
static inline int ss7_uderror_reply(queue_t *q, mblk_t *pdu, int err) { mblk_t *mp; N_unitdata_req_t *p = (N_unitdata_req_t *) pdu->b_rptr; if ((mp = sccp_uderror_ind(err, p->DEST_length ? (sccp_addr_t *) (pdu->b_rptr + p->DEST_offset) : 0, p->SRC_length ? (sccp_addr_t *) (pdu->b_rptr + p->SRC_offset) : 0, pdu->b_cont))) { freeb(pdu); qreply(q, mp); return (0); } return (-ENOBUFS); }
/* * apush_ioctl() - * Handle the M_IOCTL messages associated with * the autopush feature. */ static void apush_ioctl( queue_t *qp, /* pointer to write queue */ mblk_t *mp) /* message pointer */ { struct iocblk *iocp; struct saddev *sadp; uint_t size; iocp = (struct iocblk *)mp->b_rptr; if (iocp->ioc_count != TRANSPARENT) { miocnak(qp, mp, 0, EINVAL); return; } if (SAD_VER(iocp->ioc_cmd) > AP_VERSION) { miocnak(qp, mp, 0, EINVAL); return; } sadp = (struct saddev *)qp->q_ptr; switch (SAD_CMD(iocp->ioc_cmd)) { case SAD_CMD(SAD_SAP): if (!(sadp->sa_flags & SADPRIV)) { miocnak(qp, mp, 0, EPERM); break; } /* FALLTHRU */ case SAD_CMD(SAD_GAP): sadp->sa_addr = (caddr_t)*(uintptr_t *)mp->b_cont->b_rptr; if (SAD_VER(iocp->ioc_cmd) == 1) size = STRAPUSH_V1_LEN; else size = STRAPUSH_V0_LEN; mcopyin(mp, (void *)GETSTRUCT, size, NULL); qreply(qp, mp); break; default: ASSERT(0); miocnak(qp, mp, 0, EINVAL); break; } /* switch (ioc_cmd) */ }
/* * LMI_OK_ACK * ----------------------------------- */ STATIC INLINE int lmi_ok_ack(queue_t *q, long state, long prim) { mblk_t *mp; lmi_ok_ack_t *p; if ((mp = ss7_allocb(q, sizeof(*p), BPRI_MED))) { mp->b_datap->db_type = M_PCPROTO; p = (typeof(p)) mp->b_wptr; mp->b_wptr += sizeof(*p); p->lmi_primitive = LMI_OK_ACK; p->lmi_correct_primitive = prim; p->lmi_state = state; qreply(q, mp); return (QR_DONE); } rare(); return (-ENOBUFS); }
/* * Received a put from sockfs. We only support ndd get/set */ static void sdp_gen_wput(queue_t *q, mblk_t *mp) { switch (mp->b_datap->db_type) { case M_IOCTL: sdp_gen_ioctl(q, mp); break; case M_FLUSH: *mp->b_rptr &= ~FLUSHW; if (*mp->b_rptr & FLUSHR) qreply(q, mp); else freemsg(mp); break; default: freemsg(mp); return; } }
/* * LMI_STATS_IND * ----------------------------------- */ STATIC INLINE int lmi_stats_ind(queue_t *q) { mblk_t *mp; lmi_stats_ind_t *p; if ((mp = ss7_allocb(q, sizeof(*p), BPRI_MED))) { mp->b_datap->db_type = M_PCPROTO; p = (typeof(p)) mp->b_wptr; mp->b_wptr += sizeof(*p); p->lmi_primitive = LMI_STATS_IND; p->lmi_interval = 0; p->lmi_timestamp = jiffies; qreply(q, mp); return (QR_DONE); } rare(); return (-ENOBUFS); }
/* * LMI_ERROR_IND * ----------------------------------- */ STATIC INLINE int lmi_error_ind(queue_t *q, long state, long error, long reason) { mblk_t *mp; lmi_error_ind_t *p; if ((mp = ss7_allocb(q, sizeof(*p), BPRI_MED))) { mp->b_datap->db_type = M_PCPROTO; p = (typeof(p)) mp->b_wptr; mp->b_wptr += sizeof(*p); p->lmi_primitive = LMI_ERROR_IND; p->lmi_errno = error; p->lmi_reason = reason; p->lmi_state = state; qreply(q, mp); return (QR_DONE); } rare(); return (-ENOBUFS); }
/* * cvc_ioctl() * handle normal console ioctls. */ static void cvc_ioctl(register queue_t *q, register mblk_t *mp) { register cvc_t *cp = q->q_ptr; int datasize; int error = 0; /* * Let ttycommon_ioctl take the first shot at processing the ioctl. If * it fails because it can't allocate memory, schedule processing of the * ioctl later when a proper buffer is available. The mblk that * couldn't be processed will have been stored in the tty structure by * ttycommon_ioctl. */ datasize = ttycommon_ioctl(&cp->cvc_tty, q, mp, &error); if (datasize != 0) { if (cp->cvc_wbufcid) { unbufcall(cp->cvc_wbufcid); } cp->cvc_wbufcid = bufcall(datasize, BPRI_HI, cvc_reioctl, cp); return; } /* * ttycommon_ioctl didn't do anything, but there's nothing we really * support either with the exception of TCSBRK, which is supported * only to appear a bit more like a serial device for software that * expects TCSBRK to work. */ if (error != 0) { struct iocblk *iocp = (struct iocblk *)mp->b_rptr; if (iocp->ioc_cmd == TCSBRK) { miocack(q, mp, 0, 0); } else { miocnak(q, mp, 0, EINVAL); } } else { qreply(q, mp); } }
/* * M_FLUSH Processing * ------------------------------------------------------------------------- */ static int xxx_r_flush(queue_t *q, mblk_t *mp) { if (*mp->b_rptr & FLUSHR) { if (*mp->b_rptr & FLUSHBAND) flushband(q, mp->b_rptr[1], FLUSHDATA); else flushall(q, FLUSHDATA); *mp->b_rptr &= ~FLUSHR; } if ((*mp->b_rptr & FLUSHW) && !(mp->b_flags & MSGNOLOOP)) { if (*mp->b_rptr & FLUSHBAND) flushband(q, mp->b_rptr[1], FLUSHDATA); else flushall(q, FLUSHDATA); mp->b_flag |= MSGNOLOOP; qreply(q, mp); /* flush all the way back down */ } freemsg(mp); return (0); }
STATIC INLINE int lmi_optmgmt_ack(queue_t *q, ulong flags, caddr_t opt_ptr, size_t opt_len) { mblk_t *mp; lmi_optmgmt_ack_t *p; if ((mp = ss7_allocb(q, sizeof(*p) + opt_len, BPRI_MED))) { mp->b_datap->db_type = M_PCPROTO; p = ((typeof(p)) mp->b_wptr)++; p->lmi_primitive = LMI_OPTMGMT_ACK; p->lmi_opt_length = opt_len; p->lmi_opt_offset = opt_len ? sizeof(*p) : 0; p->lmi_flags = flags; bcopy(opt_ptr, mp->b_wptr, opt_len); mp->b_wptr += opt_len; qreply(q, mp); return (QR_DONE); } rare(); return (-ENOBUFS); }
/* * sppp_dlinforeq() * * MT-Perimeters: * shared inner, shared outer. * * Description: * Perform DL_INFO_REQ request, called by sppp_mproto. */ static int sppp_dlinforeq(queue_t *q, mblk_t *mp, spppstr_t *sps) { dl_info_ack_t *dlip; uint32_t size; uint32_t addr_size; sppa_t *ppa; ASSERT(q != NULL && q->q_ptr != NULL); ASSERT(mp != NULL && mp->b_rptr != NULL); ASSERT(sps != NULL); ppa = sps->sps_ppa; /* Exchange current msg for a DL_INFO_ACK. */ addr_size = SPPP_ADDRL; size = sizeof (dl_info_ack_t) + addr_size; if ((mp = mexchange(q, mp, size, M_PCPROTO, DL_INFO_ACK)) == NULL) { DBGERROR((CE_CONT, "DLPI info: mexchange failed\n")); /* mexchange already sent up an merror ENOSR */ return (0); } /* Fill in DL_INFO_ACK fields and reply */ dlip = (dl_info_ack_t *)mp->b_rptr; *dlip = sppp_infoack; dlip->dl_current_state = sps->sps_dlstate; dlip->dl_max_sdu = ppa != NULL ? ppa->ppa_mtu : PPP_MAXMTU; #ifdef DBG_DLPI { const char *cp = state2name(dlip->dl_current_state); if (cp != NULL) cmn_err(CE_CONT, "info returns state %s, max sdu %d\n", cp, dlip->dl_max_sdu); else cmn_err(CE_CONT, "info returns state %d, max sdu %d\n", dlip->dl_current_state, dlip->dl_max_sdu); } #endif qreply(q, mp); return (0); }