home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / MSDOS / WATTCP / UNZIPPED / MCAST / SRC / PCIGMP.C next >
Encoding:
C/C++ Source or Header  |  1993-11-09  |  3.1 KB  |  146 lines

  1. #if defined(MULTICAST)
  2. /*
  3.  * Internet Group Management Protocol (IGMP) as per RFC 1112.
  4.  * 
  5.  *    This protocol is to allow multicast routers to establish group
  6.  * membership on attached networks. Thus allowing the router to not send 
  7.  * data that is not needed.
  8.  *
  9.  * Jim Martin
  10.  * Rutgers University - RUCS-TD/NS
  11.  * jim@noc.rutgers.edu
  12.  * 6/9/93
  13.  */
  14.  
  15. #include "wattcp.h"
  16. #include "stdlib.h"
  17. #include "copyright.h"
  18.  
  19. typedef struct _pkt {
  20.     in_Header    in;
  21.     IGMP_packet    igmp;
  22. };
  23.  
  24. static int igmp_id = 0;
  25.  
  26. /* 
  27.  * igmp_handler - handles the incoming IGMP packets
  28.  *
  29.  * void igmp_handler( in_Header *ip )
  30.  * Where:
  31.  *    ip    is the IP packet in question
  32.  *
  33.  * Returns: None
  34.  *
  35.  */
  36.  
  37. void igmp_handler( ip )
  38. in_Header *ip;
  39. {
  40.     IGMP_packet     *igmp;
  41.     word        len;
  42.     byte        i;
  43.     longword    host;
  44.  
  45.     len = in_GetHdrlenBytes(ip);
  46.     igmp = (IGMP_packet *)((byte *)ip + len);
  47.  
  48.  
  49.     /* If it doesn't check, drop it */
  50.     if ( checksum(igmp, 8) != 0xffff ){
  51.         return;
  52.     }
  53.  
  54.     /* Get this out of the way right up front */
  55.  
  56.     host = intel( igmp->address );
  57.  
  58.     /* first determine whether this is a report or a query */
  59.     switch (igmp->type){
  60.         case( IGMP_Query ):
  61.             for( i = 0 ; i < IPMULTI_SIZE ; i++){
  62.                 if(_ipmulti[i].active &&
  63.                    (_ipmulti[i].ina != ALL_SYSTEMS) &&
  64.                    ( !_ipmulti[i].replytime )){
  65.                       _ipmulti[i].replytime = time(NULL)
  66.                                             + random(11);
  67.                    }
  68.             }
  69.             break;
  70.         case( IGMP_Report ):
  71.             for( i = 0 ; i < IPMULTI_SIZE ; i++){
  72.                 if( _ipmulti[i].active &&
  73.                     (_ipmulti[i].ina == host) &&
  74.                     ( host != ALL_SYSTEMS )){
  75.                     _ipmulti[i].replytime = 0;
  76.                     break;
  77.                     }
  78.             }
  79.             break;
  80.         default:
  81.             break;
  82.     }
  83. }
  84.  
  85.  
  86.  
  87. /* 
  88.  * igmp_report - send a IGMP Report packet
  89.  *
  90.  * int igmp_report( longword ina)
  91.  * Where:
  92.  *    ina    is the IP address to report.
  93.  *
  94.  * Returns:
  95.  *    0    if unable to send report
  96.  *    1    report was sent successfully
  97.  */
  98.  
  99. int igmp_report( ina )
  100. longword ina;
  101. {
  102.     struct _pkt  *pkt;
  103.     in_Header *ip;
  104.     IGMP_packet *igmp;
  105.     eth_address    ethaddr;
  106.  
  107.  
  108.     /* get the ethernet addr of the destination */
  109.     multi_to_eth( (longword)ALL_SYSTEMS, ethaddr);
  110.  
  111.         /* format the packet with the request's hardware address */
  112.         pkt = (struct _pkt*)(_eth_formatpacket( ethaddr, 8));
  113.  
  114.     /* make things a bit easier to work with */
  115.     ip = &pkt->in;
  116.     igmp = &pkt->igmp;
  117.  
  118.     /* first fill in the igmp packet */
  119.     igmp->type = IGMP_Report;
  120.     igmp->version = IGMP_Version;
  121.     igmp->mbz = 0;
  122.     igmp->checksum = 0;
  123.     igmp->address = intel( ina );
  124.  
  125.     /* then compute the IGMP checksum */
  126.     igmp->checksum = ~checksum(igmp, sizeof( IGMP_packet ));
  127.  
  128.     /* Now to stick it in an IP packet */
  129.     ip->ver = 4;
  130.     ip->hdrlen = 5;
  131.     ip->length = intel16( sizeof( in_Header ) + sizeof( IGMP_packet) );
  132.     ip->tos = 0;
  133.     ip->identification = intel16 (igmp_id ++);
  134. /*    ip->frag = 0; */
  135.     ip->ttl = 1;
  136.     ip->proto = IGMP_PROTO;
  137.     ip->checksum = 0;
  138.     ip->source = intel( my_ip_addr );
  139.     ip->destination = intel( ina );
  140.     ip->checksum = ~checksum(ip, sizeof( in_Header ));
  141.  
  142.     _eth_send( intel16( ip->length ));
  143.     return(1);
  144. }
  145. #endif /* MULTICAST */
  146.