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

📄 igmp.c

📁 用于嵌入式系统的TCP/IP协议栈及若干服务
💻 C
📖 第 1 页 / 共 3 页
字号:
/**            Copyright (c) 1998-2001 by NETsilicon Inc.**  This software is copyrighted by and is the sole property of*  NETsilicon.  All rights, title, ownership, or other interests*  in the software remain the property of NETsilicon.  This*  software may only be used in accordance with the corresponding*  license agreement.  Any unauthorized use, duplication, transmission,*  distribution, or disclosure of this software is expressly forbidden.**  This Copyright notice may not be removed or modified without prior*  written consent of NETsilicon.**  NETsilicon, reserves the right to modify this software*  without notice.**  NETsilicon*  411 Waverley Oaks Road                  USA 781.647.1234*  Suite 227                               http://www.netsilicon.com*  Waltham, MA 02452                       AmericaSales@netsilicon.com***************************************************************************  $Name: Fusion 6.52 Fusion 6.51 $*  $Date: 2001/11/28 17:57:03 $*  $Source: M:/psisrc/stack/mcast/rcs/igmp.c $*  $Revision: 1.24 $***************************************************************************                         - Revision Log -                              ** Who   When        Why** FND   09/28/01    Rename t_start/t_delete to fns_t_start/fns_t_delete*                   to fix conflict with pSOS.****************************************************************************  File Description: IGMP V2**************************************************************************/#include "std.h"#ifdef IGMP_PROTOCOL#include "flags.h"#include "fr.h"#include "netdev.h"#include "netioc.h"#include "fns_mem.h"#include "fnsproto.h"#include "igmp.h"#include "enet.h"#include "nerrno.h"#include "debug.h"#include "fns_heap.h"#define t_start fns_t_start#define t_delete fns_t_delete/** external functions **/import  netdev  *ll_dev_2_ndp (char * devname);export igmp_entry   *igmp_tbl;export u32      igmp_entries;/** internal functions **/u32 igmp_num (int i, u8 max_response_time );int igmp_do_send ( IGMP_T *packet, netdev *ndp, u32 ipdest );int igmp_send_report( igmp_entry *igmp_tab_entry );export int igmp_send_general_query (char *devname, u8 max_response_time );export int igmp_send_group_query ( igmp_entry *entry, u8 max_response_time );int igmp_update (void *uarg);int igmp_start_t (netdev *ndp, a32 *ipaddr, u8 max_response_time );static u32 modulus =    9997;static u32 offset;/********************************************************************* * * igmp_is_v2(void) * * DESCRIPTION:  For any external code which wants to know if we are *               configured for IGMP V2 operation via the IGMP_VERSION_2 *               switch but doesn't want to include igmp.h * * RETURNS:      1 if we are v2, 0 if not * **/int igmp_is_v2(void){#ifdef IGMP_VERSION_2    return 1;#else    return 0;#endif}/********************************************************************* ** ip_add_multi_route() * *  PARAMETERS: 1. IP multicast address. *              2. Device name as in ncdev.c. *              3. local_mc is a boolean set to 1 if we don't *                 want this address to participate in IGMP * *  DESCRIPTION:    1. Check if it is proper Multicast IP address. *                  2. Adds Multi. IP address to the routing table on *                     the selected device. *                  3. Allocates the entry in the igmp_tbl. *                  4. Sets the state of new entry to DELAY so it is *                     sent at least twice. *                  5. Sends igmp report of the new entry. * *  RETURNS: 0   - OK *           > 1 - error**********************************************************************/int ip_add_multi_route (char *devname, char *ip_address, int is_localmc ){    netdev      *ndp;    int         err;    int         i = 0;    u32         ip_address_u32;    use_critical;    err = 0;    ip_address_u32 = MemToHost32((u8 *)ip_address);    if ( !(is_D_class((u8 *)ip_address)) )        return FNS_EDESTADDRREQ;    if ((ndp = ll_dev_2_ndp(devname)) == (netdev *)0)        return FNS_ENODEV;    /* Is this interface already a member of the specified multicast group?	   If so, all we need to do here is to increment the reference count for	   the interface. */    if ( (i = igmp_find (ip_address_u32, ndp)) >= 0 ) {		/* This interface already a member of this multicast group */        igmp_tbl[i].refs++;        return 0;	} /* if */		/* If we get down here, then this is the first membership of the specified	   interface in the specified multicast group. So we need to create a new	   membership entry, provided we have room for it in our membership table */    if (igmp_entries >= IGMP_CNT) {#ifdef DEBUG        os_printf("ip_add_multi_route: IGMP reference table full\n");#endif        return FNS_ETOOMANYREFS;    }    /* If this is an ethernet interface, invoke the processing to take advantage	   of ethernet hardware's ethernet layer multicasting capability */	ndp->nd_xflags |= F_X_MULTI_ADDR;    if (IS_LAN_TYPE((int)ndp->nd_lladdr.a_type)) {        err = arp_multi_add (ndp, ip_address);        if (err) {			return(err);		}	}	/* The IGMP_ALLHOSTS group doesn't need an entry */    if ( ip_address_u32 == IGMP_ALLHOST ) {		return(0);	}    /* Well, all the condtions are met, we are going to add an entry to the 	   IGMP table. */    /* go critical while manipulating the IGMP membership table */    critical;    /* Look for a free entry in the IGMP table to use for this new membership */    for (i = 0; i < IGMP_CNT; i++) {        if (igmp_tbl[i].state == IGMP_FREE) {            break;		} /* if */	} /* for */    if (i >= IGMP_CNT) {		/* Something is seriously wrong -- earlier we decided that our IGMP table		   isn't full, yet we just looked for a free entry and didn't find one. */        normal;#ifdef DEBUG        os_printf("ip_add_multi_route: IGMP reference table full (inconsistent)\n");#endif        return FNS_ETOOMANYREFS;    }    igmp_entries++;    igmp_tbl[i].state = IGMP_IDLE;    igmp_tbl[i].ndp = ndp;    igmp_tbl[i].ip_multi = ip_address_u32;    igmp_tbl[i].seed = (int)ip_address_u32;    igmp_tbl[i].refs = 1;    if ( is_localmc ) {        /* OL:  Local Multicast does not need timers*/        igmp_tbl[i].timer = (tcb *)0;    } else {        if ( (igmp_tbl[i].timer = t_new((tcb *)0            , igmp_update, &igmp_tbl[i],            igmp_num(i, 100), F_T_STOPPED))              == (tcb *)0) {            normal;#ifdef DEBUG            os_printf("ip_add_multi_route: out of heap for timer creation !!!!!\n");#endif            return FNS_ENOMEM;        }    }    /* Finished manipulating the membership table */    normal;    /* JPP locals do not participate in reports */    if( !is_localmc ) {        igmp_send_report( &igmp_tbl[i] );        igmp_tbl[i].state = IGMP_DELAY;        igmp_tbl[i].last_2_report = true;        t_start (igmp_tbl[i].timer, igmp_num(i, 100));    } else        igmp_tbl[i].state = IGMP_STATIC;    return err;}/********************************************************************* ** igmp_send_leave( igmpentry *entry ) * *  PARAMETERS:     entry - entry in igmp table. * *  DESCRIPTION:    Send a v2 leave message if conditions are OK. * *  RETURNS:    0 - OK *              1 - error***********************************************************************/void igmp_send_leave( igmp_entry *entry ){#ifdef IGMP_VERSION_2    netdev *ndp = entry->ndp;    IGMP_T packet[SIZEOF_IGMP_T];    /* Only can send if:            1.  Built for V2            2.  We have are sending IGMPv2 reports (we haven't heard                an IGMPv1 Query in IGMP_V1_ROUTER_PRESENT_TIMEOUT seconds).            3.  We were the last host to send a membership report for                this group.    */    if( ndp->v1_router_present || !entry->last_2_report ) {        return;    }    /* Fill in the packet fields */    packet[IGMP_T_IGMP_TYPE] = IGMP_V2_LEAVE;    /* unused field for reports */    packet[IGMP_T_MAX_RESP_TIME] = 0;    HostToMem32(&packet[IGMP_T_IP_ADDR], entry->ip_multi);    igmp_do_send ( packet, entry->ndp, IGMP_ALLROUTER );#else    return;#endif}/********************************************************************* ** ip_del_multi_route() * *  PARAMETERS:     1. Device name as in ncdev.c *          2. IP multicast address. * *  DESCRIPTION:    1. Check if it is proper Multicast IP address. *                  2. Deletes Multi. IP address from the routing table of *                  the selected device. *                  3. Changes the sate of the igmp_tbl entry. *                  4. Deletes the allocated time queue. * *  RETURNS:    0 - OK *              1 - error***********************************************************************/int ip_del_multi_route (char * devname, char *ip_address){    netdev      *ndp;    int         err;    int         i = 0;    u32         ip_address_u32;    use_critical;    err = 0;    if ( !(is_D_class((u8 *)ip_address)) )    {#ifdef DEBUG        os_printf("ip_del_multi_route: wrong address\n");#endif        return FNS_EADDRNOTAVAIL;    }    if ((ndp = ll_dev_2_ndp(devname)) == (netdev *)0)        return FNS_ENODEV;    ip_address_u32 = MemToHost32((u8 *)ip_address);    if ((i = igmp_find (ip_address_u32, ndp)) >= 0)    {        /* refs is the number of references to the address on this interface.           If it is non-zero there is nothing more to be done.  If zero see           below - we must remove it from the interface.        */        if (--igmp_tbl[i].refs) {            return 0;        }    }    else    {#ifdef DEBUG        os_printf("ip_del_multi_route: address not in igmp table\n");#endif        return FNS_EADDRNOTAVAIL;    }    /* For IGMPv2 send a leave message */    igmp_send_leave( &igmp_tbl[i] );    critical;    igmp_tbl[i].state = IGMP_FREE;    igmp_tbl[i].last_2_report = false;    igmp_entries--;    /* OL: local multicast does not have a timer */    if (igmp_tbl[i].timer != (tcb *)0)        t_delete (igmp_tbl[i].timer);    normal;    /* OL: deleted interface to old router */    /* OL: replaced comparison to AF_ETHER with macro  */    if (IS_LAN_TYPE((int)ndp->nd_lladdr.a_type))        err = arp_multi_del (ndp, ip_address);    return err;}/* * dummy timer callback * */int igmpdummy( void *dummy ){    return 0;}/********************************************************************* ** igmpinit () * *  PARAMETERS:     prp - protocol structure * *  DESCRIPTION:    1. Allocates IGMP_CNT entries in the igm_tbl and *                  initialize them to 0. * *  RETURNS:    0 - OK *              1 - error ************************************************************************/export int igmpinit (pr_t * prp){    igmp_entry  *entry;

⌨️ 快捷键说明

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