📄 tables.c
字号:
/* tables.c - routines for managing RIP internal routing table *//* Copyright 1984 - 1999 Wind River Systems, Inc. */#include "copyright_wrs.h"/* * Copyright (c) 1983, 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * @(#)tables.c 8.2 (Berkeley) 4/28/95 *//*modification history--------------------01m,16mar99,spm recovered orphaned code from tor1_0_1.sens1_1 (SPR #25770)01l,29sep98,spm added support for IP group MIB (SPR #9374); removed unneeded routine (SPR #21109).01k,11sep98,spm moved mutual exclusion semaphore to prevent any collisions between RIP tasks (SPR #22350), removed all references to bloated trace commands (SPR #22350)01j,01sep98,spm corrected processing of RIPv2 route updates to support version changes (SPR #22158); added support for default routes (SPR #22067)01i,26jul98,spm removed compiler warnings01h,06oct97,gnn fixed insque/remque casting bug and cleaned up warnings01g,12aug97,gnn fixed prototypes for mRouteEntryDelete().01f,15may97,gnn added code to implement route leaking.01e,14apr97,gnn fixed calls to mRouteEntryAdd to follow Rajesh's changes.01d,07apr97,gnn cleared up some of the more egregious warnings. added MIB-II interfaces and options.01c,24feb97,gnn added rip version 2 functionality.01b,05dec96,gnn changed insque/remque to _insque/_remque for compatability.01a,26nov96,gnn created from BSD4.4 routed*//*DESCRIPTION*//* * Routing Table Management Daemon */#include "vxWorks.h"#include "rip/defs.h"#include "sys/ioctl.h"#include "netinet/in.h"#include "routeLib.h"#include "errno.h"#include "inetLib.h"#include "semLib.h"#include "logLib.h"#include "m2Lib.h" #include "stdlib.h"#ifndef DEBUG#define DEBUG 0#endif#ifdef RTM_ADD#define FIXLEN(s) {if ((s)->sa_len == 0) (s)->sa_len = sizeof *(s);}#else#define FIXLEN(s) { }#endif/* forward declarations */IMPORT void _insque (NODE* pNode, NODE* pPrev);IMPORT void _remque (NODE* pNode);IMPORT int routedDebug;/* * Lookup dst in the tables for an exact match. */struct rt_entry *rtlookup(dst) struct sockaddr *dst;{ register struct rt_entry *rt; register struct rthash *rh; register u_int hash; struct sockaddr target; struct afhash h; int doinghost = 1; if (dst->sa_family >= af_max) return (0); (*afswitch[dst->sa_family].af_hash)(dst, &h); hash = h.afh_hosthash; rh = &hosthash[hash & ROUTEHASHMASK]; /* * The equal() comparison within the following loop expects all * members of the structure except the family, length, and address * fields to be zero. This condition may not be met when processing a * RIPv2 packet. In that case, the destination passed to this routine * accesses a route within the payload of a RIP message, so some * fields of the overlayed structure will not be zero as expected. * Duplicate or incorrect routes will be added because matching routes * are not detected. To avoid this problem, copy the required fields * from the route destination value to a clean structure. */ bzero ( (char *)&target, sizeof (struct sockaddr)); target.sa_family = dst->sa_family; target.sa_len = dst->sa_len; ((struct sockaddr_in *)&target)->sin_addr.s_addr = ((struct sockaddr_in *)dst)->sin_addr.s_addr; again: for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) { if (rt->rt_hash != hash) continue; if (equal(&rt->rt_dst, &target)) return (rt); } if (doinghost) { doinghost = 0; hash = h.afh_nethash; rh = &nethash[hash & ROUTEHASHMASK]; goto again; } return (0);}struct sockaddr wildcard; /* zero valued cookie for wildcard searches *//* * Find a route to dst as the kernel would. */struct rt_entry *rtfind(dst) struct sockaddr *dst;{ register struct rt_entry *rt; register struct rthash *rh; register u_int hash; struct sockaddr target; struct afhash h; int af = dst->sa_family; int doinghost = 1; int (*match)() = NULL; /* Assigned later for network hash search. */ if (af >= af_max) return (0); (*afswitch[af].af_hash)(dst, &h); hash = h.afh_hosthash; rh = &hosthash[hash & ROUTEHASHMASK]; /* * The equal() comparison within the following loop expects all * members of the structure except the family, length, and address * fields to be zero. This condition may not be met when processing a * RIPv2 packet. In that case, the destination passed to this routine * accesses a route within the payload of a RIP message, so some * fields of the overlayed structure will not be zero as expected, * and existing host routes would be missed. To avoid this problem, * copy the required fields from the route destination value to a * clean structure. */ bzero ( (char *)&target, sizeof (struct sockaddr)); target.sa_family = dst->sa_family; target.sa_len = dst->sa_len; ((struct sockaddr_in *)&target)->sin_addr.s_addr = ((struct sockaddr_in *)dst)->sin_addr.s_addr; again: for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) { if (rt->rt_hash != hash) continue; if (doinghost) { if (equal(&rt->rt_dst, &target)) return (rt); } else { if (rt->rt_dst.sa_family == af && (*match)(&rt->rt_dst, dst)) return (rt); } } if (doinghost) { doinghost = 0; hash = h.afh_nethash; rh = &nethash[hash & ROUTEHASHMASK]; match = afswitch[af].af_netmatch; goto again; }#ifdef notyet /* * Check for wildcard gateway, by convention network 0. */ if (dst != &wildcard) { dst = &wildcard, hash = 0; goto again; }#endif return (0);}STATUS rtadd ( struct sockaddr *dst, struct sockaddr *gate, int metric, int state, struct sockaddr *netmask ) { struct afhash h; register struct rt_entry *rt; struct rthash *rh; int af = dst->sa_family, flags; struct sockaddr_in* pDsin; struct sockaddr_in* pGsin; struct sockaddr_in* pNsin; u_int hash; struct interface* pIfp; IMPORT RIP ripState; if (af >= af_max) return (ERROR); (*afswitch[af].af_hash)(dst, &h); flags = (*afswitch[af].af_rtflags)(dst); /* * Subnet flag isn't visible to kernel, move to state. XXX */ FIXLEN(dst); FIXLEN(gate); if (flags & RTF_SUBNET) { state |= RTS_SUBNET; flags &= ~RTF_SUBNET; } if (flags & RTF_HOST) { hash = h.afh_hosthash; rh = &hosthash[hash & ROUTEHASHMASK]; } else { hash = h.afh_nethash; rh = &nethash[hash & ROUTEHASHMASK]; } rt = (struct rt_entry *)malloc(sizeof (*rt)); if (rt == 0) return (ERROR); rt->pKernelRt = NULL; rt->rt_hash = hash; rt->rt_dst = *dst; rt->rt_router = *gate; rt->rt_timer = 0; rt->rt_flags = RTF_UP | flags; rt->rt_state = state | RTS_CHANGED; rt->rt_ifp = ripIfWithDstAddr(&rt->rt_dst); if (rt->rt_ifp == 0) rt->rt_ifp = ripIfWithNet(&rt->rt_router); if ((state & RTS_INTERFACE) == 0) rt->rt_flags |= RTF_GATEWAY; rt->rt_metric = metric; /* * Set the netmask. The interface's netmask is used if none is included * in the RIP message. Otherwise, the specified netmask is used, except * for default routes, which always use a netmask of 0. */ if (netmask != (struct sockaddr *)NULL && ((struct sockaddr_in *)dst)->sin_addr.s_addr) { rt->rt_netmask = *netmask; } else { /* Leave the netmask value as zero if a default route is used. */ bzero((char *)&rt->rt_netmask, sizeof(rt->rt_netmask)); rt->rt_netmask.sa_family = AF_INET; rt->rt_netmask.sa_len = 16; pNsin = (struct sockaddr_in *)&rt->rt_netmask; if ( ((struct sockaddr_in *)dst)->sin_addr.s_addr) { pNsin->sin_addr.s_addr = htonl(rt->rt_ifp->int_subnetmask); /* * Learned routes and locally generated interface routes use the * (possibly classless) subnet mask value. Internally generated * routes provided to implement border gateway filtering will * use a class-based netmask in all updates to be understood * by RIP-2 routers on "distant" hosts not directly connected to * the destination. Since supernet routes must use the classless * netmask during border gateway filtering to correctly detect * matching supernet numbers, they retain that value internally * while the subnetted routes replace it with the class-based * value. */ if (rt->rt_state & RTS_INTERNAL) { /* * Check if the subnetmask is shorter than the (class-based) * netmask. This test works because equal values are not * possible for these routes (RTS_SUBNET is always set). */ if ( (rt->rt_ifp->int_subnetmask | rt->rt_ifp->int_netmask) == rt->rt_ifp->int_subnetmask) { /* Longer mask. Replace with class-based value. */ pNsin->sin_addr.s_addr = htonl (rt->rt_ifp->int_netmask); } } } } ripRouteToAddrs(rt, &pDsin, &pGsin, &pNsin); pIfp = rt->rt_ifp; if ((pIfp) && (pIfp->leakHook)) { if (pIfp->leakHook (pDsin->sin_addr.s_addr, pGsin->sin_addr.s_addr, pNsin->sin_addr.s_addr) == OK) { return (OK); } } _insque((NODE *)rt, (NODE *)rh); if (routedDebug > 1) logMsg ("Adding route to %x through %x (mask %x).\n", pDsin->sin_addr.s_addr, pGsin->sin_addr.s_addr, pNsin->sin_addr.s_addr, 0, 0, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -