📄 route.c
字号:
/***********************************************************************//* *//* Module: tcp_ip/ip/route.c *//* Release: 2001.3 *//* Version: 99.0 *//* Purpose: IP Routing Implementation *//* *//*---------------------------------------------------------------------*//* *//* Copyright 1999, Blunk Microsystems *//* ALL RIGHTS RESERVED *//* *//* Licensees have the non-exclusive right to use, modify, or extract *//* this computer program for software development at a single site. *//* This program may be resold or disseminated in executable format *//* only. The source code may not be redistributed or resold. *//* *//***********************************************************************/#include "../tcp_ipp.h"#include "ip.h"/***********************************************************************//* Configuration *//***********************************************************************/#define RT_TSIZE 16 /* number of hash table headers */#define NUM_ROUTES 64 /* maximum number of routes *//***********************************************************************//* Symbol and Macro Definitions *//***********************************************************************/#define RtFree(route) { \ route->next = FreeHead; \ FreeHead = route; \ }/***********************************************************************//* Global Variable Definitions *//***********************************************************************/static Route *RtHead[RT_TSIZE + 1]; /* plus one for default routes */static Route *FreeHead;static Route *CachedRoute;static ui32 CachedAddr;/***********************************************************************//* Local Function Definitions *//***********************************************************************//***********************************************************************//* rthash: compute hash value for "net" *//* *//***********************************************************************/static int rthash(ui32 net){ ui8 hv; /* hash value */ net = ntohl(net); if (IP_CLASSC(net)) hv = (net >> 24) + (net >> 16) + (net >> 8); else if (IP_CLASSB(net)) hv = (net >> 24) + (net >> 16); else if (IP_CLASSA(net)) hv = (net >> 24); else if (IP_CLASSD(net)) return ((net >> 24) & 0xF0) % RT_TSIZE; else return 0; return hv % RT_TSIZE;}/***********************************************************************//* clr_cache: Clear cached routes *//* *//* Input: route = specific route or NULL to clear all routes *//* *//***********************************************************************/static void clr_cache(const Route *route){ SOCKET sock; /*-------------------------------------------------------------------*/ /* Clear socket caches. */ /*-------------------------------------------------------------------*/ if (route) { for (sock = &Socks[0]; sock < &Socks[MAX_NUM_SOCKETS - 1]; ++sock) if (sock->route == route) sock->route = NULL; } else { for (sock = &Socks[0]; sock < &Socks[MAX_NUM_SOCKETS - 1]; ++sock) sock->route = NULL; } /*-------------------------------------------------------------------*/ /* Clear route table cache. */ /*-------------------------------------------------------------------*/ CachedAddr = 0;}/***********************************************************************//* print_entry: Print route table entry *//* *//* Input: route = pointer to entry *//* *//***********************************************************************/static void print_entry(const Route *route){ printf("%08lX %08lX %08lX %-7s ", ntohl(route->gw), ntohl(route->mask), ntohl(route->addr), route->ni->name); if (route->flags & RT_GATEWAY) putchar('G'); if (route->flags & RT_BRDCST) putchar('B'); putchar('\n');}/***********************************************************************//* Global Function Definitions *//***********************************************************************//***********************************************************************//* RtInit: Initialize the routing table *//* *//***********************************************************************/void RtInit(void){ int i; static Route entry[NUM_ROUTES]; /*-------------------------------------------------------------------*/ /* Initially link all routes onto free list. */ /*-------------------------------------------------------------------*/ FreeHead = &entry[0]; for (i = 0; i < NUM_ROUTES; ++i) entry[i].next = &entry[i + 1]; entry[NUM_ROUTES - 1].next = NULL;}/***********************************************************************//* RtAdd: Add a route to the routing table *//* *//* Inputs: gw = gateway address (in network order) *//* mask = address mask (all 1's for host route) *//* addr = host or network address (in network order) *//* ni = interface to gateway *//* flags = RT_BRDCST | RT_GATEWAY *//* *//* Returns: -1 if errors, else 0 *//* *//***********************************************************************/int RtAdd(ui32 gw, ui32 mask, ui32 addr, Ni *ni, int flags){ Route *route; /*-------------------------------------------------------------------*/ /* Verify route table entry is available and allocate it. */ /*-------------------------------------------------------------------*/ if (FreeHead == NULL) { NetError(NULL, ENOBUFS); return -1; } route = FreeHead; FreeHead = FreeHead->next; /*-------------------------------------------------------------------*/ /* Initialize new route. */ /*-------------------------------------------------------------------*/ route->addr = addr; route->mask = mask; route->gw = gw; route->ni = ni; route->flags = flags; /*-------------------------------------------------------------------*/ /* If network address is INADDR_ANY, insert on default list head. */ /*-------------------------------------------------------------------*/ if (addr == htonl(INADDR_ANY)) { route->next = RtHead[RT_TSIZE]; RtHead[RT_TSIZE] = route; route->mask = 0; } /*-------------------------------------------------------------------*/ /* Else insert in hashed slot, putting host routes first. */ /*-------------------------------------------------------------------*/ else { int hv, i; Route *next, *prev = NULL; /*-----------------------------------------------------------------*/ /* Count ones to compute route's queue sort key (corrupts mask). */ /*-----------------------------------------------------------------*/ for (route->key = i = 0; i < 32; ++i) { route->key += (mask & 1); mask >>= 1; } /*-----------------------------------------------------------------*/ /* Find insertion point for new entry in routing table. */ /*-----------------------------------------------------------------*/ hv = rthash(addr); for (next = RtHead[hv]; next; next = next->next) { if (route->key >= next->key) break; prev = next; } /*-----------------------------------------------------------------*/ /* Insert new route in table. */ /*-----------------------------------------------------------------*/ route->next = next; if (prev) prev->next = route; else RtHead[hv] = route; } /*-------------------------------------------------------------------*/ /* Clear cached entries for this route and return success. */ /*-------------------------------------------------------------------*/ clr_cache(NULL); return 0;}/***********************************************************************//* RtDel: Delete route with given gateway, mask, and address *//* *//* Inputs: gw = gateway address (in network order) *//* mask = address mask (all 1's for host route) *//* addr = host or network address (in network order) *//* *//***********************************************************************/int RtDel(ui32 gw, ui32 mask, ui32 addr){ Route *route, *prev; int hv; /*-------------------------------------------------------------------*/ /* Use last table entry for default routes, else hash address. */ /*-------------------------------------------------------------------*/ if (addr == htonl(INADDR_ANY)) { hv = RT_TSIZE; mask = 0; } else hv = rthash(addr); /*-------------------------------------------------------------------*/ /* Lookup route in routing table. */ /*-------------------------------------------------------------------*/ prev = NULL; for (route = RtHead[hv]; route; route = route->next) { if (gw == route->gw && mask == route->mask && addr == route->addr) break; prev = route; } /*-------------------------------------------------------------------*/ /* Error if we didn't find anything. */ /*-------------------------------------------------------------------*/ if (route == NULL) { NetError(NULL, ENETUNREACH); return -1; } /*-------------------------------------------------------------------*/ /* Remove entry from linked list and return to free list. */ /*-------------------------------------------------------------------*/ if (prev) prev->next = route->next; else RtHead[hv] = route->next; clr_cache(route); RtFree(route); return 0;}/***********************************************************************//* RtSearch: Find route to given IP destination *//* *//* Input: dest = destination IP address *//* *//* Returns: Pointer to route structure or NULL *//* *//***********************************************************************/Route *RtSearch(ui32 dest)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -