⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcigmp.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
字号:

/*
 * Internet Group Management Protocol (IGMP) as per RFC 1112.
 * 
 * This protocol is to allow multicast routers to establish group
 * membership on attached networks. Thus allowing the router to not send 
 * data that is not needed.
 *
 * Jim Martin
 * Rutgers University - RUCS-TD/NS
 * jim@noc.rutgers.edu
 * 6/9/93
 */

#include <stdio.h>
#include <stdlib.h>

#include "copyrigh.h"
#include "wattcp.h"
#include "misc.h"
#include "chksum.h"
#include "ip_out.h"
#include "pcmulti.h"
#include "pcdbug.h"
#include "pcstat.h"
#include "pcsed.h"
#include "pctcp.h"

#if defined(USE_MULTICAST)

#include <sys/packon.h>

struct IGMP_PKT {
       in_Header   in;
       IGMP_packet igmp;
     };

#include <sys/packoff.h>


/* 
 * igmp_handler - handles the incoming IGMP packets
 *
 * void igmp_handler (in_Header *ip)
 * Where:
 *      ip    is the IP packet in question
 *
 * Returns: None
 *
 */
void igmp_handler (const in_Header *ip, BOOL broadcast)
{
  BYTE         i;
  DWORD        host;
  BOOL         found = 0;
  WORD         len   = in_GetHdrLen (ip);
  IGMP_packet *igmp  = (IGMP_packet*) ((BYTE*)ip + len);

  DEBUG_RX (NULL, ip);

  if (len < sizeof(*igmp))
  {
    STAT (igmpstats.igps_rcv_tooshort++);
    return;
  }

  if (checksum(igmp,sizeof(*igmp)) != 0xFFFF)
  {
    STAT (igmpstats.igps_rcv_badsum++);
    return;
  }

  host = intel (igmp->address);

  /* Determine whether this is a report or a query
   */
  switch (igmp->type)
  {
    case IGMP_QUERY:
         STAT (igmpstats.igps_rcv_queries++);
         for (i = 0; i < IPMULTI_SIZE; i++)
             if (_ipmulti[i].active             &&
                 _ipmulti[i].ina != ALL_SYSTEMS &&
                 _ipmulti[i].replytime == 0)
             {
               _ipmulti[i].replytime = set_timeout (Random(500,1000));
               found = 1;
             }
         if (!found && !broadcast)
            STAT (igmpstats.igps_rcv_badqueries++);
         break;

    case IGMP_REPORT:
         STAT (igmpstats.igps_rcv_reports++);
         for (i = 0; i < IPMULTI_SIZE; i++)
             if (_ipmulti[i].active      &&
                 _ipmulti[i].ina == host &&
                 host != ALL_SYSTEMS)
             {
               _ipmulti[i].replytime = 0;
               found = 1;
               STAT (igmpstats.igps_rcv_ourreports++);
               break;
             }
         if (!found && !broadcast)
            STAT (igmpstats.igps_rcv_badreports++);
         break;
  }
}
         

/* 
 * igmp_report - send a IGMP Report packet
 *
 * int igmp_report (DWORD ip)
 * Where:
 *      ip is the IP address to report.
 *
 * Returns:
 *      0   if unable to send report
 *      1   report was sent successfully
 */
int igmp_report (DWORD ip)
{
  struct IGMP_PKT *pkt;
  IGMP_packet     *igmp;
  eth_address      ethaddr;

  /* get the ethernet addr of the destination
   */
  multi_to_eth ((DWORD)ALL_SYSTEMS, (BYTE*)&ethaddr);

  /* format the packet with the request's hardware address
   */
  pkt  = (struct IGMP_PKT*) _eth_formatpacket (ethaddr, IP_TYPE);
  igmp = &pkt->igmp;
  ip = intel (ip);

  /* fill in the igmp packet
   */
  igmp->type     = IGMP_REPORT;
  igmp->version  = IGMP_VERSION;
  igmp->mbz      = 0;
  igmp->address  = ip;
  igmp->checksum = 0;
  igmp->checksum = ~checksum (igmp,sizeof(*igmp));

  return IP_OUTPUT (&pkt->in, 0, ip, IGMP_PROTO,
                    0, 0, 0, (int)sizeof(*igmp), NULL);
}

#endif /* USE_MULTICAST */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -