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); } }
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); } }
LOCAL BOOL nptEtherInputHookRtn ( void * pCallBackId, /* Sent down in muxTkBind(); same as pSpare as in muxBind() */ long type, /* SNARF */ M_BLK_ID pMblk, /* Received frame (with link-level header). */ void * pSpareData /* Extra protocol data */ ) { HOOK_ENTRY * pHookEnt = (HOOK_ENTRY*) pCallBackId; char devName[32]; char packetData [ETHERMTU + SIZEOF_ETHERHEADER]; struct ifnet fakeIF; extern LIST inputHookList; int flags; int len; END_OBJ* pEnd=PCOOKIE_TO_ENDOBJ(pHookEnt->pCookie); int ifHdrLen=0; bzero ( (char *)&fakeIF, sizeof (fakeIF)); fakeIF.if_name = &devName[0]; strcpy (fakeIF.if_name, pEnd->devObject.name); fakeIF.if_unit = pEnd->devObject.unit; muxIoctl (pHookEnt->pCookie, EIOCGFLAGS, (caddr_t)&flags); fakeIF.if_flags = flags; /* Get the Link Level header length . */ if (muxIoctl (pHookEnt->pCookie, EIOCGHDRLEN, (caddr_t)&ifHdrLen) != OK) fakeIF.if_hdrlen = 0; else fakeIF.if_hdrlen = (UCHAR)ifHdrLen; len = netMblkToBufCopy(pMblk, (char *)packetData, NULL); for (pHookEnt = (HOOK_ENTRY *)lstFirst (&inputHookList); pHookEnt != NULL; pHookEnt = (HOOK_ENTRY *)lstNext (&pHookEnt->node)) { if ( (* pHookEnt->routine) (&fakeIF, packetData, len)) { netMblkClChainFree (pMblk); /* hook has consumed the packet */ return (TRUE); } } return (FALSE); }
int devIocStatsGetIFErrors (ifErrInfo *pval) { struct ifnet *ifp; /* add all interfaces' errors */ #if _WRS_VXWORKS_MAJOR >= 6 #if 0 /* FIXME: There is no implementation for vxWorks 6!! */ TAILQ_FOREACH(ifp, (&ifnet_head), if_link) #else return -1; #endif #else for (ifp = ifnet; ifp != NULL; ifp = ifp->if_next) { #ifdef END_MIB_2233 /* This is defined in end.h if 2233 drivers are supported on the OS */ /* This block localizes the 2233 variables so we wont get unused variable warnings */ IP_DRV_CTRL * pDrvCtrl = NULL; END_OBJ * pEnd=NULL; /* Dig into the structure */ pDrvCtrl = (IP_DRV_CTRL *)ifp->pCookie; /* Get a pointer to the driver's data if there is one */ if (pDrvCtrl) pEnd = PCOOKIE_TO_ENDOBJ(pDrvCtrl->pIpCookie); /* If we have an end driver and it is END_MIB_2233 then we look in the m2Data structure for the errors. */ if (pEnd && (pEnd->flags & END_MIB_2233)) { M2_DATA *pIfMib = &pEnd->pMib2Tbl->m2Data; pval->ierrors += pIfMib->mibIfTbl.ifInErrors; pval->oerrors += pIfMib->mibIfTbl.ifOutErrors; } else { /* We get the errors the old way */ pval->ierrors += ifp->if_ierrors; pval->oerrors += ifp->if_oerrors; } #else /* ifdef END_MIB_2233 */ pval->ierrors += ifp->if_ierrors; pval->oerrors += ifp->if_oerrors; #endif /* ifdef END_MIB_2233 */ } #endif return 0; }
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); }
STATUS 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; char ifname [20]; char inetAdrs [24]; /* 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; #ifndef STANDALONE_AGENT /* * 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. */ #ifdef WDB_NPT_CAPABLE if (muxTkDrvCheck (pDevice) == TRUE) { if ((pPktDev->pCookie = muxTkBind (pDevice, unit, wdbNptInt, (FUNCPTR)wdbNptShutdown, NULL, NULL, MUX_PROTO_SNARF, "Wind Debug Agent", NULL, NULL, NULL)) == NULL) { if (wdbEndDebug) logMsg ("Could not bind to NPT Device %s, loading...\n", (int)pDevice, 2, 3, 4, 5, 6); return (ERROR); } } else /* END */ { if (wdbEndDebug) logMsg ("Not a NPT device! %s\n", (int)pDevice,2,3,4,5,6); #endif /* WDB_NPT_CAPABLE */ 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 (ERROR); } #ifdef WDB_NPT_CAPABLE } #endif /* WDB_NPT_CAPABLE */ pEnd = PCOOKIE_TO_ENDOBJ(pPktDev->pCookie); #else /* STANDALONE_AGENT */ /* * for standalone agent, we simply need to get the address of the * of the device. */ if ((pPktDev->pCookie = endFindByName (pDevice, unit)) == NULL) return (ERROR); #endif /* STANDALONE_AGENT */ /* build interface name */ sprintf (ifname, "%s%d", pDevice, unit); /* get interface inet address */ if (ifAddrGet (ifname, inetAdrs) != OK) { if (wdbEndDebug) logMsg ("Could not get inet address of %s interface...\n", (int) ifname, 2, 3, 4, 5, 6); return (ERROR); } pPktDev->ipAddr.s_addr = inet_addr (inetAdrs); pEnd = PCOOKIE_TO_ENDOBJ(pPktDev->pCookie); if ((pInPkt = memalign (4,pEnd->mib2Tbl.ifMtu)) == NULL) return (ERROR); if ((pPktDev->pInBlk = wdbEndMblkClGet (pEnd, pEnd->mib2Tbl.ifMtu)) == NULL) return (ERROR); pPktDev->pInBlk->mBlkHdr.mFlags |= M_PKTHDR; if ((pPktDev->pOutBlk = wdbEndMblkClGet (pEnd, pEnd->mib2Tbl.ifMtu)) == NULL) return (ERROR); pPktDev->pOutBlk->mBlkHdr.mFlags |= M_PKTHDR; if ((pPktDev->lastHAddr = wdbEndMblkClGet (pEnd, pEnd->mib2Tbl.ifMtu)) == NULL) return (ERROR); if ((pPktDev->srcAddr = wdbEndMblkClGet (pEnd, pEnd->mib2Tbl.ifMtu)) == NULL) return (ERROR); /* 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; return (OK); }