📄 route.c
字号:
{ static Route *route; int hv; /*-------------------------------------------------------------------*/ /* Check if cached route matches. */ /*-------------------------------------------------------------------*/ if (dest == CachedAddr) { ++Stats.RouteCacheHits; return CachedRoute; } /*-------------------------------------------------------------------*/ /* Hash destination address to get routing table key. */ /*-------------------------------------------------------------------*/ hv = rthash(dest); /*-------------------------------------------------------------------*/ /* Search routing table for matching network address. */ /*-------------------------------------------------------------------*/ for (route = RtHead[hv]; route; route = route->next) if ((dest & route->mask) == (route->addr & route->mask)) break; /*-------------------------------------------------------------------*/ /* If not found, try default route. */ /*-------------------------------------------------------------------*/ if (route == NULL) route = RtHead[RT_TSIZE]; /*-------------------------------------------------------------------*/ /* If route exists, cache it. */ /*-------------------------------------------------------------------*/ if (route) { CachedAddr = dest; CachedRoute = route; } return route;}/***********************************************************************//* RtDump: Dump routing table to stdout *//* *//* Note: Assumes internal semaphore is help by caller *//* *//***********************************************************************/void RtDump(void){ int i; Route *route; /*-------------------------------------------------------------------*/ /* Cycle through route table, displaying all routes. */ /*-------------------------------------------------------------------*/ printf("gateway mask net/host intf flags\n"); for (i = 0; i <= RT_TSIZE; ++i) { for (route = RtHead[i]; route; route = route->next) print_entry(route); }}/***********************************************************************//* NiRtDel: Remove all routes using specified network interface *//* *//* Input: ni = network interface being removed *//* *//* Note: Assumes internal semaphore is help by caller *//* *//***********************************************************************/void NiRtDel(Ni *ni){ int i, hv, changed; Route *route, *prev, *temp; /*-------------------------------------------------------------------*/ /* Cycle through table to remove local routes using specified NI. */ /*-------------------------------------------------------------------*/ for (i = 0; i <= RT_TSIZE; ++i) { for (prev = NULL, route = RtHead[i]; route;) { if (((route->flags & RT_GATEWAY) == FALSE) && ((route->ni == ni) || ((route->ni == &Net.Local) && (route->addr == ni->ip_addr)))) { /*-------------------------------------------------------------*/ /* Route must be removed. */ /*-------------------------------------------------------------*/ temp = route; route = route->next; if (prev) prev->next = route; else RtHead[i] = route; RtFree(temp); } else { prev = route; route = route->next; } } } /*-------------------------------------------------------------------*/ /* Remove or adjust routes until none remain using specified NI. */ /*-------------------------------------------------------------------*/ do { /*-----------------------------------------------------------------*/ /* Cycle through all routes in hash table. */ /*-----------------------------------------------------------------*/ for (changed = FALSE, i = 0; i <= RT_TSIZE; ++i) { for (prev = NULL, route = RtHead[i]; route;) { /*-------------------------------------------------------------*/ /* Skip entry if it doesn't use the specified NI. */ /*-------------------------------------------------------------*/ if (route->ni != ni) { prev = route; route = route->next; continue; } /*-------------------------------------------------------------*/ /* Else the entry needs to be deleted or adjusted. */ /*-------------------------------------------------------------*/ else changed = TRUE; /*-------------------------------------------------------------*/ /* Hash gateway address to find correct routing table slot. */ /*-------------------------------------------------------------*/ hv = rthash(route->gw); /*-------------------------------------------------------------*/ /* Search hashed slot for matching network address. */ /*-------------------------------------------------------------*/ for (temp = RtHead[hv]; temp; temp = temp->next) if ((route->gw & temp->mask) == (temp->addr & temp->mask)) break; /*-------------------------------------------------------------*/ /* If gateway reachable through another NI, just update entry. */ /*-------------------------------------------------------------*/ if (temp) { route->ni = temp->ni; prev = route; route = route->next; } /*-------------------------------------------------------------*/ /* Else the entry should be removed. */ /*-------------------------------------------------------------*/ else { temp = route; route = route->next; if (prev) prev->next = route; else RtHead[RT_TSIZE] = route; RtFree(temp); } } } } while (changed); /*-------------------------------------------------------------------*/ /* Clear all cached routes. */ /*-------------------------------------------------------------------*/ clr_cache(NULL); /*-------------------------------------------------------------------*/ /* Clear "up" flag and, if installed, call event callback function. */ /*-------------------------------------------------------------------*/ ni->flags &= ~NIF_UP; if (ni->report) ni->report(ni, NIE_DOWN);}/***********************************************************************//* tcpAddRoute: Add route to routing table *//* *//* Inputs: gw = address of a reachable gateway (in network order) *//* addr = network or host address (in network order) *//* mask = address address (all 1's for host route) *//* *//* Note: If network address is NULL, adding default route *//* *//* Returns: -1 if errors, else 0 *//* *//***********************************************************************/int tcpAddRoute(ui32 gw, ui32 addr, ui32 mask){ Route *route; int rc; /*-------------------------------------------------------------------*/ /* Verify protocol has been initialized. */ /*-------------------------------------------------------------------*/ if (!Net.Initialized) { NetError(NULL, ENETDOWN); return -1; } /*-------------------------------------------------------------------*/ /* Acquire exclusive access to protocol internals. */ /*-------------------------------------------------------------------*/ semPend(Net.IntSem, WAIT_FOREVER); /*-------------------------------------------------------------------*/ /* Check if gateway is unreachable. */ /*-------------------------------------------------------------------*/ route = RtSearch(gw); if (route == NULL) { NetError(NULL, EHOSTUNREACH); rc = -1; goto err_exit; } /*-------------------------------------------------------------------*/ /* Ensure old default gateway is not being used to reach new. */ /*-------------------------------------------------------------------*/ if ((addr == htonl(INADDR_ANY)) && (route == RtHead[RT_TSIZE])) { NetError(NULL, EHOSTUNREACH); rc = -1; goto err_exit; } /*-------------------------------------------------------------------*/ /* Add gateway route to routing table. */ /*-------------------------------------------------------------------*/ rc = RtAdd(gw, mask, addr, route->ni, RT_GATEWAY); /*-------------------------------------------------------------------*/ /* Release access to protocol internals. */ /*-------------------------------------------------------------------*/err_exit: semPost(Net.IntSem); return rc;}/***********************************************************************//* tcpDelRoute: Delete route from routing table *//* *//* Inputs: gw = gateway address *//* addr = host or network address *//* mask = address mask (all 1's for host route) *//* *//* Returns: -1 if errors, else 0 *//* *//***********************************************************************/int tcpDelRoute(ui32 gw, ui32 addr, ui32 mask){ int rc; /*-------------------------------------------------------------------*/ /* Verify protocol has been initialized. */ /*-------------------------------------------------------------------*/ if (!Net.Initialized) { NetError(NULL, ENETDOWN); return -1; } /*-------------------------------------------------------------------*/ /* Acquire exclusive access to protocol internals. */ /*-------------------------------------------------------------------*/ semPend(Net.IntSem, WAIT_FOREVER); /*-------------------------------------------------------------------*/ /* Remove from routing table. */ /*-------------------------------------------------------------------*/ rc = RtDel(gw, mask, addr); /*-------------------------------------------------------------------*/ /* Release access to protocol internals. */ /*-------------------------------------------------------------------*/ semPost(Net.IntSem); return rc;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -