?? tables.c
字號:
/* tables.c - routines for managing RIP internal routing table *//* Copyright 1984 - 2002 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--------------------01r,22mar02,niq Merged from Synth view, tor3_x.synth branch, ver 02c01q,24jan02,niq SPR 72415 - Added support for Route tags01p,15oct01,rae merge from truestack ver 01w, base 01m (SPRs 70188, 69983, 65547, etc.)01o,21nov00,spm fixed creation of internal default route (SPR #62533)01n,10nov00,spm merged from version 01n of tor3_x branch (code cleanup)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"#include "routeEnhLib.h"#ifdef VIRTUAL_STACK#include "netinet/vsLib.h"#include "netinet/vsRip.h"#endif /* VIRTUAL_STACK *//* defines */#ifdef RTM_ADD#define FIXLEN(s) {if ((s)->sa_len == 0) (s)->sa_len = sizeof *(s);}#else#define FIXLEN(s) { }#endif /* RTM_ADD *//* globals */#ifndef VIRTUAL_STACKIMPORT int routedDebug;IMPORT RIP ripState;#endif /* VIRTUAL_STACK *//* locals */LOCAL struct sockaddr_in inet_default = {#ifdef RTM_ADD sizeof (inet_default),#endif AF_INET, INADDR_ANY };/* forward declarations */IMPORT void ripSockaddrPrint (struct sockaddr * pSockAddr);LOCAL void ripInsque (NODE * pNode, NODE * pPrev);LOCAL void ripRemque (NODE * pNode);LOCAL STATUS ripSystemRouteAdd (long dstIp, long gateIp, long mask, int flags);LOCAL STATUS ripSystemRouteDelete (long dstIp, long gateIp, long mask, int flags);void ripRouteMetricSet (struct rt_entry * pRtEntry);/* * 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);}#ifdef notyet#ifndef VIRTUAL_STACKstruct sockaddr wildcard; /* zero valued cookie for wildcard searches */#endif#endif/* * 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);}struct rt_entry * rtadd ( struct sockaddr *dst, struct sockaddr *gate, int metric, int state, struct sockaddr *netmask, int proto, int tag, int from, struct interface *ifp ) { 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; int ret = ERROR; if (af >= AF_MAX) return ((struct rt_entry *)NULL); (*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 ((struct rt_entry *)NULL); rt->inKernel = FALSE; 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_proto = proto; rt->rt_tag = tag; rt->rt_refcnt = 0; rt->rt_subnets_cnt = 0; rt->rt_orgrouter = from; /* * A matching interface exists for all standard destinations or * the RIP session will not begin the add operation, but no * interface exists for the default route. The rt_ifp field is * equal to zero in that case. * Also, we need to search for the gateway address for the non-rip * route. */ if (ifp) rt->rt_ifp = ifp; else { rt->rt_ifp = ripIfWithDstAddr (&rt->rt_dst, &rt->rt_router); if (rt->rt_ifp == 0) rt->rt_ifp = ripIfWithNet (&rt->rt_router); } if ((state & RTS_INTERFACE) == 0) { rt->rt_flags |= RTF_GATEWAY; 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. */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -