📄 wdbendpktdrv.c
字号:
* wdbEndTx - transmit a packet.** The packet is realy a chain of mbufs. We may have to just queue up* this packet is we are already transmitting.** RETURNS: OK or ERROR** NOMANUAL*/STATUS wdbEndTx ( void * pDev, struct mbuf * pMbuf ) { WDB_END_PKT_DEV *pPktDev = pDev; struct mbuf* pFirstMbuf = pMbuf;#ifdef WDB_NPT_CAPABLE int sendStatus = 0; char * dstMacAddr = NULL;#else int len = 0;#endif WDB_NPT_CAPABLE if (wdbEndDebug) logMsg ("entering send\n", 1, 2, 3, 4, 5, 6); if (pMbuf == NULL) return (ERROR); if (pPktDev->outputBusy) { wdbMbufChainFree (pFirstMbuf); return (EAGAIN); } else pPktDev->outputBusy = TRUE; if (wdbEndDebug) logMsg ("About to enter the copy loop!\n", 1, 2, 3, 4, 5, 6); /* Make sure we know that the outgoing buffer is clean/empty */ pPktDev->pOutBlk->mBlkHdr.mLen = 0; pPktDev->pOutBlk->mBlkHdr.mData = pPktDev->pOutBlk->pClBlk->clNode.pClBuf; /* increment the data pointer so that muxAddressForm can prepend header */ pPktDev->pOutBlk->mBlkHdr.mData += SIZEOF_ETHERHEADER;#ifndef WDB_NPT_CAPABLE /* First place the addressing information into the packet. */ muxAddressForm (pPktDev->pCookie, pPktDev->pOutBlk, pPktDev->srcAddr, pPktDev->lastHAddr); len = pPktDev->pOutBlk->mBlkHdr.mLen; if (wdbEndDebug) logMsg ("About to check length!\n", 1, 2, 3, 4, 5, 6); if (len == 0) { wdbMbufChainFree (pFirstMbuf); pPktDev->outputBusy = FALSE; if (wdbEndDebug) logMsg ("Wrong length!\n", 1, 2, 3, 4, 5, 6); return (EAGAIN); } if (wdbEndDebug) logMsg ("hdr length:%d\n", len, 2, 3, 4, 5, 6); pPktDev->pOutBlk->mBlkHdr.mLen = len + netMblkToBufCopy (pMbuf, pPktDev->pOutBlk->mBlkHdr.mData + len, NULL); pPktDev->pOutBlk->mBlkPktHdr.len = pPktDev->pOutBlk->mBlkHdr.mLen; if (wdbEndDebug) logMsg ("OutBlk: %x:%x:%x:%x:%x:%x\n", pPktDev->pOutBlk->mBlkHdr.mData[0], pPktDev->pOutBlk->mBlkHdr.mData[1], pPktDev->pOutBlk->mBlkHdr.mData[2], pPktDev->pOutBlk->mBlkHdr.mData[3], pPktDev->pOutBlk->mBlkHdr.mData[4], pPktDev->pOutBlk->mBlkHdr.mData[5]);#else pPktDev->pOutBlk->mBlkHdr.mLen = netMblkToBufCopy (pMbuf, pPktDev->pOutBlk->mBlkHdr.mData, NULL); pPktDev->pOutBlk->mBlkPktHdr.len = pPktDev->pOutBlk->mBlkHdr.mLen;#endif /* WDB_NPT_CAPABLE */ if (wdbEndDebug) logMsg ("Data copied !\n", 1, 2, 3, 4, 5, 6); wdbMbufChainFree (pFirstMbuf); if (wdbEndDebug) logMsg ("About to send a packet!\n", 1, 2, 3, 4, 5, 6);#ifdef WDB_NPT_CAPABLE dstMacAddr = pPktDev->lastHAddr->mBlkHdr.mData;#endif /* WDB_NPT_CAPABLE */#ifndef STANDALONE_AGENT /* if we are in polled mode, transmit the packet in a loop */ if (pPktDev->mode == WDB_COMM_MODE_POLL) {#ifndef WDB_NPT_CAPABLE muxPollSend (pPktDev->pCookie, pPktDev->pOutBlk);#else sendStatus = muxTkPollSend (pPktDev->pCookie, pPktDev->pOutBlk, dstMacAddr, htons(ETHERTYPE_IP), NULL); if (sendStatus != OK) { pPktDev->outputBusy = FALSE; if (wdbEndDebug) logMsg ("Wrong length!\n", 1, 2, 3, 4, 5, 6); return (EAGAIN); }#endif /* WDB_NPT_CAPABLE */ if (wdbEndDebug) logMsg ("Sent polled packet!\n", 1, 2, 3, 4, 5, 6); } else {#ifndef WDB_NPT_CAPABLE if (muxSend (pPktDev->pCookie, pPktDev->pOutBlk) == OK)#else if (muxTkSend (pPktDev->pCookie, pPktDev->pOutBlk, dstMacAddr, htons(ETHERTYPE_IP), NULL) == OK)#endif /* WDB_NPT_CAPABLE */ { END_OBJ * pEnd; if (wdbEndDebug) logMsg ("Sent regular packet!\n", 1, 2, 3, 4, 5, 6); /*pEnd = (END_OBJ *)pPktDev->pCookie;*/ pEnd = PCOOKIE_TO_ENDOBJ(pPktDev->pCookie); if ((pPktDev->pOutBlk = wdbEndMblkClGet (pEnd, pEnd->mib2Tbl.ifMtu)) == NULL) return (ERROR); pPktDev->pOutBlk->mBlkHdr.mFlags |= M_PKTHDR; } else { if (wdbEndDebug) logMsg ("Could not send regular packet!\n", 1, 2, 3, 4, 5, 6); } }#else /* STANDALONE_AGENT */ if (muxPollSend (pPktDev->pCookie, pPktDev->pOutBlk) == ERROR) { if (wdbEndDebug); logMsg ("Could not send regular packet!\n", 1, 2, 3, 4, 5, 6); } else { if (wdbEndDebug) logMsg ("Sent polled packet!\n", 1, 2, 3, 4, 5, 6); }#endif /* STANDALONE_AGENT */ wdbEndOutputFree (pPktDev); return (OK); }/******************************************************************************** wdbEndOutputFree - free the output buffer** This is the callback used to let us know the that the device is done with the* output buffer we loaned it.** RETURNS: N/A** NOMANUAL*/LOCAL void wdbEndOutputFree ( void * pDev ) { WDB_END_PKT_DEV * pPktDev = pDev; DRIVER_RESET_OUTPUT(pPktDev); }/******************************************************************************** wdbEndInputFree- free the input buffer** This is the callback used to let us know the agent is done with the* input buffer we loaded it.** RETURNS: N/A** NOMANUAL*/LOCAL void wdbEndInputFree ( void * pDev ) { WDB_END_PKT_DEV * pPktDev = pDev; DRIVER_RESET_INPUT(pPktDev); }/******************************************************************************** wdbEndModeSet - switch driver modes** RETURNS: OK for a supported mode, else ERROR** NOMANUAL*/LOCAL STATUS wdbEndModeSet ( void * pDev, uint_t newMode ) { WDB_END_PKT_DEV * pPktDev = pDev; if (newMode == WDB_COMM_MODE_INT) { muxIoctl (pPktDev->pCookie, EIOCPOLLSTOP, NULL); pPktDev->mode = newMode; return (OK); } else if (newMode == WDB_COMM_MODE_POLL) { muxIoctl (pPktDev->pCookie, EIOCPOLLSTART, NULL); pPktDev->mode = newMode; return (OK); } else return (ERROR); return (ERROR); }/******************************************************************************** wdbEndPollArpReply - END driver ARP reply handler** WDB agent normally only manages IP packets that are sent to a dedicated* port. However it is the only protocol bound to the MUX, we must also reply* to ARP request so that communication becomes possible.** RETURNS: TRUE if the packet was for us, FALSE otherwise.** NOMANUAL*/LOCAL BOOL wdbEndPollArpReply ( struct mbuf * pMblk, void * pCookie ) { struct ether_header * pEh; struct ether_arp * pEa; WDB_END_PKT_DEV * pPktDev = pEndPktDev; int op; pEh = mtod(pMblk, struct ether_header *); pEa = (struct ether_arp *) ((char *)pEh + sizeof (struct ether_header)); op = ntohs(pEa->arp_op); /* test if the request is for us */ if ((bcmp ((caddr_t)&pPktDev->ipAddr.s_addr, (caddr_t)&pEa->arp_tpa, pEa->arp_pln) == 0) && (op == ARPOP_REQUEST)) { /* build the reply */ /* fill the ethernet header */ bcopy (pEh->ether_shost, pEh->ether_dhost, sizeof(pEh->ether_shost)); bcopy (pPktDev->srcAddr->mBlkHdr.mData, pEh->ether_shost, sizeof(pEh->ether_shost)); /* fill the ARP Frame */ bcopy (pEh->ether_dhost, pEa->arp_tha, pEa->arp_hln); bcopy (pEa->arp_spa, pEa->arp_tpa, pEa->arp_pln); bcopy (pEh->ether_shost, pEa->arp_sha, pEa->arp_hln); bcopy ((char *)&pPktDev->ipAddr.s_addr, pEa->arp_spa, pEa->arp_pln); pEa->arp_op = htons (ARPOP_REPLY); /* send the reply */ muxPollSend (pCookie, pMblk); netMblkClFree (pMblk); DRIVER_RESET_INPUT(pPktDev); return (TRUE); } netMblkClFree (pMblk); DRIVER_RESET_INPUT(pPktDev); return (FALSE); }/******************************************************************************** wdbEndPoll - poll for a packet** This routine polls for a packet. If a packet has arrived it invokes* the agents callback.** RETURNS: OK if a packet has arrived, else ERROR.** NOMANUAL*/ LOCAL STATUS wdbEndPoll ( void * pDev ) { long type; M_BLK_ID pMblk; WDB_END_PKT_DEV * pPktDev = pDev; LL_HDR_INFO llHdrInfo; int mode = WDB_COMM_MODE_POLL; END_OBJ * pEnd = PCOOKIE_TO_ENDOBJ(pPktDev->pCookie); /* Reset the size to the maximum. */ pPktDev->pInBlk->mBlkHdr.mLen = pPktDev->pInBlk->pClBlk->clSize; pPktDev->pInBlk->mBlkHdr.mData = pPktDev->pInBlk->pClBlk->clNode.pClBuf;#ifdef WDB_NPT_CAPABLE if (muxTkPollReceive (pPktDev->pCookie, pPktDev->pInBlk, NULL) == OK)#else if (muxPollReceive (pPktDev->pCookie, pPktDev->pInBlk) == OK)#endif /* WDB_NPT_CAPABLE */ { if ((pMblk = mBlkGet (pEnd->pNetPool, M_DONTWAIT, MT_DATA)) == NULL) return (ERROR); /* duplicate the received mBlk so that wdbEndInt can free it */ pMblk = netMblkDup (pPktDev->pInBlk, pMblk);#ifndef WDB_NPT_CAPABLE if (muxPacketDataGet (pPktDev->pCookie, pMblk, &llHdrInfo) == ERROR) { return (ERROR); }#else if ((pEnd->mib2Tbl.ifType == M2_ifType_ethernet_csmacd) || (pEnd->mib2Tbl.ifType == M2_ifType_iso88023_csmacd)) { if (endEtherPacketDataGet (pMblk, &llHdrInfo) == ERROR) { return (ERROR); } } else return ERROR;#endif /* WDB_NPT_CAPABLE */ type = llHdrInfo.pktType; if (wdbEndInt (pPktDev->pCookie, type, pMblk, &llHdrInfo, (void *)&mode) == TRUE) return (OK); return (ERROR); } else { return (ERROR); } }/******************************************************************************** wdbEndMblkClGet - get an mBlk/clBlk/cluster ** This routine returns an mBlk which points to a clBlk which points to a* cluster. This routine allocates the triplet from the pNetPool in the* end object.** RETURNS: M_BLK_ID / NULL** NOMANUAL*/ LOCAL M_BLK_ID wdbEndMblkClGet ( END_OBJ * pEnd, /* endobject in which the netpool belongs */ int size /* size of the cluster */ ) { M_BLK_ID pMblk; if ((pMblk = netTupleGet (pEnd->pNetPool, size, M_DONTWAIT, MT_DATA, FALSE)) == NULL) { if (wdbEndDebug) logMsg ("wdbEndMblkClGet:Could not get mBlk...\n", 1, 2, 3, 4, 5, 6); } return (pMblk); }#ifdef WDB_NPT_CAPABLE/******************************************************************************** wdbNptInt - NPT driver interrupt handler** This is really a MUX receive routine but we let it look like* an interrupt handler to make this interface look as much like the* template as possible.** RETURNS: TRUE if the packet was for us, FALSE otherwise.** NOMANUAL*/int wdbNptInt ( void * callbackId, /* call back Id supplied during muxTkBind */ long type, /* our network service type */ M_BLK_ID pMblk, /* the packet */ void * pSpareData /* any spare data; we ignore it */ ) { END_OBJ * pEnd = PCOOKIE_TO_ENDOBJ(pEndPktDev->pCookie); LL_HDR_INFO llHdrInfo; switch (pEnd->mib2Tbl.ifType) { case M2_ifType_ethernet_csmacd: case M2_ifType_iso88023_csmacd: if (wdbEndDebug) logMsg ("wdbNptInt: Received an Ethernet packet\n",1,2,3,4,5,6); endEtherPacketDataGet (pMblk,&llHdrInfo); return (wdbEndInt (pEndPktDev->pCookie, type, pMblk, &llHdrInfo,callbackId)); break; default: if (wdbEndDebug) logMsg ("wdbNptInt: NOT an Ethernet packet\n",1,2,3,4,5,6); return (FALSE); } }/********************************************************************************* wdbNptShutdown - dummy shutdown routine for muxTkBind ** RETURNS: N/A** NOMANUAL*/void wdbNptShutdown ( void * callbackId /* call back Id supplied during muxTkBind */ ) { }#endif /* WDB_NPT_CAPABLE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -