?? startup.c
字號:
/* startup.c - RIP routines for creating initial data structures *//* 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. * @(#)startup.c 8.2 (Berkeley) 4/28/95 *//*modification history--------------------01l,22mar02,niq Merged from Synth view, tor3_x.synth branch, ver 01q01k,24jan02,niq SPR 68672 - Add route to the local end of the PTP link with the correct netmask SPR 72415 - Added support for Route tags01j,15oct01,rae merge from truestack ver 01m, base 01h (SPR #69983 etc.)01i,10nov00,spm merged from version 01j of tor3_x branch (SPR #29099 fix)01h,11sep98,spm provided fatal error handling in place of quit routine, replaced ripMakeAddr with optimized results (SPR #22350)01g,01sep98,spm modified addrouteforif to correctly support interfaces with classless netmasks (SPR #22220); changed spacing for coding standards01f,26jul98,spm moved assignment from conditional to avoid compiler warnings01e,06oct97,gnn fixed SPR 9211 and added sendHook functionality01d,16may97,gnn added code to initialize hooks to NULL.01c,07apr97,gnn cleared up some of the more egregious warnings. added MIB-II interfaces and options.01b,24feb97,gnn added rip version 2 functionality.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 "net/if.h"#include "net/if_dl.h"#include "netinet/in.h"#include "stdlib.h"#include "logLib.h"#include "m2Lib.h"#include "sockLib.h"#ifdef VIRTUAL_STACK#include "netinet/vsLib.h"#include "netinet/vsRip.h"#endif /* VIRTUAL_STACK */#define same(a1, a2) \ (memcmp((a1)->sa_data, (a2)->sa_data, 14) == 0)/* globals */#ifndef VIRTUAL_STACKIMPORT int routedDebug;IMPORT RIP ripState;struct interface * ripIfNet;struct interface ** ifnext = &ripIfNet;#endif /* VIRTUAL_STACK *//* locals */#ifndef VIRTUAL_STACKLOCAL int foundloopback; /* valid flag for loopaddr */LOCAL struct sockaddr loopaddr; /* our address on loopback */LOCAL struct rt_addrinfo info;#endif /* VIRTUAL_STACK *//* forward declarations */IMPORT void _ripAddrsXtract (caddr_t, caddr_t, struct rt_addrinfo *); IMPORT int sysctl_rtable (int *, int, caddr_t, size_t *, caddr_t *, size_t);IMPORT void _ripIfShow (struct interface *);void addrouteforif(register struct interface *);LOCAL int add_ptopt_localrt (register struct interface *, int);/* defines *//* Sleazy use of local variables throughout file, warning!!!! */#define NETMASK info.rti_info[RTAX_NETMASK]#define IFAADDR info.rti_info[RTAX_IFA]#define BRDADDR info.rti_info[RTAX_BRD]/******************************************************************************* routedIfInit - initialize interface information** This routine behaves differently based on the <ifindex> parameter.* If <ifIndex> is 0, this routine searches the kernel's "ifnet" interface* list for all interfaces belonging to the AF_INET family and copies the* interface data into RIP private interface table list if that interface is UP.* If <ifIndex> is non-zero then only the specified interface is queried* and its data copied if the interface is UP.** Interfaces that are down are ignored.** For every interface retrieved from the kernel, this routine checks if* a route for the interface address already exists in RIP's table. If it does* this signifies that RIP already knows about this interface address; hence it* skips over that entry. If a route doesn't exist, then RIP adds a route* to that interface in its own table as well as in the system Routing database.* The above procedure is repeated for each address entry present for an* interface.** If an interface has multiple IP addresses (aliases), this routine creates* a different interface entry (virtual interface) for each address. * For example an interface "fei0" in the system with address "100.10.1.1"* and "144.1.1.1" will result in two interfaces in RIP's interface list - * 1) "fei0", 100.10.1.1* 2) "fei0", 144.1.1.1* The <resetFlag> parameter distinguishes the initial execution of this* routine from later executions which add new interfaces to the list. * It is used to initialize RIP's interface list.** If the sytem runs out of memory during uring the addition of an interface* to RIP's internal list, or if is encounters some incomplete entries, * the "lookforinterfaces" flag is set to automatically repeat the execution* of this routine at the next timer interval. ** The initial execution of this routine (during RIP startup) must succeed* or the session will not begin, but the session will continue regardless* of the results of later executions.** RETURNS: OK, or ERROR if unable to process interface table.** NOMANUAL** INTERNAL* After the RIP session has started, the routine can be called again* within the context of either the RIP timer task or the RIP input task. * The caller should take the ripLockSem semaphore to provide mutual* exclusion so that no message processing happens while the * interface list is changed and any corresponding route entries are* created.*/STATUS routedIfInit ( BOOL resetFlag, /* build entire new list or add entries? */ long ifIndex /* particular interface to search for, 0-all */ ) { struct interface ifs, *ifp; size_t needed; int mib[6], no_ipaddr = 0, flags = 0; char *buf, *cplim, *cp; register struct if_msghdr *ifm; register struct ifa_msghdr *ifam; struct sockaddr_dl *sdl = NULL; struct sockaddr_in *sin; struct ip_mreq ipMreq; /* Structure for joining multicast groups. */ u_long i; if (resetFlag) { /* Reset globals in case of restart after shutdown. */ foundloopback = 0; ripIfNet = NULL; ifnext = &ripIfNet; } ripState.lookforinterfaces = FALSE; ipMreq.imr_multiaddr.s_addr = htonl (RIP_MCAST_ADDR); /* * The sysctl_rtable routine provides access to internal networking data * according to the specified operations. The NET_RT_IFLIST operator * traverses the entire internal "ifnet" linked list created when the * network devices are initialized. The third argument, when non-zero, * restricts the search to a particular unit number. In this case, all * devices are examined. The first argument, when non-zero, limits the * addresses to the specified address family. */ mib[0] = AF_INET; mib[1] = NET_RT_IFLIST; mib[2] = ifIndex; /* * The first call to the routine determines the amount of space needed * for the results. No data is actually copied. */ if (sysctl_rtable(mib, 3, NULL, &needed, NULL, 0) < 0) { if (routedDebug) logMsg ("Error %x estimating size of interface buffer.\n", errno, 0, 0, 0, 0, 0); return (ERROR); } if (routedDebug) logMsg ("Executing routedInit for iIndex = %d.\n", ifIndex, 0, 0, 0, 0, 0); /* * Allocate the required data, and repeat the system call to copy the * actual values. */ buf = malloc (needed); if (buf == NULL) { if (routedDebug) logMsg ("Error %x allocating interface buffer.\n", errno, 0, 0, 0, 0, 0); return (ERROR); } if (sysctl_rtable(mib, 3, buf, &needed, NULL, 0) < 0) { if (routedDebug) logMsg ("Error %x retrieving interface table.\n", errno, 0, 0, 0, 0, 0); free (buf); return (ERROR); } /* End of VxWorks specific stuff. */ /* * Analyze the retrieved data. The provided buffer now contains a * structure of type if_msghdr for each interface followed by zero * or more structures of type ifa_msghdr for each address for that * interface. The if_msghdr structures have type fields of * RTM_IFINFO and the address structures have type fields of * RTM_NEWADDR. */ cplim = buf + needed; for (cp = buf; cp < cplim; cp += ifm->ifm_msglen) { ifm = (struct if_msghdr *)cp; if (ifm->ifm_type == RTM_IFINFO) { /* Parse the generic interface information. */ memset(&ifs, 0, sizeof(ifs)); ifs.int_flags = flags = (0xffff & ifm->ifm_flags) | IFF_INTERFACE; /* * The sockaddr_dl structure containing the link-level address * immediately follows the if_msghdr structure. */ sdl = (struct sockaddr_dl *) (ifm + 1); sdl->sdl_data[sdl->sdl_nlen] = 0; no_ipaddr = 1; continue; } /* * Only address entries should be present at this point. * Exit if an unknown type is detected. */ if (ifm->ifm_type != RTM_NEWADDR) { if (routedDebug) logMsg ("Unexpected entry in interface table.\n", 0, 0, 0, 0, 0, 0); free (buf); return (ERROR); } /* If RIP is not desired on this interface, then so be it */ if (ripIfExcludeListCheck (sdl->sdl_data) == OK) continue; /* * Ignore the address information if the interface initialization * is incomplete. Set flag to repeat the search at the next timer * interval. */ if ( (flags & IFF_UP) == 0) { continue; } /* Access the address information through the ifa_msghdr structure. */ ifam = (struct ifa_msghdr *)ifm; /* Reset the pointers to access the address pointers. */ info.rti_addrs = ifam->ifam_addrs; _ripAddrsXtract ((char *)(ifam + 1), cp + ifam->ifam_msglen, &info); if (IFAADDR == 0) { if (routedDebug) logMsg ("No address for %s.\n", (int)sdl->sdl_data, 0, 0, 0, 0, 0); continue; } /* Copy and process the actual address values. */ ifs.int_addr = *IFAADDR; if (ifs.int_addr.sa_family != AF_INET) continue; no_ipaddr = 0; if (ifs.int_flags & IFF_POINTOPOINT) { if (BRDADDR == 0) /* No remote address specified? */ { if (routedDebug) logMsg ("No dstaddr for %s.\n", (int)sdl->sdl_data, 0, 0, 0, 0, 0); continue; } if (BRDADDR->sa_family == AF_UNSPEC) { ripState.lookforinterfaces = TRUE; continue; } /* Store the remote address for the link in the correct place. */ ifs.int_dstaddr = *BRDADDR; } /* * Skip interfaces we already know about. But if there are * other interfaces that are on the same network as the ones * we already know about, we want to know about them as well. */ if (ifs.int_flags & IFF_POINTOPOINT) { if (ripIfWithDstAddrAndIndex (&ifs.int_dstaddr, NULL, ifam->ifam_index)) continue;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -