home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / MSDOS / WATTCP / UNZIPPED / MCAST / SRC / PCMULTI.C < prev   
Encoding:
C/C++ Source or Header  |  1993-11-09  |  3.4 KB  |  161 lines

  1. #if defined(MULTICAST)
  2. /*
  3.  * IP Multicasting extensions as per RFC 1112.
  4.  * 
  5.  *    These extensions include routines to detect multicast addresses,
  6.  * transform Multicast IP addresses to Multicast Ethernet addresses, as
  7.  * well as a mechanism to join and leave multicast groups.
  8.  *
  9.  * Jim Martin
  10.  * Rutgers University - RUCS-TD/NS
  11.  * jim@noc.rutgers.edu
  12.  * 6/6/93
  13.  */
  14.  
  15. #include "wattcp.h"
  16. #include "copyright.h"
  17.  
  18. multicast _ipmulti[IPMULTI_SIZE];
  19.  
  20. /* 
  21.  * is_multicast - determines if the given IP addr is Class D (Multicast)
  22.  *
  23.  * int is_multicast( longword ina )
  24.  * Where:
  25.  *    ina    IP address in question
  26.  * Returns:
  27.  *    1    if ina is Class D
  28.  *    0    if ina is not Class D
  29.  */
  30.  
  31. int is_multicast( ina )
  32. longword ina;
  33. {
  34.     if ( (ina & CLASS_D_MASK) == CLASS_D_MASK )
  35.         return( 1 );
  36.     else
  37.         return( 0 );
  38. }
  39.  
  40. /* 
  41.  * multi_to_eth - calculates the proper ethernet address for a given
  42.  *                IP Multicast address.
  43.  *
  44.  * int multi_to_eth( longword ina, eth_address *ethaddr )
  45.  * Where:
  46.  *    ina    IP address to be converted
  47.  *    ethaddr    Ethernet MAC address
  48.  * Returns:
  49.  *    1    if calculation is successful
  50.  *    0    if calculation failed
  51.  */
  52.  
  53. int multi_to_eth( ina, ethaddr )
  54. longword ina;
  55. eth_address ethaddr;
  56. {
  57.     longword top = ETH_MULTI;
  58.  
  59.     ina = ( ina & IPMULTI_MASK );
  60.     ethaddr[0] = ( top >> 16 );
  61.     ethaddr[1] = (( top >> 8 ) & 0xff);
  62.     ethaddr[2] = ( top & 0xff );
  63.     ethaddr[3] = ( ina >> 16 );
  64.     ethaddr[4] = (( ina >> 8 ) & 0xff );
  65.     ethaddr[5] = ( ina & 0xff );
  66.     return( 1 );
  67. }
  68.  
  69.  
  70. /* 
  71.  * join_mcast_group - joins a multicast group
  72.  *
  73.  * int join_mcast_group( longword ina )
  74.  * Where:
  75.  *    ina    IP address of the group to be joined
  76.  * Returns:
  77.  *    1    if the group was joined successfully
  78.  *    0    if attempt failed
  79.  */
  80.  
  81. int join_mcast_group( ina )
  82. longword ina;
  83. {
  84.     byte    i;
  85.     int    free = -1;
  86.  
  87.     /* first verify that it's a valid mcast address */
  88.     if ( ! is_multicast( ina ))
  89.         return( 0 );
  90.  
  91.     /* determine if the group has already been joined */
  92.     /* as well as what the first free slot is */
  93.     for( i = 0; i < IPMULTI_SIZE ; i++){
  94.         if( _ipmulti[i].active && (ina == _ipmulti[i].ina) ){
  95.             _ipmulti[i].processes++;
  96.             return( 1 );
  97.         }
  98.         if( ( free == -1 ) && ( ! _ipmulti[i].active ) )
  99.             free = i;
  100.     }
  101.  
  102.     /* alas, no...we need to join it */
  103.  
  104.     if( free == -1 )    /* out of slots! */
  105.         return( 0 );
  106.  
  107.     _ipmulti[free].ina = ina;
  108.     if ( ! _eth_join_mcast_group( free ))
  109.         return( 0 );
  110.     return( 1 );
  111. }
  112.  
  113. /* 
  114.  * leave_mcast_group - leaves a multicast group
  115.  *
  116.  * int leave_mcast_group( longword ina )
  117.  * Where:
  118.  *    ina    IP address of the group to be joined
  119.  * Returns:
  120.  *    1    if the group was left successfully
  121.  *    0    if attempt failed
  122.  */
  123.  
  124. int leave_mcast_group( ina )
  125. longword ina;
  126. {
  127.     byte    i;
  128.     int    groupnum = -1;
  129.  
  130.     /* first verify that it's a valid mcast address */
  131.     if ( ! is_multicast( ina ))
  132.         return( 0 );
  133.  
  134.     /* determine if the group has more than one interested
  135.        process. if so, then just decrement .processes and return */
  136.     for( i = 0; i < IPMULTI_SIZE ; i++){
  137.         if( _ipmulti[i].active && (ina == _ipmulti[i].ina)){
  138.             if (_ipmulti[i].processes > 1 ){
  139.                 _ipmulti[i].processes--;
  140.                 return( 1 );
  141.             }
  142.             else {
  143.                 groupnum = i;
  144.                 break;
  145.             }
  146.         }
  147.     }
  148.  
  149.     /* did the ipaddr they gave match anything in _ipmulti ?? */
  150.     if ( groupnum == -1 )
  151.         return( 0 );
  152.  
  153.     /* alas...we need to physically leave it */
  154.  
  155.     if ( ! _eth_leave_mcast_group( groupnum ))
  156.         return( 0 );
  157.  
  158.     return( 1 );
  159. }
  160. #endif /* MULTICAST */
  161.