{ "IF", IF, 0 }, { "IMPLICIT", IMPLICIT, 0 }, { "INTRINSIC", INTRINSIC, 0 }, { "PROGRAM", PROGRAM, 0 }, { "RETURN", RETURN, 0 }, { "REWIND", REWIND, 0 }, { "SAVE", SAVE, 0 }, { "STOP", STOP, 0 }, { "SUBROUTINE", SUBROUTINE, 0 }, { "THEN", THEN, 0 }, NULL }; /* type declarators */ kwdtab tab_type[] = { { "DOUBLEPRECISION", TYPE, MTYPE(REAL, 8), }, { "REAL*8", TYPE, MTYPE(REAL, 8), }, { "REAL*4", TYPE, MTYPE(REAL, 4), }, { "REAL", TYPE, MTYPE(REAL, 4), }, { "INTEGER*4", TYPE, MTYPE(INTEGER, 4), }, { "INTEGER", TYPE, MTYPE(INTEGER, 4), }, { "LOGICAL*4", TYPE, MTYPE(LOGICAL, 4), }, { "LOGICAL", TYPE, MTYPE(LOGICAL, 4), }, { "DOUBLECOMPLEX", TYPE, MTYPE(COMPLEX, 16), }, { "COMPLEX*16", TYPE, MTYPE(COMPLEX, 16), }, { "COMPLEX*8", TYPE, MTYPE(COMPLEX, 8), },
/* * sppp_dlunitdatareq() * * MT-Perimeters: * shared inner, shared outer. * * Description: * Handle DL_UNITDATA_REQ request, called by sppp_mproto. This procedure * gets called for M_PROTO (DLPI) style of transmission. The fact that we * have acknowledged IP's fastpath probing (DL_IOC_HDR_INFO) does not * guarantee that IP will always transmit via M_DATA, and it merely implies * that such situation _may_ happen. In other words, IP may decide to use * M_PROTO (DLPI) for data transmission should it decide to do so. * Therefore, we should never place any restrictions or checks against * streams marked with SPS_FASTPATH, since it is legal for this procedure * to be entered with or without the bit set. */ static int sppp_dlunitdatareq(queue_t *q, mblk_t *mp, spppstr_t *sps) { sppa_t *ppa; mblk_t *hdrmp; mblk_t *pktmp; dl_unitdata_req_t *dludp; int dladdroff; int dladdrlen; int msize; int error = 0; boolean_t is_promisc; ASSERT(q != NULL && q->q_ptr != NULL); ASSERT(mp != NULL && mp->b_rptr != NULL); ASSERT((MTYPE(mp) == M_PCPROTO) || (MTYPE(mp) == M_PROTO)); dludp = (dl_unitdata_req_t *)mp->b_rptr; dladdroff = dludp->dl_dest_addr_offset; dladdrlen = dludp->dl_dest_addr_length; ASSERT(sps != NULL); ASSERT(!IS_SPS_PIOATTACH(sps)); ASSERT(sps->sps_dlstate == DL_IDLE); ASSERT(q->q_ptr == sps); /* * If this stream is not attached to any ppas, then discard data * coming down through this stream. */ ppa = sps->sps_ppa; if (ppa == NULL) { DBGERROR((CE_CONT, "DLPI unitdata: no attached ppa\n")); error = ENOLINK; } else if (mp->b_cont == NULL) { DBGERROR((CE_CONT, "DLPI unitdata: missing data\n")); error = EPROTO; } if (error != 0) { dluderrorind(q, mp, mp->b_rptr + dladdroff, dladdrlen, DL_BADDATA, error); return (0); } ASSERT(mp->b_cont->b_rptr != NULL); /* * Check if outgoing packet size is larger than allowed. We use * msgdsize to count all of M_DATA blocks in the message. */ msize = msgdsize(mp); if (msize > ppa->ppa_mtu) { /* Log, and send it anyway */ mutex_enter(&ppa->ppa_sta_lock); ppa->ppa_otoolongs++; mutex_exit(&ppa->ppa_sta_lock); } if (IS_SPS_KDEBUG(sps)) { SPDEBUG(PPP_DRV_NAME "/%d: DL_UNITDATA_REQ (%d bytes) sps=0x%p flags=0x%b " "ppa=0x%p flags=0x%b\n", sps->sps_mn_id, msize, (void *)sps, sps->sps_flags, SPS_FLAGS_STR, (void *)ppa, ppa->ppa_flags, PPA_FLAGS_STR); } /* Allocate a message (M_DATA) to contain PPP header bytes. */ if ((hdrmp = allocb(PPP_HDRLEN, BPRI_MED)) == NULL) { mutex_enter(&ppa->ppa_sta_lock); ppa->ppa_allocbfail++; mutex_exit(&ppa->ppa_sta_lock); DBGERROR((CE_CONT, "DLPI unitdata: can't allocate header buffer\n")); dluderrorind(q, mp, mp->b_rptr + dladdroff, dladdrlen, DL_SYSERR, ENOSR); return (0); } /* * Should there be any promiscuous stream(s), send the data up * for each promiscuous stream that we recognize. */ rw_enter(&ppa->ppa_sib_lock, RW_READER); is_promisc = ppa->ppa_promicnt; if (is_promisc) { ASSERT(ppa->ppa_streams != NULL); sppp_dlprsendup(ppa->ppa_streams, mp->b_cont, sps->sps_sap, B_FALSE); } rw_exit(&ppa->ppa_sib_lock); /* Discard DLPI header and keep only IP payload (mp->b_cont). */ pktmp = mp->b_cont; mp->b_cont = NULL; freemsg(mp); mp = hdrmp; *(uchar_t *)mp->b_wptr++ = PPP_ALLSTATIONS; *(uchar_t *)mp->b_wptr++ = PPP_UI; *(uchar_t *)mp->b_wptr++ = ((uint16_t)sps->sps_sap >> 8) & 0xff; *(uchar_t *)mp->b_wptr++ = ((uint16_t)sps->sps_sap) & 0xff; ASSERT(MBLKL(mp) == PPP_HDRLEN); linkb(mp, pktmp); /* * Only time-stamp the packet with hrtime if the upper stream * is configured to do so. */ if (IS_PPA_TIMESTAMP(ppa)) { ppa->ppa_lasttx = gethrtime(); } /* * Just put this back on the queue and allow the write service * routine to handle it. We're nested too deeply here to * rewind the stack sufficiently to prevent overflow. This is * the slow path anyway. */ if (putq(q, mp) == 0) { mutex_enter(&ppa->ppa_sta_lock); ppa->ppa_oqdropped++; mutex_exit(&ppa->ppa_sta_lock); freemsg(mp); } else { qenable(q); } return (0); }