📄 etherlib.c
字号:
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); }/********************************************************************************* etherInputHookDelete - delete a network interface input hook routine** This routine deletes a network interface input hook.** RETURNS: N/A*/void etherInputHookDelete ( FUNCPTR inputHook, char *pName, int unit ) { HOOK_ENTRY *pHookEnt; HOOK_ENTRY *pTarget = NULL; BOOL unbindFlag = TRUE; /* Remove handler if hook found? */ if (pName != NULL) /* END case */ { for (pHookEnt = (HOOK_ENTRY *)lstFirst(&inputHookList); pHookEnt != NULL; pHookEnt = (HOOK_ENTRY *)lstNext(&pHookEnt->node)) { /* Ignore BSD device hook entries. */ if (pHookEnt->pCookie == NULL) continue; if (STREQ(pHookEnt->name, pName) && (pHookEnt->unit == unit)) { if (pHookEnt->routine == inputHook) { /* * Found matching hook entry to remove. Keep searching * for other hooks on this device if needed. */ pTarget = pHookEnt; if (!unbindFlag) /* Another hook already found? */ break; } else { /* * Different hook on same driver - do not unbind. * Stop searching if target hook entry already found. */ unbindFlag = FALSE; if (pTarget) break; } } } if (pTarget) /* Remove hook entry if match found. */ { if (unbindFlag) /* Remove binding if last hook for device. */ { if (muxTkDrvCheck (pName)) { muxUnbind (pTarget->pCookie, MUX_PROTO_SNARF, nptEtherInputHookRtn); } else { muxUnbind (pTarget->pCookie, MUX_PROTO_SNARF, endEtherInputHookRtn); } } lstDelete (&inputHookList, &pTarget->node); free (pTarget); } } else /* 4.4 case */ { for (pHookEnt = (HOOK_ENTRY *)lstFirst(&inputHookList); pHookEnt != NULL; pHookEnt = pTarget) { if (pHookEnt->pCookie) /* Ignore END device hook entries. */ continue; pTarget = (HOOK_ENTRY *)lstNext(&pHookEnt->node); if (pHookEnt->routine == inputHook) { lstDelete(&inputHookList, &pHookEnt->node); free(pHookEnt); } } } if (lstCount(&inputHookList) <= 0) { etherInputHookActive = FALSE; /* No END driver hooks installed. */ etherInputHookRtn = NULL; /* No BSD driver hooks installed. */ lstFree (&inputHookList); } }/********************************************************************************* etherOutputHookAdd - add a routine to receive all Ethernet output packets** This routine adds a hook routine that will be called for every Ethernet* packet that is transmitted.** The calling sequence of the output hook routine is:* .CS* BOOL outputHook* (* struct ifnet *pIf, /@ interface packet will be sent on @/* char *buffer, /@ packet to transmit @/* int length /@ length of packet to transmit @/* )* .CE* The hook is called immediately before transmission. The hook routine* should return TRUE if it has handled the output packet and no further* action should be taken with it. It should return FALSE if it has not* handled the output packet and normal transmission should take place.** The Ethernet packet data is in a temporary buffer when the hook routine* is called. This buffer will be reused upon return from the hook. If* the hook routine needs to retain the output packet, it should be copied* elsewhere.** IMPLEMENTATION* A call to the function pointed to be the global function pointer* `etherOutputHookRtn' should be invoked in the transmit routine of every* network driver providing this service. For example:* .ne 14* .CS* ...* #include "etherLib.h"* ...* xxxStartOutput ()* /@ call output hook if any @/* if ((etherOutputHookRtn != NULL) &&* (* etherOutputHookRtn) (&ls->ls_if, buf0, len))* {* /@ output hook has already processed this packet @/* }* else* ...* .CE** RETURNS: OK if the hook was added, or ERROR otherwise.*/STATUS etherOutputHookAdd ( FUNCPTR outputHook /* routine to receive Ethernet output */ ) { HOOK_ENTRY *pHookEnt; pHookEnt = malloc(sizeof(HOOK_ENTRY)); if (pHookEnt == NULL) return (ERROR); if (etherOutputHookRtn == NULL) { etherOutputHookRtn = etherOutputHook; lstInit(&outputHookList); } pHookEnt->routine = outputHook; lstAdd(&outputHookList, &pHookEnt->node); return (OK); }/********************************************************************************* etherOutputHookDelete - delete a network interface output hook routine** This routine deletes a network interface output hook, which must be supplied* as the only argument.** RETURNS: N/A*/void etherOutputHookDelete ( FUNCPTR outputHook ) { HOOK_ENTRY *pHookEnt; extern LIST outputHookList; NODE index; for (pHookEnt = (HOOK_ENTRY *)lstFirst(&outputHookList); pHookEnt != NULL; pHookEnt = (HOOK_ENTRY *)lstNext(&index)) { index = pHookEnt->node; if (pHookEnt->routine == outputHook) { lstDelete(&outputHookList, &pHookEnt->node); free(pHookEnt); } } if (lstCount(&outputHookList) <= 0) { etherOutputHookRtn = NULL; lstFree(&outputHookList); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -