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

📄 igmp.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifdef INCLUDE_WVNET    /* WV_NET_WARNING event */            WV_NET_DSTADDRIN_EVENT_3 (NET_CORE_EVENT, WV_NET_WARNING, 5, 4,                                        ip->ip_dst.s_addr,                                      WV_NETEVENT_IGMPIN_BADADDR, WV_NET_RECV,                                      igmp->igmp_type, ip->ip_dst.s_addr, 0)#endif  /* INCLUDE_WVNET */#endif				return;			}		}		/*		 * - Start the timers in all of our membership records		 *   that the query applies to for the interface on		 *   which the query arrived excl. those that belong		 *   to the "all-hosts" group (224.0.0.1).		 * - Restart any timer that is already running but has		 *   a value longer than the requested timeout.		 * - Use the value specified in the query message as		 *   the maximum timeout.		 */                {                IN_MULTI_HEAD * inMultiHead;                int		ix;                for (ix = 0; ix <= mCastHashInfo.hashMask; ix++)                    {                    inMultiHead = &mCastHashInfo.hashBase [ix];                    if (inMultiHead != NULL)                        {                        for (inm = inMultiHead->lh_first;                             inm != NULL;                             inm = inm->inm_hash.le_next)                            {                            if (inm->inm_ifp == ifp &&                                inm->inm_addr.s_addr != igmp_all_hosts_group &&                                (igmp->igmp_group.s_addr == 0 ||                                 igmp->igmp_group.s_addr == inm->inm_addr.s_addr))                                {                                if (inm->inm_timer == 0 ||                                    inm->inm_timer > timer)                                    {                                    inm->inm_timer =                                        IGMP_RANDOM_DELAY(timer);                                    igmp_timers_are_running = 1;                                    }                                }                                                        }                        }                    }                }        		break;	case IGMP_V1_MEMBERSHIP_REPORT:	case IGMP_V2_MEMBERSHIP_REPORT:		/*		 * For fast leave to work, we have to know that we are the		 * last person to send a report for this group.  Reports		 * can potentially get looped back if we are a multicast		 * router, so discard reports sourced by me.		 */		IFP_TO_IA(ifp, ia);		if (ia && ip->ip_src.s_addr == IA_SIN(ia)->sin_addr.s_addr)			break;		++igmpstat.igps_rcv_reports;		if (ifp->if_flags & IFF_LOOPBACK)			break;		if (!IN_MULTICAST(ntohl(igmp->igmp_group.s_addr))) {			++igmpstat.igps_rcv_badreports;			m_freem(m);#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_WARNING event */            WV_NET_DSTADDRIN_EVENT_3 (NET_CORE_EVENT, WV_NET_WARNING, 5, 4,                                        ip->ip_dst.s_addr,                                      WV_NETEVENT_IGMPIN_BADADDR, WV_NET_RECV,                                      igmp->igmp_type, ip->ip_dst.s_addr,                                      igmp->igmp_group.s_addr)#endif  /* INCLUDE_WVNET */#endif			return;		}		/*		 * KLUDGE: if the IP source address of the report has an		 * unspecified (i.e., zero) subnet number, as is allowed for		 * a booting host, replace it with the correct subnet number		 * so that a process-level multicast routing demon can		 * determine which subnet it arrived from.  This is necessary		 * to compensate for the lack of any way for a process to		 * determine the arrival interface of an incoming packet.		 */		if ((ntohl(ip->ip_src.s_addr) & IN_CLASSA_NET) == 0)			if (ia) ip->ip_src.s_addr = htonl(ia->ia_subnet);		/*		 * If we belong to the group being reported, stop		 * our timer for that group.		 */		IN_LOOKUP_MULTI(igmp->igmp_group, ifp, inm);		if (inm != NULL) {			inm->inm_timer = 0;			++igmpstat.igps_rcv_ourreports;			inm->inm_state = IGMP_OTHERMEMBER;		}		break;	}	/*	 * Pass all valid IGMP packets up to any process(es) listening	 * on a raw IGMP socket.	 */#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_NOTICE event */        WV_NET_ADDRIN_EVENT_2 (NET_CORE_EVENT, WV_NET_NOTICE, 5, 5,                               ip->ip_src.s_addr, ip->ip_dst.s_addr,                            WV_NETEVENT_IGMPIN_FINISH, WV_NET_RECV,                               ip->ip_src.s_addr, ip->ip_dst.s_addr)#endif  /* INCLUDE_WVNET */#endif        if (_igmpMessageHook) /* if IGMP routing is on */            {            _igmpMessageHook (m->m_pkthdr.rcvif->if_index,                         &(ip->ip_src), igmp);            m_freem(m);            }        else            rip_input(m);}voidigmp_joingroup(inm)struct in_multi *inm;{int s = splnet();    #ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_VERBOSE event */    WV_NET_MARKER_1 (NET_AUX_EVENT, WV_NET_VERBOSE, 16, 9,                     WV_NETEVENT_IGMPJOIN_START, inm->inm_addr.s_addr)#endif  /* INCLUDE_WVNET */#endif            if (_igmpJoinAlertHook != NULL)            _igmpJoinAlertHook(inm->inm_ifp->if_index);    if (inm->inm_addr.s_addr == igmp_all_hosts_group        || inm->inm_ifp->if_flags & IFF_LOOPBACK) {    inm->inm_timer = 0;    inm->inm_state = IGMP_OTHERMEMBER;    } else {    inm->inm_rti = find_rti(inm->inm_ifp);    igmp_sendpkt(inm, inm->inm_rti->rti_type, 0);		inm->inm_timer = IGMP_RANDOM_DELAY(IGMP_MAX_HOST_REPORT_DELAY *                                                             PR_FASTHZ);		inm->inm_state = IGMP_IREPORTEDLAST;		igmp_timers_are_running = 1;	}    splx(s);    }voidigmp_leavegroup(inm)struct in_multi *inm;{#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_VERBOSE event */         WV_NET_MARKER_1 (NET_AUX_EVENT, WV_NET_VERBOSE, 17, 10,                             WV_NETEVENT_IGMPLEAVE_START, inm->inm_addr.s_addr)#endif  /* INCLUDE_WVNET */#endif	 if (_igmpLeaveAlertHook != NULL)            _igmpLeaveAlertHook(inm->inm_ifp->if_index);         if (inm->inm_state == IGMP_IREPORTEDLAST &&	    inm->inm_addr.s_addr != igmp_all_hosts_group &&	    !(inm->inm_ifp->if_flags & IFF_LOOPBACK) &&	    inm->inm_rti->rti_type != IGMP_V1_ROUTER)		igmp_sendpkt(inm, IGMP_V2_LEAVE_GROUP, igmp_all_rtrs_group);}voidigmp_fasttimo(){	register struct in_multi *inm;	int s;	#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_INFO event */        WV_NET_MARKER_0 (NET_AUX_EVENT, WV_NET_INFO, 4, 7,                         WV_NETEVENT_IGMPFASTTIMER_START)#endif  /* INCLUDE_WVNET */#endif	/*	 * Quick check to see if any work needs to be done, in order	 * to minimize the overhead of fasttimo processing.	 */	if (!igmp_timers_are_running)		return;	s = splnet();	igmp_timers_are_running = 0;        {        IN_MULTI_HEAD * inMultiHead;        int		ix;        for (ix = 0; ix <= mCastHashInfo.hashMask; ix++)            {            inMultiHead = &mCastHashInfo.hashBase [ix];            if (inMultiHead != NULL)                {                for (inm = inMultiHead->lh_first;                     inm != NULL;                     inm = inm->inm_hash.le_next)                    {                    if (inm->inm_timer == 0)                        {                        /* do nothing */                        }                    else if (--inm->inm_timer == 0)                        {			igmp_sendpkt(inm, inm->inm_rti->rti_type, 0);			inm->inm_state = IGMP_IREPORTEDLAST;			}                    else                        {                        igmp_timers_are_running = 1;                        }                    }                }            }    }	splx(s);}voidigmp_slowtimo(){	int s = splnet();	register struct router_info *rti =  Head;#ifdef IGMP_DEBUG_XXX	printf("[igmp.c,_slowtimo] -- > entering \n");#endif	while (rti) {	    if (rti->rti_type == IGMP_V1_ROUTER) {		rti->rti_time++;                if(_igmpQuerierTimeUpdateHook != NULL)                            _igmpQuerierTimeUpdateHook(rti->rti_ifp->if_index, rti->rti_time);		if (rti->rti_time >= IGMP_AGE_THRESHOLD) {			rti->rti_type = IGMP_V2_ROUTER;		}	    }	    rti = rti->rti_next;	}#ifdef IGMP_DEBUG_XXX	printf("[igmp.c,_slowtimo] -- > exiting \n");#endif	splx(s);}static struct route igmprt;static voidigmp_sendpkt(inm, type, addr)	struct in_multi *inm;	int type;	unsigned long addr;{        struct mbuf *m;        struct igmp *igmp;        struct ip *ip;        struct ip_moptions imo;        m = mHdrClGet(M_DONTWAIT, MT_HEADER, CL_SIZE_128, TRUE);	if (m == NULL)            {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_EMERGENCY event */            WV_NET_MARKER_0 (NET_AUX_EVENT, WV_NET_EMERGENCY, 8, 1,                            WV_NETEVENT_IGMPSENDREP_NOBUFS)#endif  /* INCLUDE_WVNET */#endif            return;            }	m->m_pkthdr.rcvif = loif;	m->m_pkthdr.len = sizeof(struct ip) + IGMP_MINLEN;	MH_ALIGN(m, IGMP_MINLEN + sizeof(struct ip));	m->m_data += sizeof(struct ip);        m->m_len = IGMP_MINLEN;        igmp = mtod(m, struct igmp *);        igmp->igmp_type   = type;        igmp->igmp_code   = 0;        igmp->igmp_group  = inm->inm_addr;        igmp->igmp_cksum  = 0;        igmp->igmp_cksum  = in_cksum(m, IGMP_MINLEN);        m->m_data -= sizeof(struct ip);        m->m_len += sizeof(struct ip);        ip = mtod(m, struct ip *);        ip->ip_tos        = 0;        ip->ip_len        = sizeof(struct ip) + IGMP_MINLEN;        ip->ip_off        = 0;        ip->ip_p          = IPPROTO_IGMP;        ip->ip_src.s_addr = INADDR_ANY;        ip->ip_dst.s_addr = addr ? addr : igmp->igmp_group.s_addr;        imo.imo_multicast_ifp  = inm->inm_ifp;        imo.imo_multicast_ttl  = 1;	/*	imo.imo_multicast_vif  = -1; */        /*         * Request loopback of the report if we are acting as a multicast         * router, so that the process-level routing demon can hear it.         */       imo.imo_multicast_loop = (_mCastRouteFwdHook != NULL);#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_NOTICE event */        WV_NET_DSTADDROUT_EVENT_1 (NET_CORE_EVENT, WV_NET_NOTICE, 6, 6,                                   ip->ip_dst.s_addr,                                   WV_NETEVENT_IGMPSENDREP_FINISH, WV_NET_SEND,                                   ip->ip_dst.s_addr)#endif  /* INCLUDE_WVNET */#endif	/*	 * XXX	 * Do we have to worry about reentrancy here?  Don't think so.	 */        ip_output(m, router_alert, &igmprt, 0, &imo);        ++igmpstat.igps_snd_reports;}

⌨️ 快捷键说明

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