📄 wdbendpktdrv.c
字号:
/* wdbEndPktDrv.c - END based packet driver for lightweight UDP/IP *//*modification history--------------------01r,02mar99,dbt correctly initialize mBlkPktHdr.len field in send routine (SPR #25330).01q,11dec97,vin optimized some code and additional fixes to SPR9563.01p,08dec97,gnn fixed spr#9563 to get MBLK chains.01o,25nov97,gnn fixed spr#9620 polled mode receive01n,19oct97,vin fixed wdbEndInt, wdbEndPoll(), cleanup.01m,17oct97,vin changed wdbEndInt for muxPacketDataGet fixes.01l,09oct97,vin fixed wdbEndInt various error conditions, added htons01k,03oct97,gnn adjusted muxBind call to be in line with new prototype01j,25sep97,gnn SENS beta feedback fixes01i,25aug97,gnn fixed remaining polled mode problems.01h,22aug97,gnn changes due to new buffering scheme.01g,12aug97,gnn changes necessitated by MUX/END update.01f,08apr97,map Free mbuf cluster in wdbEndTx() when output is busy.01e,21jan97,gnn Added code to handle new addressles sending. Changed the way that transmit is done and free'd.01d,22oct96,gnn Name changes to follow the coding standards.01c,22oct96,gnn Removed netVectors and replaced with netBuffers. Replaced the 0 for promiscous protocol with a constant MUX_PROTO_PROMISC.01b,23sep96,gnn Added new buffering scheme information.01a,1jul96,gnn written.*//*DESCRIPTIONOVERVIEWThis is an END based driver for the WDB system. It uses the MUX and ENDbased drivers to allow for interaction between the target and targetserver.USAGEThe driver is typically only called only from usrWdb.c. The only directlycallable routine in this module is wdbEndPktDevInit(). Your configAll.hfile will have to be modified so that WDB_COMM_TYPE is defined asWDB_COMM_END. DATA BUFFERINGThe drivers only need to handle one input packet at a time becausethe WDB protocol only supports one outstanding host-request at a time.If multiple input packets arrive, the driver can simply drop them.The driver then loans the input buffer to the WDB agent, and the agentinvokes a driver callback when it is done with the buffer.For output, the agent will pass the driver a chain of mbufs, whichthe driver must send as a packet. When it is done with the mbufs,it calls wdbMbufChainFree() to free them.The header file wdbMbuflib.h provides the calls for allocating, freeing,and initializing mbufs for use with the lightweight UDP/IP interpreter.It ultimatly makes calls to the routines wdbMbufAlloc and wdbMbufFree, whichare provided in source code in usrWdb.c.*/#include "string.h"#include "errno.h"#include "sioLib.h"#include "intLib.h"#include "logLib.h"#include "end.h"#include "muxLib.h"#include "stdlib.h"#include "wdb/wdbMbufLib.h"#include "drv/wdb/wdbEndPktDrv.h"#include "net/if.h"#include "netinet/udp.h"#include "netinet/if_ether.h"/* defints */#define IP_HDR_SIZE 20/* globals */WDB_END_PKT_DEV * pEndPktDev;int wdbEndDebug = 0;char *pInPkt;/* pseudo-macros */#define DRIVER_INIT_HARDWARE(pDev) {}#define DRIVER_MODE_SET(pDev, mode)#define DRIVER_PACKET_IS_READY(pDev) FALSE#define DRIVER_RESET_INPUT(pDev) {pDev->inputBusy=FALSE;}#define DRIVER_RESET_OUTPUT(pDev) {pDev->outputBusy=FALSE;}#define DRIVER_GET_INPUT_PACKET(pDev, pBuf) (50)#define DRIVER_DATA_FROM_MBUFS(pDev, pBuf) {}#define DRIVER_POLL_TX(pDev, pBuf) {}#define DRIVER_TX_START(pDev) {}/* forward declarations */LOCAL STATUS wdbEndPoll (void *pDev);LOCAL STATUS wdbEndTx (void *pDev, struct mbuf * pMbuf);LOCAL STATUS wdbEndModeSet (void *pDev, uint_t newMode);LOCAL void wdbEndInputFree (void *pDev);LOCAL void wdbEndOutputFree (void *pDev);LOCAL M_BLK_ID wdbEndMblkClGet (END_OBJ * pEnd, int size);int wdbEndInt (void* pCookie, long type, M_BLK_ID pMblk, LL_HDR_INFO *, void* pNull);/******************************************************************************** wdbEndPktDevInit - initialize an END packet device.** NOMANUAL*/void wdbEndPktDevInit ( WDB_END_PKT_DEV *pPktDev, /* device structure to init */ void (*stackRcv)(), /* receive packet callback (udpRcv) */ char * pDevice, /* Device (ln, ie, etc.) that we wish to */ /* bind to. */ int unit /* unit number (0, 1, etc.) */ ) { END_OBJ* pEnd; /* initialize the wdbDrvIf field with driver info */ pPktDev->wdbDrvIf.mode = WDB_COMM_MODE_POLL| WDB_COMM_MODE_INT; pPktDev->wdbDrvIf.mtu = WDB_END_PKT_MTU; pPktDev->wdbDrvIf.stackRcv = stackRcv; /* udpRcv */ pPktDev->wdbDrvIf.devId = (WDB_END_PKT_DEV *)pPktDev; pPktDev->wdbDrvIf.pollRtn = wdbEndPoll; pPktDev->wdbDrvIf.pktTxRtn = wdbEndTx; pPktDev->wdbDrvIf.modeSetRtn = wdbEndModeSet; /* initialize the device specific fields in the driver structure */ pPktDev->inputBusy = FALSE; pPktDev->outputBusy = FALSE; /* * Here is where we bind to the lower layer. * We do not, as yet, provide for a shutdown routine, but perhaps * later. * We are a promiscous protocol. * The Int routine a fakeout. Interrupts are handled by the lower * layer but we use a similar mechanism to check packets for * the proper type and hand them off to the WDB agent from * the "interrupt" routine if it's appropriate to do so. */ if ((pPktDev->pCookie = muxBind(pDevice, unit, wdbEndInt, NULL, NULL, NULL, MUX_PROTO_SNARF, "Wind Debug Agent", NULL)) == NULL) { if (wdbEndDebug) logMsg("Could not bind to %s, loading...\n", (int)pDevice, 2, 3, 4, 5, 6); return; } pEnd = (END_OBJ *)pPktDev->pCookie; if ((pInPkt = memalign (4,pEnd->mib2Tbl.ifMtu)) == NULL) return; if ((pPktDev->pInBlk = wdbEndMblkClGet (pEnd, pEnd->mib2Tbl.ifMtu)) == NULL) return; if ((pPktDev->pOutBlk = wdbEndMblkClGet (pEnd, pEnd->mib2Tbl.ifMtu)) == NULL) return; if ((pPktDev->lastHAddr = wdbEndMblkClGet (pEnd, pEnd->mib2Tbl.ifMtu)) == NULL) return; if ((pPktDev->srcAddr = wdbEndMblkClGet (pEnd, pEnd->mib2Tbl.ifMtu)) == NULL) return; /* Set the length to the size of the buffer just allocated. */ pPktDev->pInBlk->mBlkHdr.mLen = pPktDev->pInBlk->pClBlk->clSize; pPktDev->lastHAddr->mBlkHdr.mLen = pEnd->mib2Tbl.ifPhysAddress.addrLength; memset(pPktDev->lastHAddr->mBlkHdr.mData, 0xff, pPktDev->lastHAddr->mBlkHdr.mLen); /* * Create a source address structure so we can send fully * qualified packets. */ muxIoctl(pPktDev->pCookie, EIOCGADDR, pPktDev->srcAddr->mBlkHdr.mData); pEndPktDev = pPktDev; }/******************************************************************************** wdbEndInt - END 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 wdbEndInt ( void * pCookie, long type, M_BLK_ID pMblk, LL_HDR_INFO * pLinkHdrInfo, void * pMode ) { struct mbuf * pMbuf; int size; struct udphdr * pUdpHdr; WDB_END_PKT_DEV * pPktDev = pEndPktDev; /* input buffer already in use - drop this packet */ if (wdbEndDebug) logMsg("Got a packet!\n", 1, 2, 3, 4, 5, 6); if (pPktDev->inputBusy) { if (wdbEndDebug) logMsg("Input busy!\n", 1, 2, 3, 4, 5, 6); netMblkClFree (pMblk); return (FALSE); } pPktDev->inputBusy = TRUE; /* Check the type before doing anything expensive. */ if (type != 0x800) { if (wdbEndDebug) logMsg ("Type != 0x800\n", 1, 2, 3, 4, 5, 6); goto wdbEndIntError; } size = pLinkHdrInfo->dataOffset + IP_HDR_SIZE + sizeof(struct udphdr); if (!(pMblk->mBlkHdr.mFlags & M_PKTHDR) || (pMblk->mBlkPktHdr.len < size)) { goto wdbEndIntError; } if (pMblk->mBlkHdr.mLen < size) { if (netMblkOffsetToBufCopy (pMblk, pLinkHdrInfo->dataOffset, pInPkt, size, NULL) == 0) goto wdbEndIntError; pUdpHdr = (struct udphdr *)(pInPkt + IP_HDR_SIZE); } else { pUdpHdr = (struct udphdr *)(pMblk->mBlkHdr.mData + pLinkHdrInfo->dataOffset + IP_HDR_SIZE); } if (pUdpHdr->uh_dport != htons(WDBPORT)) goto wdbEndIntError; if ((size = netMblkOffsetToBufCopy (pMblk, pLinkHdrInfo->dataOffset, pInPkt, M_COPYALL, NULL)) == 0) goto wdbEndIntError; bcopy((char *)pMblk->mBlkHdr.mData + pLinkHdrInfo->srcAddrOffset, (char *)pPktDev->lastHAddr->mBlkHdr.mData, pLinkHdrInfo->srcSize); /* We're always going to send an IP packet. */ pPktDev->lastHAddr->mBlkHdr.reserved = htons (0x800); /* * Fill the input buffer with the packet. Use an mbuf cluster * to pass the packet on to the agent. */ pMbuf = wdbMbufAlloc(); if (pMbuf == NULL) goto wdbEndIntError; wdbMbufClusterInit (pMbuf, pInPkt, size, (int (*)())wdbEndInputFree, (int)pPktDev); if (wdbEndDebug) logMsg("Passing up a packet!\n", 1, 2, 3, 4, 5, 6); (*pPktDev->wdbDrvIf.stackRcv) (pMbuf); /* invoke callback */ netMblkClFree (pMblk); return (TRUE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -