routed_if.c
上传用户:baixin
上传日期:2008-03-13
资源大小:4795k
文件大小:8k
开发平台:

MultiPlatform

  1. /* routed_if.c -  RIP routines for handling available interfaces */
  2. /* Copyright 1984 - 2002 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5.  * Copyright (c) 1983, 1993
  6.  * The Regents of the University of California.  All rights reserved.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in the
  15.  *    documentation and/or other materials provided with the distribution.
  16.  * 3. All advertising materials mentioning features or use of this software
  17.  *    must display the following acknowledgement:
  18.  * This product includes software developed by the University of
  19.  * California, Berkeley and its contributors.
  20.  * 4. Neither the name of the University nor the names of its contributors
  21.  *    may be used to endorse or promote products derived from this software
  22.  *    without specific prior written permission.
  23.  *
  24.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34.  * SUCH DAMAGE.
  35.  * @(#)if.c 8.2 (Berkeley) 4/28/95";
  36.  */
  37. /*
  38. modification history
  39. --------------------
  40. 01f,22mar02,niq  Merged from Synth view, tor3_x.synth branch, ver 01h
  41. 01e,15oct01,rae  merge from truestack ver 01f, base 01c (SPR #69983 etc.)
  42. 01d,10nov00,spm  merged from version 01d of tor3_x branch (namespace cleanup)
  43. 01c,01sep98,spm  extended the interface search routines to handle 
  44.                  supernets (SPR #22220)
  45. 01b,24feb97,gnn  changed routine names to avoid conflicts.
  46. 01a,26nov96,gnn  created from BSD4.4 routed if.c
  47. */
  48. /*
  49. DESCRIPTION
  50. */
  51. /*
  52.  * Routing Table Management Daemon
  53.  */
  54. #include "vxWorks.h"
  55. #include "rip/defs.h"
  56. #ifdef VIRTUAL_STACK
  57. #include "netinet/vsLib.h"
  58. #include "netinet/vsRip.h"
  59. #else
  60. extern struct interface *ripIfNet;
  61. #endif
  62. /*
  63.  * Find the interface with address addr.
  64.  */
  65. struct interface *
  66. ripIfWithAddr(addr)
  67. struct sockaddr *addr;
  68. {
  69. register struct interface *ifp;
  70. #define same(a1, a2) 
  71. (memcmp((a1)->sa_data, (a2)->sa_data, 14) == 0)
  72. for (ifp = ripIfNet; ifp; ifp = ifp->int_next) {
  73. if (ifp->int_flags & IFF_REMOTE)
  74. continue;
  75. if (ifp->int_addr.sa_family != addr->sa_family)
  76. continue;
  77. if (same(&ifp->int_addr, addr))
  78. break;
  79. if ((ifp->int_flags & IFF_BROADCAST) &&
  80.     same(&ifp->int_broadaddr, addr))
  81. break;
  82. }
  83. return (ifp);
  84. }
  85. /*
  86.  * Find the interface with address addr.
  87.  */
  88. struct interface *
  89. ripIfWithAddrAndIndex(addr, index)
  90. struct sockaddr *addr;
  91.         int index;
  92. {
  93. register struct interface *ifp;
  94. #define same(a1, a2) 
  95. (memcmp((a1)->sa_data, (a2)->sa_data, 14) == 0)
  96. for (ifp = ripIfNet; ifp; ifp = ifp->int_next) {
  97. if (ifp->int_flags & IFF_REMOTE)
  98. continue;
  99. if (ifp->int_addr.sa_family != addr->sa_family)
  100. continue;
  101. if (same(&ifp->int_addr, addr) && index == ifp->int_index)
  102. break;
  103. if ((ifp->int_flags & IFF_BROADCAST) &&
  104.     same(&ifp->int_broadaddr, addr) && index == ifp->int_index)
  105. break;
  106. }
  107. return (ifp);
  108. }
  109. /*
  110.  * Find the point-to-point interface with destination address addr.
  111.  */
  112. struct interface *
  113. ripIfWithDstAddr(addr, gateaddr)
  114. struct sockaddr *addr;
  115. struct sockaddr *gateaddr;
  116. {
  117. register struct interface *ifp;
  118. for (ifp = ripIfNet; ifp; ifp = ifp->int_next) {
  119. if ((ifp->int_flags & IFF_POINTOPOINT) == 0)
  120. continue;
  121. if (same(&ifp->int_dstaddr, addr) || 
  122.                     (gateaddr && same(&ifp->int_dstaddr, gateaddr)))
  123. break;
  124. }
  125. return (ifp);
  126. }
  127. /*
  128.  * Find the point-to-point interface with destination address addr and index.
  129.  */
  130. struct interface *
  131. ripIfWithDstAddrAndIndex(addr, gateaddr, index)
  132. struct sockaddr *addr;
  133. struct sockaddr *gateaddr;
  134. {
  135. register struct interface *ifp;
  136. for (ifp = ripIfNet; ifp; ifp = ifp->int_next) {
  137. if ((ifp->int_flags & IFF_POINTOPOINT) == 0)
  138. continue;
  139. if ((same(&ifp->int_dstaddr, addr) || 
  140.                      (gateaddr && same(&ifp->int_dstaddr, gateaddr))) &&
  141.                     ifp->int_index == index)
  142. break;
  143. }
  144. return (ifp);
  145. }
  146. /*
  147.  * Find the interface on the network 
  148.  * of the specified address. INTERNET SPECIFIC.
  149.  */
  150. struct interface *
  151. ripIfWithNet(addr)
  152. register struct sockaddr *addr;
  153. {
  154. register struct interface *ifp;
  155. register struct interface *pIfMax;
  156. register int af = addr->sa_family;
  157.         register u_long dstaddr;
  158. if (af >= AF_MAX)
  159. return (0);
  160.         pIfMax = 0;
  161.         dstaddr = ntohl ( ((struct sockaddr_in *)addr)->sin_addr.s_addr);
  162. for (ifp = ripIfNet; ifp; ifp = ifp->int_next) {
  163. if (ifp->int_flags & IFF_REMOTE)
  164. continue;
  165. if (af != ifp->int_addr.sa_family)
  166. continue;
  167.                 if ( (dstaddr & ifp->int_subnetmask) == ifp->int_subnet)
  168.                     {
  169.                     if (pIfMax)
  170.                         {
  171.                         if ( (ifp->int_subnetmask | pIfMax->int_subnetmask)
  172.                              == ifp->int_subnetmask)
  173.                             pIfMax = ifp;
  174.                         }
  175.                     else
  176.                         pIfMax = ifp;
  177.                     }
  178. }
  179. return (pIfMax);
  180. }
  181. /*
  182.  * Find an interface matching the specified source address. This routine
  183.  * is used to select an interface for tracking errors in RIP responses
  184.  * and verifying the source of RIP updates before altering the routing
  185.  * table.
  186.  */
  187. struct interface * ripIfLookup(addr)
  188. struct sockaddr *addr;
  189. {
  190. register struct interface *ifp, *maybe;
  191. register int af = addr->sa_family;
  192. register u_long dstaddr;
  193. if (af >= AF_MAX)
  194. return (0);
  195. maybe = 0;
  196.         dstaddr = ntohl ( ((struct sockaddr_in *)addr)->sin_addr.s_addr);
  197. for (ifp = ripIfNet; ifp; ifp = ifp->int_next) {
  198. if (ifp->int_addr.sa_family != af)
  199. continue;
  200.                 /*
  201.                  * When this routine is called by inet_output() via the
  202.                  * toall() routine, one of the following comparisons is 
  203.                  * always true and the results of the network number 
  204.                  * tests are not used.
  205.                  */
  206. if (same(&ifp->int_addr, addr))
  207. break;
  208. if ((ifp->int_flags & IFF_BROADCAST) &&
  209.     same(&ifp->int_broadaddr, addr))
  210. break;
  211. if ((ifp->int_flags & IFF_POINTOPOINT) &&
  212.     same(&ifp->int_dstaddr, addr))
  213. break;
  214.                 /*
  215.                  * If the given address does not match any of the 
  216.                  * available interfaces directly, search for the
  217.                  * matching network number with the longest prefix.
  218.                  * The use of the if_subnetmask value instead of
  219.                  * if_netmask accounts for any classless routing
  220.                  * (supernets or subnets). The results of this test
  221.                  * are generally used when verifying the source of
  222.                  * a RIP message before accepting any route updates.
  223.                  */
  224. if ( (dstaddr & ifp->int_subnetmask) == ifp->int_subnet)
  225.                     {
  226.                     if (maybe)
  227.                         {
  228.                         if ( (ifp->int_subnetmask | maybe->int_subnetmask)
  229.                             == ifp->int_subnetmask)
  230.                             maybe = ifp;
  231.                         }
  232.                     else
  233.                         maybe = ifp;
  234.                     }
  235. }
  236. if (ifp == 0)
  237. ifp = maybe;
  238. return (ifp);
  239. }