⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tables.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 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 + -