📄 ip_mroute.c
字号:
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 + -