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

📄 igmp.c

📁 用于嵌入式系统的TCP/IP协议栈及若干服务
💻 C
📖 第 1 页 / 共 3 页
字号:
        if( (igmp_tbl[i].state != IGMP_FREE) && igmp_tbl[i].ndp == ndp ) {            if( groupaddr ) {                /* Must be a group-specific query.  Only send reports                for that specific group.                */                if( MemToHost32(*groupaddr) != igmp_tbl[i].ip_multi ) continue;            }            /* local multicast does not have timer */            if (igmp_tbl[i].timer != (tcb *)0) {                if ( igmp_tbl[i].state == IGMP_IDLE ) {                    igmp_tbl[i].state = IGMP_DELAY;                    t_start (igmp_tbl[i].timer, igmp_num(i, max_resp_time ));                    bFound = 1;                }#ifdef IGMP_VERSION_2                else if( igmp_tbl[i].state == IGMP_DELAY ) {                    /* max_resp_time == 0 implies this is a V1 query */                    if( max_resp_time != 0 ) {                        if( t_remaining(igmp_tbl[i].timer) > (u32)max_resp_time*(u32)100 ) {                            /*  Per IGMPv2 spec we must restart the timer with a                                new random value bounded by the smaller Max Response Time                            */                            t_stop(igmp_tbl[i].timer);                            igmp_tbl[i].state = IGMP_DELAY;                            t_start (igmp_tbl[i].timer, igmp_num(i, max_resp_time ));                            bFound = 1;                        }                    }                }#endif            }        }    }    normal;    return 0;}/********************************************************************** ** igmp_find () * *  PARAMETERS: a32 *ip - Pointer to the ip multicast address *  OL: netdev * ndp - pointer to the netdev structure * *  DESCRIPTION:    Searches the igmp_tbl for the IP multicast address *  OL:  on a given interface. If ndp is nil, search on all ndp's *      The assumption is that there is only one IP in the *      table. * *  RETURNS:    >= 0 - index in the igmp_tbl *              -1   - no entry found ************************************************************************/int igmp_find (u32 ip, netdev * ndp){    int i;    for (i=0; i < IGMP_CNT; i++)    {        if (igmp_tbl[i].state != IGMP_FREE)        {            if ( igmp_tbl[i].ip_multi == ip ) {            /* OL: if ndp is nil same code as before */                if ((ndp == (netdev *)0)                /* if ndp is non nil only returns if ndp's match too */                || (ndp == igmp_tbl[i].ndp))                    return i;            }        }    }    return -1;}/********************************************************************** ** igmp_update () * *  PARAMETERS:  void *uarg - pointer to entry in igmp table as void. * *  DESCRIPTION: Timer callback to send an IGMPv1 or IGMPv2 report. *               We can only send v2 report if doing IGMP version 2 *               and we have not seen a v1 router query in the last *               IGMP_V1_ROUTER_PRESENT_TIMEOUT seconds on the corresponding *               interface as determined by a flag * *  RETURNS:     0 ************************************************************************/int igmp_update (void *uarg){    igmp_entry  *entry;    entry = (igmp_entry *) uarg;    if (entry->state == IGMP_DELAY)    {        entry->state = IGMP_IDLE;        igmp_send_report(entry);    }    return 0;}/********************************************************************** ** igmp_do_send () * *  PARAMETERS:     packet - pointer to a filled in IGMP IGMP_T structure *                           except for checksum which is taken care of. *                  ndp    - device to send on. *                  ipdest - destination address to send to. * *  DESCRIPTION:    Creates IGMP packet and sends it through the *                  state machine.  Takes care of IGMP checksum for caller. * *  RETURNS:        0 - OK *                  1 - error ************************************************************************/int igmp_do_send ( IGMP_T *packet, netdev *ndp, u32 ipdest ){    m       *mp;    int     err;    int     size;    size = (int)(SIZEOF_ENH + SIZEOF_IPH_T + SIZEOF_IGMP_T#ifdef IGMP_VERSION_2            + 4 /* This is for the IP router alert option */#endif            );    if ((mp = m_new( size, (int *)&err, 0)) == (m *)0)    {#ifdef DEBUG        os_printf("igmp_do_send: out of heap !!!!!\n");#endif        return FNS_ENOMEM;    }    mp->m_hp -= SIZEOF_IGMP_T;    mp->m_flags = F_COMM_MASK;    HostToNet16(&packet[IGMP_T_IGMP_CHECKSUM], 0);    HostToNet16(&packet[IGMP_T_IGMP_CHECKSUM],                (u16)~oc_sum((a16 *)packet,                (int)SIZEOF_IGMP_T));    OS_MOVE_N((char *)mp->m_hp, (char *)packet, SIZEOF_IGMP_T);    mp->m_dest.a_len = sizeof(ipa);    mp->m_dest.a_type = AF_INET;    mp->m_dest.a_ipa.ip_nethost = ipdest;    mp->m_ndp = ndp;    mp->m_type = IP_IGMP;    mp->m_pflags |= F_M_ORIGIN;    msm(mp, ip_send);    return 0;}/*************** IGMP message-specific send routines ******************//********************************************************************** ** igmp_send_report * *  PARAMETERS:  entry - the igmp table entry we're reporting on * *  DESCRIPTION: Sends Host Membership Report, either V1 or V2.  If we're *               running V2 looks to see if there is a V1 router present *               on the interface before sending the V2 report.  If so it *               sends a V1 report. * * *  RETURNS:     0 * ***********************************************************************/int igmp_send_report( igmp_entry *entry ){    IGMP_T packet[SIZEOF_IGMP_T];    netdev *ndp;    u8      ptype = IGMP_V1_REPORT;    ndp =  entry->ndp;#ifdef IGMP_VERSION_2    if( !ndp->v1_router_present ) {        /* Send a v2 report */        ptype = IGMP_V2_REPORT;    }#endif    /* Fill in the packet fields */    packet[IGMP_T_IGMP_TYPE] = ptype;    /* unused field for reports */    packet[IGMP_T_MAX_RESP_TIME] = 0; /* 2 10ths sec */    HostToMem32(&packet[IGMP_T_IP_ADDR], entry->ip_multi);    /* Set the last2report flag for the entry */    entry->last_2_report = true;    igmp_do_send ( packet, entry->ndp, entry->ip_multi );    return 0;}/********************************************************************** ** igmp_send_general_query * *  PARAMETERS: * *  DESCRIPTION: Sends Host Membership General Query request *               (for demo\test purposes). * *  RETURNS: ************************************************************************/int igmp_send_general_query (char *devname, u8 max_resp_time ){    IGMP_T packet[SIZEOF_IGMP_T];    netdev *ndp;    if ((ndp = ll_dev_2_ndp(devname)) == (netdev *)0)        return FNS_ENODEV;    /* Fill in the packet fields */    packet[IGMP_T_IGMP_TYPE] = IGMP_QUERY;#ifndef IGMP_VERSION_2    max_resp_time = 0;#endif    packet[IGMP_T_MAX_RESP_TIME] = max_resp_time;    /* Address is zero for general query */    HostToMem32(&packet[IGMP_T_IP_ADDR], 0x0 );    /* General query is sent to the all multicast hosts address */    igmp_do_send ( packet, ndp, IGMP_ALLHOST );    return 0;}/********************************************************************** ** igmp_send_group_query * *  PARAMETERS: * *  DESCRIPTION: Sends Host Membership Group-Specific Query request *               (for demo\test purposes). * *  RETURNS: ************************************************************************/int igmp_send_group_query ( igmp_entry *entry, u8 max_response_time ){    IGMP_T packet[SIZEOF_IGMP_T];    /* Fill in the packet fields */    packet[IGMP_T_IGMP_TYPE] = IGMP_QUERY;    packet[IGMP_T_MAX_RESP_TIME] = max_response_time; /* 10ths of a sec */    /* Group specific query has IGMP address field set to group address */    HostToMem32(&packet[IGMP_T_IP_ADDR], entry->ip_multi);    /* Group specific query has destination IP address set to group address */    igmp_do_send ( packet, entry->ndp, entry->ip_multi );    return 0;}/********************************************************************** ** igmp_num () * *  PARAMETERS:  int i                  - index into igmp table *               u8 max_response_time   - upper bound on time * *  DESCRIPTION: Generates a 'random' time in the range of (0,max_response_time] *               where max_response_time is in 10ths of a second. *               If max_response_time is 0 then 100 10ths (10 secs) is used. * * *  RETURNS:     The time in milliseconds for the Fusion timer functions. * ***********************************************************************/u32igmp_num (int i,  u8 max_response_time ){    u32 rv;    u32 mod = modulus;    if( max_response_time > 0 ) {        /* max_response_time is in 10ths of a second and modulus must           be in msecs.        */        mod = ((u32)max_response_time * (u32)100);    }    rv = (igmp_tbl[i].seed + (i+1)*t_time) % mod;    igmp_tbl[i].seed = rv;    return rv;}/********************************************************************** ** igmp_attach () * *  PARAMETERS: * *  DESCRIPTION: Dummy function. * *  RETURNS: ************************************************************************/export int igmp_attach (struct so_t * sop){    return 0;}/********************************************************************** * igmp_start * *  PARAMETERS:     added ndp parameter * *  DESCRIPTION:    Adds Multicast Broadcast addres to a device *                  that is supporting the IGMP. * *  RETURNS:    0 - OK * ***********************************************************************/export int igmp_start (netdev * ndp){    int     err;    a32     ip_all;    HostToNet32(ip_all, IGMP_ALLHOST); /* local multicast */    if (ndp->nd_xflags & F_X_MULTI_ENBL)    {        err = ip_add_multi_route ((char *)ndp->nd_name                        , (char *)&ip_all, 1 );        if (err)        {#ifdef DEBUG    os_printf("igmp_start: ip_add_multi_route returns %d\n",err);#endif            return err;        }    }    return 0;}/****************************************************************************** * * igmpFindNdp * * Given an IP multicast address return the associated ndp */netdev *igmpFindNdp (a32 * a32p){    int i;    u32 ip;    ip = MemToHost32((u8 *)a32p);    i = igmp_find(ip, (netdev *)0);        if (i >= 0)        return igmp_tbl[i].ndp;    else        return (netdev *)0;}#endif /* IGMP_PROTOCOL */

⌨️ 快捷键说明

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