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

📄 ip_mroute.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	MRTDEBUG    (        (mrtdebug),	    "MROUTE: ip_mrouter_get returns %i error",         error,2,3,4,5,6    );	return (error);}int (*ip_mrouter_get)(struct socket *, struct sockopt *) = X_ip_mrouter_get;/* * Handle ioctl commands to obtain information from the cache */static intX_mrt_ioctl(cmd, data)    int cmd;    caddr_t data;{    int error = 0;    switch (cmd) {	case (SIOCGETVIFCNT):	    return (get_vif_cnt((struct sioc_vif_req *)data));	    break;	case (SIOCGETSGCNT):	    return (get_sg_cnt((struct sioc_sg_req *)data));	    break;	default:	    return (EINVAL);	    break;    }    return error;}int (*mrt_ioctl)(int, caddr_t) = X_mrt_ioctl;/* * returns the packet, byte, rpf-failure count for the source group provided */static intget_sg_cnt(req)    struct sioc_sg_req *req;{    struct mfc *rt;    int s;    s = splnet();    MFCFIND(req->src.s_addr, req->grp.s_addr, rt);    splx(s);    if (rt != NULL) {	req->pktcnt = rt->mfc_pkt_cnt;	req->bytecnt = rt->mfc_byte_cnt;	req->wrong_if = rt->mfc_wrong_if;    } else	req->pktcnt = req->bytecnt = req->wrong_if = 0xffffffff;    return 0;}/* * returns the input and output packet and byte counts on the vif provided */static intget_vif_cnt(req)    struct sioc_vif_req *req;{    vifi_t vifi = req->vifi;    if (vifi >= numvifs) return EINVAL;    req->icount = viftable[vifi].v_pkt_in;    req->ocount = viftable[vifi].v_pkt_out;    req->ibytes = viftable[vifi].v_bytes_in;    req->obytes = viftable[vifi].v_bytes_out;    return 0;}/* * Enable multicast routing */static intip_mrouter_init(so, version)	struct socket *so;	int version;{    if (so == NULL)        return (EINVAL);    MRTDEBUG        (            (mrtdebug),            "MROUTE: ip_mrouter_init: so_type = %d, pr_protocol = %d\n",			so->so_type,             so->so_proto->pr_protocol,            3,4,5,6        );	if ( _mCastRouteFwdHook != NULL)	/* if already installed */            return (EADDRINUSE);	else		_mCastRouteFwdHook = X_ip_mforward; 	/* forwarding func ptr */    if (so->so_type != SOCK_RAW ||	so->so_proto->pr_protocol != IPPROTO_IGMP) return EOPNOTSUPP;    if (ip_mrouter != 0) 	{		return EADDRINUSE;	}    ip_mrouter = (struct socket*) so->so_fd;    bzero((caddr_t)mfctable, sizeof(mfctable));    bzero((caddr_t)nexpire, sizeof(nexpire));    pim_assert = 0;    expire_upcalls_ch = timeout(expire_upcalls, (caddr_t)NULL, EXPIRE_TIMEOUT);    MRTDEBUG        (            (mrtdebug),		    "MROUTE: ip_mrouter_init returning success.\n",            1,2,3,4,5,6        );    return 0;}/* * Disable multicast routing */static intX_ip_mrouter_done(){    vifi_t vifi;    int i;    struct ifnet *ifp;    struct ifreq ifr;    struct mfc *rt;    struct rtdetq *rte;    int s;    s = splnet();    /*     * For each phyint in use, disable promiscuous reception of all IP     * multicasts.     */    for (vifi = 0; vifi < numvifs; vifi++) {	if (viftable[vifi].v_lcl_addr.s_addr != 0 &&	    !(viftable[vifi].v_flags & VIFF_TUNNEL)) {	    ((struct sockaddr_in *)&(ifr.ifr_addr))->sin_family = AF_INET;	    ((struct sockaddr_in *)&(ifr.ifr_addr))->sin_addr.s_addr								= INADDR_ANY;	    ifp = viftable[vifi].v_ifp;	    if_allmulti(ifp, 0);	}    }    bzero((caddr_t)tbftable, sizeof(tbftable));    bzero((caddr_t)viftable, sizeof(viftable));    numvifs = 0;    pim_assert = 0;    untimeout(expire_upcalls_ch);    expire_upcalls_ch = 0;    _mCastRouteFwdHook = NULL;    _pimCacheMissSendHook = NULL;    /*     * Free all multicast forwarding cache entries.     */    for (i = 0; i < MFCTBLSIZ; i++) {	for (rt = mfctable[i]; rt != NULL; ) {	    struct mfc *nr = rt->mfc_next;	    for (rte = rt->mfc_stall; rte != NULL; ) {		struct rtdetq *n = rte->next;		m_freem(rte->m);		MRT_FREE((char*) rte);		rte = n;	    }	    MRT_FREE((char*) rt);	    rt = nr;	}    }    bzero((caddr_t)mfctable, sizeof(mfctable));    /*     * Reset de-encapsulation cache     */    last_encap_src = 0;    last_encap_vif = NULL;    have_encap_tunnel = 0;     ip_mrouter = 0;    splx(s);    MRTDEBUG        (            (mrtdebug),		    "MROUTE: ip_mrouter_done\n",            1,2,3,4,5,6        );    return 0;}/* * Set PIM assert processing global */static intset_assert(FUNCPTR i){    pim_assert = (int)i;	_pimCacheMissSendHook = (FUNCPTR)i;    return 0;}/* * Sets mroute debug processing global */static intsetDebug( int i){    mrtdebug = i;    return 0;}/* * Add a vif to the vif table */static intadd_vif(vifcp)    struct vifctl *vifcp;{    struct vif *vifp = viftable + vifcp->vifc_vifi;    static struct sockaddr_in sin = {sizeof sin, AF_INET};    struct ifaddr *ifa;    struct ifnet *ifp;    int error, s;    struct tbf *v_tbf = tbftable + vifcp->vifc_vifi;    if (vifcp->vifc_vifi >= MAXVIFS)        {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_ERROR event */        WV_NET_MARKER_2 (NET_AUX_EVENT, WV_NET_ERROR, 24, 4,                         WV_NETEVENT_ADDVIF_BADINDEX,                         vifcp->vifc_vifi, MAXVIFS)#endif  /* INCLUDE_WVNET */#endif        return EINVAL;        }    if (vifp->v_lcl_addr.s_addr != 0)        {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_ERROR event */        WV_NET_MARKER_2 (NET_AUX_EVENT, WV_NET_ERROR, 25, 5,                         WV_NETEVENT_ADDVIF_BADENTRY,                         vifcp->vifc_vifi, vifp->v_lcl_addr.s_addr)#endif  /* INCLUDE_WVNET */#endif        return EADDRINUSE;        }    /* Find the interface with an address in AF_INET family */    sin.sin_addr = vifcp->vifc_lcl_addr;    ifa = ifa_ifwithaddr((struct sockaddr *)&sin);    if (ifa == 0)        {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_ERROR event */        WV_NET_MARKER_2 (NET_AUX_EVENT, WV_NET_ERROR, 26, 6,                         WV_NETEVENT_ADDVIF_SEARCHFAIL,                         vifcp->vifc_vifi, sin.sin_addr.s_addr)#endif  /* INCLUDE_WVNET */#endif        return EADDRNOTAVAIL;        }    ifp = ifa->ifa_ifp;    if (vifcp->vifc_flags & VIFF_TUNNEL) {	if ((vifcp->vifc_flags & VIFF_SRCRT) == 0) {		/*		 * An encapsulating tunnel is wanted.  Tell ipip_input() to		 * start paying attention to encapsulated packets.		 */		if (have_encap_tunnel == 0) {			have_encap_tunnel = 1;			for (s = 0; s < MAXVIFS; ++s) {				multicast_decap_if[s].if_name = "mdecap";				multicast_decap_if[s].if_unit = s;			}		}		/*		 * Set interface to fake encapsulator interface		 */		ifp = &multicast_decap_if[vifcp->vifc_vifi];		/*		 * Prepare cached route entry		 */		bzero((char*)&vifp->v_route, sizeof(vifp->v_route));	} else {        MRTDEBUG        (            (mrtdebug),		    "MROUTE: source routed tunnels not supported\n",            1,2,3,4,5,6        );	    return EOPNOTSUPP;	}    } else {	/* Make sure the interface supports multicast */	if ((ifp->if_flags & IFF_MULTICAST) == 0)            {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_ERROR event */            WV_NET_MARKER_2 (NET_AUX_EVENT, WV_NET_ERROR, 27, 7,                             WV_NETEVENT_ADDVIF_BADFLAGS,                             vifcp->vifc_vifi, ifp)#endif  /* INCLUDE_WVNET */#endif	    return EOPNOTSUPP;            }	/* Enable promiscuous reception of all IP multicasts from the if */	s = splnet();	error = if_allmulti(ifp, 1);/* Many wrs drivers don't support this */	splx(s);	if (error)	    return error;    }    s = splnet();    /* define parameters for the tbf structure */    vifp->v_tbf = v_tbf;    GET_TIME(vifp->v_tbf->tbf_last_pkt_t);    vifp->v_tbf->tbf_n_tok = 0;    vifp->v_tbf->tbf_q_len = 0;    vifp->v_tbf->tbf_max_q_len = MAXQSIZE;    vifp->v_tbf->tbf_q = vifp->v_tbf->tbf_t = NULL;    vifp->v_flags     = vifcp->vifc_flags;    vifp->v_threshold = vifcp->vifc_threshold;    vifp->v_lcl_addr  = vifcp->vifc_lcl_addr;    vifp->v_rmt_addr  = vifcp->vifc_rmt_addr;    vifp->v_ifp       = ifp;    /* scaling up here allows division by 1024 in critical code */    vifp->v_rate_limit= vifcp->vifc_rate_limit * 1024 / 1000;    /* initialize per vif pkt counters */    vifp->v_pkt_in    = 0;    vifp->v_pkt_out   = 0;    vifp->v_bytes_in  = 0;    vifp->v_bytes_out = 0;    splx(s);    /* Adjust numvifs up if the vifi is higher than numvifs */    if (numvifs <= vifcp->vifc_vifi) numvifs = vifcp->vifc_vifi + 1;    MRTDEBUG    (        (mrtdebug),		"MROUTE: add_vif #%d, lcladdr %lx, %s %lx, thresh %x, rate %d\n",        vifcp->vifc_vifi, 		(u_long)ntohl(vifcp->vifc_lcl_addr.s_addr),        (vifcp->vifc_flags & VIFF_TUNNEL) ? (int)"rmtaddr" : (int)"mask",        (u_long)ntohl(vifcp->vifc_rmt_addr.s_addr),        (int)vifcp->vifc_threshold,         1    );        return 0;}/* * Delete a vif from the vif table */static intdel_vif(vifi)	vifi_t vifi;{    struct vif *vifp = &viftable[vifi];    struct mbuf *m;    struct ifnet *ifp;    struct ifreq ifr;    int s;    if (vifi >= numvifs)        {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_ERROR event */        WV_NET_MARKER_2 (NET_AUX_EVENT, WV_NET_ERROR, 28, 8,                         WV_NETEVENT_DELVIF_BADINDEX, vifi, numvifs)#endif  /* INCLUDE_WVNET */#endif        return EINVAL;        }    if (vifp->v_lcl_addr.s_addr == 0)        {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_ERROR event */        WV_NET_MARKER_1 (NET_AUX_EVENT, WV_NET_ERROR, 29, 9,                         WV_NETEVENT_DELVIF_BADENTRY, vifi)#endif  /* INCLUDE_WVNET */#endif        return EADDRNOTAVAIL;        }    s = splnet();    if (!(vifp->v_flags & VIFF_TUNNEL)) {	((struct sockaddr_in *)&(ifr.ifr_addr))->sin_family = AF_INET;	((struct sockaddr_in *)&(ifr.ifr_addr))->sin_addr.s_addr = INADDR_ANY;	ifp = vifp->v_ifp;	if_allmulti(ifp, 0);    }    if (vifp == last_encap_vif) {	last_encap_vif = 0;	last_encap_src = 0;    }    /*     * Free packets queued at the interface     */    while (vifp->v_tbf->tbf_q) {	m = vifp->v_tbf->tbf_q;	vifp->v_tbf->tbf_q = m->m_act;	m_freem(m);    }    bzero((caddr_t)vifp->v_tbf, sizeof(*(vifp->v_tbf)));    bzero((caddr_t)vifp, sizeof (*vifp));    MRTDEBUG    (        (mrtdebug),        "MROUTE: del_vif %d, numvifs %d\n",         vifi,         numvifs,        3,4,5,6    );    /* Adjust numvifs down */    for (vifi = numvifs; vifi > 0; vifi--)	if (viftable[vifi-1].v_lcl_addr.s_addr != 0) break;    numvifs = vifi;    splx(s);    return 0;}/*  * modifies the outgoing viftable for an s,g entry */static int mRouteOifsAdd    (    struct mfc* rt,     int oif,     int ttl    ){	struct mfc* probe;	if(rt->mfc_root_rt== NULL)		return (ERROR);	rt->mfc_root_rt->mfc_ttls[oif] = ttl;		probe = rt->mfc_root_rt;    while (probe->mfc_next_g != probe->mfc_root_rt)    {   		probe = probe->mfc_next_g;		probe->mfc_ttls[oif] = ttl;    }	return (OK);}	 /* * Add an mfc entry */static intadd_mfc(mfccp)    struct mfcctl *mfccp;{    struct mfc *rt;    struct mfc *root_rt;    u_long hash;    struct rtdetq *rte;    u_short nstl;    int s;    int i;	rt = NULL;    MRTDEBUG    (        (mrtdebug & DEBUG_MFC),        "MROUTE: add_mfc received o %p g %p p %p\n",        ntohl(mfccp->mfcc_origin.s_addr),        ntohl(mfccp->mfcc_mcastgrp.s_addr),		(u_long)mfccp->mfcc_parent,        4,5,6    );    MRTDEBUG    (        (mrtdebug & DEBUG_MFC),        "MROUTE: add_mfc ttls%i%i%i%i%i\n.",        mfccp->mfcc_ttls[0],        mfccp->mfcc_ttls[1],        mfccp->mfcc_ttls[2],        mfccp->mfcc_ttls[3],        mfccp->mfcc_ttls[4],        6    );    MFCFIND(mfccp->mfcc_origin.s_addr, mfccp->mfcc_mcastgrp.s_addr, rt);    /* If an entry already exists, just update the fields */    if (rt) 	{        MRTDEBUG        (            (mrtdebug & DEBUG_MFC),			"MROUTE: add_mfc update o %lx g %lx p %x\n",            (u_long)ntohl(mfccp->mfcc_origin.s_addr),            (u_long)ntohl(mfccp->mfcc_mcastgrp.s_addr),			mfccp->mfcc_parent,            4,5,6

⌨️ 快捷键说明

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