int et_drvTxRxInit(char * dev, int unit) { if (et_drv_txrx_info[unit].et_drvMuxBindID != NULL) { return -1; } et_drv_txrx_info[unit].queue_rx_pkts = 0; et_drvTxRxNetpoolCreate(unit); /* Bind et_drvTxRx Network service to the END driver. */ et_drv_txrx_info[unit].et_drvMuxBindID = (void *) muxBind( dev, unit, et_drvRecv, NULL, NULL, NULL, MUX_PROTO_SNARF, "ET_DRV TX/RX", NULL); if (!et_drv_txrx_info[unit].et_drvMuxBindID) { logMsg("muxTkBind Failed (%08x).\n", errnoGet(), 2, 3, 4, 5, 6); return -1; } /* Promiscuous mode */ muxIoctl( et_drv_txrx_info[unit].et_drvMuxBindID, EIOCSFLAGS, (void *)IFF_PROMISC); return 0; }
STATUS etherInputHookAdd ( FUNCPTR inputHook, /* routine to receive Ethernet input */ char* pName, /* name of device if MUX/END is being used */ int unit /* unit of device if MUX/END is being used */ ) { HOOK_ENTRY *pHookEnt; HOOK_ENTRY *pHookCurr; void * pBinding = NULL; /* Existing END device binding, if any. */ BOOL tkDevice=FALSE; if (pName != NULL) /* We are dealing with an END. */ { if (etherInputHookActive == FALSE) /* First END driver hook? */ { if (etherInputHookRtn == NULL) { /* Initialize list - first network driver of either type. */ lstInit (&inputHookList); } etherInputHookActive = TRUE; } /* Check if bind is necessary and eliminate duplicate hook routine. */ for (pHookCurr = (HOOK_ENTRY *)lstFirst(&inputHookList); pHookCurr != NULL; pHookCurr = (HOOK_ENTRY *)lstNext(&pHookCurr->node)) { /* Ignore BSD device hook entries. */ if (pHookCurr->pCookie == NULL) continue; if (STREQ(pHookCurr->name, pName) && (pHookCurr->unit == unit)) { if (pHookCurr->routine == inputHook) return (ERROR); /* Additional hook for same device - reuse binding. */ pBinding = pHookCurr->pCookie; } } pHookEnt = malloc (sizeof (HOOK_ENTRY)); if (pHookEnt == NULL) return (ERROR); bzero ( (char *)pHookEnt, sizeof (HOOK_ENTRY)); if (pBinding == NULL) /* No hook entry for this END device? */ { /* Attach Ethernet input hook handler for this device. */ tkDevice = muxTkDrvCheck (pName); if (tkDevice) { pBinding = muxTkBind (pName, unit, nptEtherInputHookRtn, NULL, NULL, NULL, MUX_PROTO_SNARF, "etherInputHook", pHookEnt, NULL, NULL); } else { pBinding = muxBind (pName, unit, endEtherInputHookRtn, NULL, NULL, NULL, MUX_PROTO_SNARF, "etherInputHook", pHookEnt); } if (pBinding == NULL) { free (pHookEnt); return (ERROR); } } /* * Assign (new or existing) handler attachment for the device, * allowing hook deletion in any order. */ pHookEnt->pCookie = pBinding; strcpy (pHookEnt->name, pName); pHookEnt->unit = unit; pHookEnt->routine = inputHook; lstAdd (&inputHookList, &pHookEnt->node); } else /* Old style driver. */ { /* Check for duplicate hook routine. */ for (pHookCurr = (HOOK_ENTRY *)lstFirst(&inputHookList); pHookCurr != NULL; pHookCurr = (HOOK_ENTRY *)lstNext(&pHookCurr->node)) { if (pHookCurr->pCookie) /* Ignore END device hook entries. */ continue; if (pHookCurr->routine == inputHook) return (ERROR); } pHookEnt = malloc(sizeof(HOOK_ENTRY)); if (pHookEnt == NULL) return (ERROR); bzero ( (char *)pHookEnt, sizeof (HOOK_ENTRY)); if (etherInputHookRtn == NULL) /* First BSD driver hook? */ { etherInputHookRtn = etherInputHook; if (!etherInputHookActive) { /* Initialize list - first network driver of either type. */ lstInit (&inputHookList); } } pHookEnt->routine = inputHook; lstAdd(&inputHookList, &pHookEnt->node); } 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); }