af.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:9k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* af.c - RIP routines supporting specific address families */
  2. /* Copyright 1984 - 2001 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.  */
  36. /*
  37. modification history
  38. --------------------
  39. 01n,22mar02,niq  Merged from Synth view, tor3_x.synth branch, ver 01o
  40. 01m,15oct01,rae  merge from truestack ver 01n, base 01k (VIRTUAL_STACK)
  41. 01l,10nov00,spm  merged from version 01m of tor3_x branch (code cleanup)
  42. 01k,11sep98,spm  updated multicast conversion test to detect all broadcast 
  43.                  addresses (SPR #22350)
  44. 01j,01sep98,spm  refined inet_checkhost test to support default routes 
  45.                  (SPR #22067) and classless netmasks (SPR #22065)
  46. 01i,26jun98,spm  changed RIP_MCAST_ADDR constant from string to value
  47. 01h,06oct97,gnn  added includes to remove warnings
  48. 01g,02jun97,gnn  fixed SPR 8672 which was a byte order problem.
  49. 01f,08may97,gnn  fixed muticasting issues in inet_send.
  50. 01e,17apr97,gnn  fixed errors pointed out by ANVL.
  51. 01d,07apr97,gnn  fixed some of the more egregious warnings
  52.                  added code to handle MIB-II interfaces and options
  53. 01c,12mar97,gnn  added multicast support.
  54.                  added time variables.
  55. 01b,24feb97,gnn  Modified code to handle new global state variables.
  56. 01a,26nov96,gnn  created from BSD4.4 routed 
  57. */
  58. /*
  59. DESCRIPTION
  60. */
  61. #include "vxWorks.h"
  62. #include "rip/defs.h"
  63. #include "ioctl.h"
  64. #include "inetLib.h"
  65. #include "sockLib.h"
  66. #include "logLib.h"
  67. #ifdef VIRTUAL_STACK
  68. #include  "netinet/vsLib.h"
  69. #include  "netinet/vsRip.h"
  70. #else
  71. IMPORT int routedDebug;
  72. #endif
  73. /*
  74.  * Address family support routines
  75.  */
  76. int inet_hash(), inet_netmatch(), inet_output(),
  77. inet_portmatch(), inet_portcheck(),
  78. inet_checkhost(), inet_rtflags(), inet_sendroute(), inet_canon();
  79. char *inet_format();
  80. #define NIL { 0 }
  81. #define RIP_INET 
  82. { inet_hash, inet_netmatch, inet_output, 
  83.   inet_portmatch, inet_portcheck, inet_checkhost, 
  84.   inet_rtflags, inet_sendroute, inet_canon, 
  85.   inet_format 
  86. }
  87. struct afswitch afswitch[AF_MAX] = {
  88. NIL, /* 0- unused */
  89. NIL, /* 1- Unix domain, unused */
  90. RIP_INET, /* Internet */
  91. };
  92. int inet_hash(sin, hp)
  93. register struct sockaddr_in *sin;
  94. struct afhash *hp;
  95. {
  96. register u_long n;
  97. n = inet_netof(sin->sin_addr);
  98. if (n)
  99.     while ((n & 0xff) == 0)
  100. n >>= 8;
  101. hp->afh_nethash = n;
  102. hp->afh_hosthash = ntohl(sin->sin_addr.s_addr);
  103. hp->afh_hosthash &= 0x7fffffff;
  104.         return (OK);
  105. }
  106. /*
  107.  * Verify the message is from the right port.
  108.  */
  109. int inet_portmatch(sin)
  110. register struct sockaddr_in *sin;
  111. {
  112. #ifndef VIRTUAL_STACK
  113.         IMPORT RIP ripState;
  114. #endif
  115. return (sin->sin_port == ripState.port);
  116. }
  117. /*
  118.  * Verify the message is from a "trusted" port.
  119.  */
  120. int inet_portcheck(sin)
  121. struct sockaddr_in *sin;
  122. {
  123. return (ntohs(sin->sin_port) <= IPPORT_RESERVED);
  124. }
  125. /******************************************************************************
  126. * inet_output - RIP Internet output routine.
  127. *
  128. * RETURNS: N/A
  129. * NOMANUAL
  130. */
  131. int inet_output
  132.     (
  133.     int s,
  134.     int flags,
  135.     struct sockaddr_in *sin,
  136.     int size
  137.     )
  138.     {
  139.     struct sockaddr_in dst;
  140.     struct in_addr localIpAddr;
  141.     struct interface* pIfp;
  142.     u_long host;
  143.     u_long mask;
  144. #ifndef VIRTUAL_STACK
  145.     IMPORT RIP ripState;
  146. #endif
  147.     dst = *sin;
  148.     sin = &dst;
  149.     if (sin->sin_len == 0)
  150.         sin->sin_len = sizeof (*sin);
  151.     pIfp = ripIfLookup((struct sockaddr *)&dst);
  152.     /* 
  153.      * Do not assign any value to sin_port before ripIfLookup is called
  154.      * as ripIflookup might fail since it compares all 16 bytes
  155.      */
  156.     if (sin->sin_port == 0)
  157.         sin->sin_port = ripState.port;
  158.     if (pIfp->ifConf.rip2IfConfSend == M2_rip2IfConfSend_ripVersion2)
  159.         {
  160.         /*
  161.          * If we're sending to the broadcast address then change
  162.          * to multicast.
  163.          */
  164.         host = ntohl (sin->sin_addr.s_addr);
  165.         mask = pIfp->int_subnetmask;
  166.         mask = ~mask;
  167.         if ( (host & mask) == mask)     /* Host part is all ones? */
  168.             {
  169.             localIpAddr.s_addr = (uint32_t) ((struct sockaddr_in *)&pIfp->int_addr)->sin_addr.s_addr;
  170.     
  171.             if (setsockopt (s, IPPROTO_IP, IP_MULTICAST_IF,
  172.                             (char *) & localIpAddr, sizeof localIpAddr) != OK)
  173.                 {
  174.                 return (ERROR);
  175.                 }
  176.             sin->sin_addr.s_addr = htonl (RIP_MCAST_ADDR);
  177.             }
  178.         flags = 0;
  179.         }
  180.     if (sendto(s, ripState.packet, size, flags,
  181.                (struct sockaddr *)sin, sizeof (*sin)) < 0)
  182.         {
  183.         if (routedDebug)
  184.             logMsg ("Error %x sending RIP message.n", errno, 0, 0, 0, 0, 0);
  185.         }
  186.     return (OK);
  187.     }
  188. /*
  189.  * Return 1 if the given address is valid. This routine tests the
  190.  * destination address for a route. Forbidden values are:
  191.  *      an address with class D or E;
  192.  *      any address on net 127;
  193.  *      all addresses on net 0 (except 0.0.0.0, for a default route);
  194.  *      any broadcast address.
  195.  *
  196.  * Any entry which specifies these addresses is ignored. Broadcast addresses
  197.  * are detected using the netmask contained in the route update, if any.
  198.  * Otherwise the subnetmask value from the receiving interface is used to
  199.  * determine the host part of the address.
  200.  */
  201. int inet_checkhost(sin, ifp)
  202. struct sockaddr_in *sin;
  203. struct interface *ifp;
  204. {
  205.         /* 
  206.          * The sockaddr_in structure actually overlays a RIP route entry,
  207.          * so the "unused" sin_zero field contains valid data. Retrieve
  208.          * the destination address and the subnet mask, if any. 
  209.          */
  210. u_long i = ntohl(sin->sin_addr.s_addr);
  211.         u_long mask;
  212.         /*
  213.          * Set the mask value to use the subnet of the receiving interface
  214.          * if none is available in the route entry. The interface's subnet
  215.          * value is equal to the class-based mask by default, but will
  216.          * contain a value that produces a longer or shorter network prefix 
  217.          * if subnetting or supernetting are used.
  218.          */
  219.         bcopy (sin->sin_zero, (char *)&mask, 4);
  220.         /* 
  221.          * Convert to host byte order if necessary. Otherwise use the
  222.          * available subnet mask.
  223.          */
  224.         if (mask == 0)
  225.             mask = ifp->int_subnetmask;
  226.         else
  227.             mask = ntohl (mask);
  228.         /* Limited broadcast address: reject. */
  229.         if (i == 0xffffffff)
  230.             return (0);
  231.         /* Accept the default address. */
  232.         if (i == 0)
  233.             return (1);
  234.         /* Reject remaining entries with network number 0. */
  235.         if ((i & mask) == 0)
  236.             return (0);
  237.         /* Check for other broadcast address formats. Reject if found. */
  238.         mask = ~mask;
  239.         if ( (i & mask) == mask)    /* Host part is all ones? */
  240.             return (0);
  241.         /* Reject any address in loopback network. */
  242.         if ((i & 0x7f000000) == 0x7f000000)
  243.             return (0);
  244.         /* Reject any address in class D or class E. */
  245.         
  246.         if (i >= 0xe0000000)
  247.             return (0);
  248.         /* Accept all other addresses. */
  249. return (1);
  250. }
  251. int inet_canon(sin)
  252. struct sockaddr_in *sin;
  253. {
  254. sin->sin_port = 0;
  255. sin->sin_len = sizeof(*sin);
  256.         return (OK);
  257. }
  258. char *
  259. inet_format(sin)
  260. struct sockaddr_in *sin;
  261. {
  262. char *inet_ntoa();
  263. return (inet_ntoa(sin->sin_addr));
  264. }