📄 riplib.c
字号:
** The hook uses the following interface:* .CS* STATUS ripLeakHookRtn (long dest, long gateway, long netmask)* .CE** The RIP session will not add the given route to any tables if the hook* routine returns OK, but will create a route entry otherwise.** The ripLeakHookDelete() will allow the RIP session to add new routes* unconditionally.** RETURNS: OK, or ERROR if the interface could not be found.** ERRNO:* S_m2Lib_INVALID_PARAMETER* S_m2Lib_ENTRY_NOT_FOUND*/STATUS ripLeakHookAdd ( char * pIpAddr, /* IP address in dotted decimal notation */ FUNCPTR pLeakHook /* function pointer to hook */ ) { struct interface* pIfp; struct sockaddr_in address; if (!ripInitFlag) return (ERROR); if (pIpAddr == NULL) { errnoSet(S_m2Lib_INVALID_PARAMETER); return (ERROR); } address.sin_addr.s_addr = inet_addr(pIpAddr); address.sin_family = AF_INET; pIfp = ripIfLookup((struct sockaddr *)&address); if (pIfp == NULL) { errnoSet(S_m2Lib_ENTRY_NOT_FOUND); return (ERROR); } /* Short critical section with message and timer processing. */ semTake (ripLockSem, WAIT_FOREVER); pIfp->leakHook = pLeakHook; semGive (ripLockSem); return (OK); }/******************************************************************************** ripLeakHookDelete - remove a table bypass hook from a RIP interface** This routine removes the assigned bypass hook from a registered interface* indicated by <pIpAddr>. (Interfaces created or changed after a RIP* session has started may be installed/updated with the ripIfSearch() * and ripIfReset() routines). The RIP session will return to the default * behavior and add entries to the internal RIP table and kernel routing * table unconditionally.** RETURNS: OK, or ERROR if the interface could not be found.** ERRNO:* S_m2Lib_INVALID_PARAMETER* S_m2Lib_ENTRY_NOT_FOUND*/STATUS ripLeakHookDelete ( char* pIpAddr /* IP address in dotted decimal notation */ ) { struct interface* pIfp; struct sockaddr_in address; if (!ripInitFlag) return (ERROR); if (pIpAddr == NULL) { errnoSet(S_m2Lib_INVALID_PARAMETER); return (ERROR); } address.sin_addr.s_addr = inet_addr(pIpAddr); address.sin_family = AF_INET; pIfp = ripIfLookup((struct sockaddr *)&address); if (pIfp == NULL) { errnoSet(S_m2Lib_ENTRY_NOT_FOUND); return (ERROR); } /* Short critical section with message and timer processing. */ semTake (ripLockSem, WAIT_FOREVER); pIfp->leakHook = NULL; semGive (ripLockSem); return (OK); }/******************************************************************************** ripLeakHook - sample leak hook for RIP routes** This routine prevents any routes from being added to the internal RIP* table or kernel routing table, and prints the information that was passed * to it.** RETURNS: OK** NOMANUAL*/STATUS ripLeakHook ( long dest, long gate, long mask ) { printf ("Destination %lx\tGateway %lx\tMask %lx\n", dest, gate, mask); return (OK); }/******************************************************************************** ripSendHookAdd - add an update filter to a RIP interface** This routine installs a hook routine to screen individual route entries* for inclusion in a periodic update. The routine is installed for the* registered interface given by <pIpAddr>. (Interfaces created or* changed after a RIP session has started may be installed/updated with * the ripIfSearch() and ripIfReset() routines).** The hook uses the following prototype:* .CS* BOOL ripSendHookRtn (struct rt_entry* pRt);* .CE** If the hook returns FALSE, the route is not included in the update.* Otherwise, it is included if it meets the other restrictions, such* as simple split horizon and border gateway filtering. The * ripSendHookDelete() routine removes this additional filter from the* output processing.** RETURNS: OK, or ERROR if the interface could not be found.** ERRNO:* S_m2Lib_INVALID_PARAMETER* S_m2Lib_ENTRY_NOT_FOUND*/STATUS ripSendHookAdd ( char* pIpAddr, /* IP address in dotted decimal notation */ BOOL (*ripSendHook) (struct rt_entry* pRt) /* Routine to use. */ ) { struct interface* pIfp; struct sockaddr_in address; if (!ripInitFlag) return (ERROR); if (pIpAddr == NULL) { errnoSet(S_m2Lib_INVALID_PARAMETER); return (ERROR); } address.sin_addr.s_addr = inet_addr(pIpAddr); address.sin_family = AF_INET; pIfp = ripIfLookup((struct sockaddr *)&address); if (pIfp == NULL) { errnoSet(S_m2Lib_ENTRY_NOT_FOUND); return (ERROR); } /* Short critical section with output processing. */ semTake (ripLockSem, WAIT_FOREVER); pIfp->sendHook = ripSendHook; semGive (ripLockSem); return (OK); }/******************************************************************************** ripSendHookDelete - remove an update filter from a RIP interface** This routine removes the hook routine that allowed additional screening* of route entries in periodic updates from the registered interface* indicated by <pIpAddr>. (Interfaces created or changed after a RIP * session has started may be installed/updated with the ripIfSearch() * and ripIfReset() routines). The RIP session will return to the default * behavior and include any entries which meet the other restrictions (such * as simple split horizon).** RETURNS: OK, or ERROR if the interface could not be found.** ERRNO:* S_m2Lib_INVALID_PARAMETER* S_m2Lib_ENTRY_NOT_FOUND*/STATUS ripSendHookDelete ( char* pIpAddr /* IP address in dotted decimal notation */ ) { struct interface* pIfp; struct sockaddr_in address; if (!ripInitFlag) return (ERROR); if (pIpAddr == NULL) { errnoSet(S_m2Lib_INVALID_PARAMETER); return (ERROR); } address.sin_addr.s_addr = inet_addr(pIpAddr); address.sin_family = AF_INET; pIfp = ripIfLookup((struct sockaddr *)&address); if (pIfp == NULL) { errnoSet(S_m2Lib_ENTRY_NOT_FOUND); return (ERROR); } /* Short critical section with output processing. */ semTake (ripLockSem, WAIT_FOREVER); pIfp->sendHook = NULL; semGive (ripLockSem); return (OK); }/******************************************************************************** ripSendHook - sample send hook for rip routes** This routine displays all the routes that are being sent and returns OK* so that they are included in the update if all other criteria are met.** RETURNS: OK** NOMANUAL*/BOOL ripSendHook ( struct rt_entry* pRt ) { char address[32]; struct sockaddr_in* dSin; struct sockaddr_in* gSin; struct sockaddr_in* nSin; ripRouteToAddrs(pRt, &dSin, &gSin, &nSin); inet_ntoa_b(dSin->sin_addr, (char *)&address); printf("Route to %s ", address); inet_ntoa_b(gSin->sin_addr, (char *)&address); printf("with gateway %s ", address); inet_ntoa_b(nSin->sin_addr, (char *)&address); printf("and netmask %s being sent.\n", address); return (OK); }/******************************************************************************** ripIfSearch - add new interfaces to the internal list** By default, a RIP session will not recognize any interfaces initialized* after it has started. This routine schedules a search for additional* interfaces which will occur during the next update of the internal routing* table. Once completed, the session will accept and send RIP messages over* the new interfaces.** RETURNS: N/A** ERRNO: N/A** INTERNAL* This routine just sets the flag tested by the watchdog timer handler* to trigger a search. Mutual exclusion with that thread is not necessary* in this case, since any change will correctly begin the search, which* is not time sensitive. However, the actual search routine must lock out * all other processing.*/void ripIfSearch (void) { if (!ripInitFlag) return; ripState.lookforinterfaces = TRUE; }/******************************************************************************** ripIfReset - alter the RIP configuration after an interface changes** This routine updates the interface list and routing tables to reflect* address and/or netmask changes for the device indicated by <pIfName>. * To accommodate possible changes in the network number, all routes using * the named interface are removed from the routing tables, but will be* added in the next route update if appropriate. None of the removed* routes are poisoned, so it may take some time for the routing tables of* all the RIP participants to stabilize if the network number has changed.** RETURNS: OK, or ERROR if named interface not found or not added to list.** ERRNO: N/A** INTERNAL* This routine uses the mutex semaphore to block all other RIP processing* until the data structures are in a stable state. The internal RIP routing* table and the kernel routing table will be updated after it returns. If* the network number did not change, all the removed routes received from* other RIP sessions are still valid and will be added by the next update.*/STATUS ripIfReset ( char * pIfName /* name of changed interface */ ) { struct interface * pIf; /* Target interface entry, if found. */ struct interface * pPrevIf; /* Previous interface entry. */ struct rthash * pHashList; /* Individual hash table entry. */ struct rt_entry * pRt; /* Individual route entry. */ int slen; int tlen; STATUS result; if (!ripInitFlag) return (ERROR); if (pIfName == NULL) return (ERROR); slen = strlen (pIfName); if (slen == 0) return (ERROR); /* * Block access to all processing while updating the interface * list and routing tables. */ semTake (ripLockSem, WAIT_FOREVER); pPrevIf = ripIfNet; for (pIf = ripIfNet; pIf; pIf = pIf->int_next) { tlen = strlen (pIf->int_name); /* * Ignore names of different lengths to prevent a false match * between overlapping unit numbers such as "ln1" and "ln10". */ if (tlen != slen) continue; if (strcmp (pIfName, pIf->int_name) == 0) break; pPrevIf = pIf; } if (pIf == NULL) { semGive (ripLockSem); return (ERROR); } /* * Remove any routes associated with the changed interface from * both hash tables. */ for (pHashList = hosthash; pHashList < &hosthash [ROUTEHASHSIZ]; pHashList++) { pRt = pHashList->rt_forw; for (; pRt != (struct rt_entry *)pHashList; pRt = pRt->rt_forw) { if (p
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -