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

📄 ip_mroute.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* ip_mroute.c - internet multicast routing routines *//* Copyright 1984-2001 Wind River Systems, Inc. */#include "copyright_wrs.h"/* * IP multicast forwarding procedures * * Written by David Waitzman, BBN Labs, August 1988. * Modified by Steve Deering, Stanford, February 1989. * Modified by Mark J. Steiglitz, Stanford, May, 1991 * Modified by Van Jacobson, LBL, January 1993 * Modified by Ajit Thyagarajan, PARC, August 1993 * Modified by Bill Fenner, PARC, April 1995 * * MROUTING Revision: 3.5 * $Id: ip_mroute.c,v 1.53 1999/01/18 02:06:57 fenner Exp $ *//*modification history--------------------01i,16jul02,gls  removed include of igmpRouterLib.h01h,25oct01,rae  _mCastRouteFwdHook must be IMPORT01g,12oct01,rae  merge from truestack ver 01x, base 01e (SPRs 70325,                 69594, 69643, upgrade to MROUTE 3.5, etc).01f,24sep01,gls  removed definition and use of __P() macro (SPR #28330)01e,21aug98,n_s  fixed add_lgrp () call to MALLOC(). spr20595.01d,08apr97,vin  added mCastRouteFwdHook deleted ip_mrouter.01c,05dec96,vin  changed malloc(..) to MALLOC(..) to use only network buffers,		 changed free(..) to FREE(..).01b,22nov96,vin  added cluster support replaced m_gethdr(..) with mHdrClGet(..)01a,03mar96,vin  created from BSD4.4 stuff.*/#include "vxWorks.h"/* mandatory vxWorks header */#include "errno.h"#include "timers.h"#include "net/mbuf.h"#include "sys/socket.h"#include "sys/times.h"#include "net/socketvar.h"#include "net/protosw.h"#include "sys/times.h"#include "net/route.h"#include "net/mbuf.h"#include "netinet/in.h"#include "netinet/in_systm.h"#include "netinet/ip.h"#include "netinet/ip_var.h"#include "netinet/in_var.h"#include "netinet/igmp.h"#include "netinet/igmp_var.h"#include "memPartLib.h"#include "tickLib.h"#include "wdLib.h"#include "sockLib.h"#include "timers.h"#include "net/mbuf.h"#include "wdLib.h"#include "netinet/ip_mroute.h"#include "netinet/udp.h"#include "netLib.h"#include "net/systm.h"#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET#include "wvNetLib.h"#endif#endif#ifdef VIRTUAL_STACK#include "netinet/vsLib.h"#include "netinet/vsIgmp.h"#include "netinet/vsMcast.h"#endif /* VIRTUAL_STACK */#ifndef NTOHL#if BYTE_ORDER != BIG_ENDIAN#define NTOHL(d) ((d) = ntohl((d)))#define NTOHS(d) ((d) = ntohs((u_short)(d)))#define HTONL(d) ((d) = htonl((d)))#define HTONS(d) ((d) = htons((u_short)(d)))#else#define NTOHL(d)#define NTOHS(d)#define HTONL(d)#define HTONS(d)#endif#endif/* * Macros for handling bitmaps with one bit per virtual interface. */#define ALL_VIFS (vifi_t)-1#define	VIFM_SET(n, m)		((m) |= (1 << (n)))#define	VIFM_CLR(n, m)		((m) &= ~(1 << (n)))#define	VIFM_ISSET(n, m)	((m) & (1 << (n)))#define	VIFM_CLRALL(m)		((m) = 0x00000000)#define	VIFM_COPY(mfrom, mto)	((mto) = (mfrom))#define	VIFM_SAME(m1, m2)	((m1) == (m2))/* * Globals.  All but ip_mrouter and ip_mrtproto could be static, * except for netstat or debugging purposes. */#ifndef VIRTUAL_STACKextern USHORT ip_id;struct socket * ip_mrouter = 0;IMPORT FUNCPTR _mCastRouteFwdHook;FUNCPTR _pimCacheMissSendHook;static struct mrtstat	mrtstat;/* table of mfc entries */static struct mfc	*mfctable[MFCTBLSIZ];static u_char		nexpire[MFCTBLSIZ];/* table of virtual interfaces */static struct vif	viftable[MAXVIFS];static u_int	mrtdebug = 0;	  /* debug level 	*/static u_int  	tbfdebug = 0;     /* tbf debug level 	*/struct mroute_timer_struct*  expire_upcalls_ch;/* * Define the token bucket filter structures * tbftable -> each vif has one of these for storing info  */static struct tbf tbftable[MAXVIFS];/* * 'Interfaces' associated with decapsulator (so we can tell * packets that went through it from ones that get reflected * by a broken gateway).  These interfaces are never linked into * the system ifnet list & no routes point to them.  I.e., packets * can't be sent this way.  They only exist as a placeholder for * multicast source verification. */static struct ifnet multicast_decap_if[MAXVIFS];/* * Private variables. */static vifi_t	   numvifs = 0;static int have_encap_tunnel = 0;/* * one-back cache used by ipip_input to locate a tunnel's vif * given a datagram's src ip address. */static u_long last_encap_src;static struct vif *last_encap_vif;int pim_assert;#endif /* VIRTUAL_STACK */#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* Set common fields of event identifiers for this module. */LOCAL UCHAR wvNetModuleId = WV_NET_IPMROUTE_MODULE; /* Value for ip_mroute.c */LOCAL UCHAR wvNetLocalFilter = WV_NET_NONE;     /* Available event filter */LOCAL ULONG wvNetEventId;       /* Event identifier: see wvNetLib.h */#endif    /* INCLUDE_WVNET */#endif/* prototype IP hdr for encapsulated packets */static struct ip multicast_encap_iphdr	= {#if BYTE_ORDER == LITTLE_ENDIAN	sizeof(struct ip) >> 2, IPVERSION,#else	IPVERSION, sizeof(struct ip) >> 2,#endif	0,				/* tos */	sizeof(struct ip),		/* total length */	0,				/* id */	0,				/* frag offset */	ENCAP_TTL, ENCAP_PROTO,		0,				/* checksum */};/*  * The timer is a wrapper for watchdog timers... functionality from the net/3 release of the bsd code.   */enum sopt_dir { SOPT_GET, SOPT_SET };struct sockopt {	enum	sopt_dir sopt_dir; /* is this a get or a set? */	int	sopt_level;	/* second arg of [gs]etsockopt */	int	sopt_name;	/* third arg of [gs]etsockopt */	void   *sopt_val;	/* fourth arg of [gs]etsockopt */	size_t	sopt_valsize;	/* (almost) fifth arg of [gs]etsockopt */	struct	proc *sopt_p;	/* calling process or null if kernel */};/* timer struct here enables */typedef struct mroute_timer_struct{	WDOG_ID watchdog_id;	VOIDFUNCPTR expire_routine;	void* argument;} MROUTE_TIMER_STRUCT;static u_long	X_ip_mcast_src __P((int vifi));static int	X_ip_mforward __P(( struct mbuf *m, struct ifnet *ifp, struct ip *ip, struct ip_moptions *imo) );static int	X_ip_mrouter_done __P((void));static int	X_ip_mrouter_get __P((struct socket *so, struct sockopt *m));static int	X_ip_mrouter_set __P((struct socket *so, struct sockopt *m));static int	X_legal_vif_num __P((int vif));static int	X_mrt_ioctl __P((int cmd, caddr_t data));static int get_sg_cnt(struct sioc_sg_req *);static int get_vif_cnt(struct sioc_vif_req *);static int ip_mrouter_init(struct socket *, int);static int add_vif(struct vifctl *);static int del_vif(vifi_t);static int add_mfc(struct mfcctl *);static int del_mfc(struct mfcctl *);static int set_assert(FUNCPTR);static int setDebug(int);static void expire_upcalls(void *);static int ip_mdq(struct mbuf *, struct ifnet *, struct mfc *,		  vifi_t);static void phyint_send(struct ip *, struct vif *, struct mbuf *);static void encap_send(struct ip *, struct vif *, struct mbuf *);static void tbf_control(struct vif *, struct mbuf *, struct ip *, u_long);static void tbf_queue(struct vif *, struct mbuf *);static void tbf_process_q(struct vif *);static void tbf_reprocess_q(void *);static int tbf_dq_sel(struct vif *, struct ip *);static void tbf_send_packet(struct vif *, struct mbuf *);static void tbf_update_tokens(struct vif *);static int priority(struct vif *, struct ip *);void multiencap_decap(struct mbuf *);static void mRouteDumpMfctable();static BOOL oifListIsEmpty(struct mfc* rt);static int mRouteOifsAdd(struct mfc* rt, int oif, int ttl);static int mRouteOifsRemove(struct mfc* rt, int oif);static int mRouteGroupLoopRemove(struct mfc* rt, struct mfc* root);int (*ip_mrouter_done)(void) = X_ip_mrouter_done;u_long (*ip_mcast_src)(int) = X_ip_mcast_src;/* From other BSD code that has yet to be ported */static intsooptcopyin(struct sockopt *, void	*, size_t, size_t);static intsooptcopyout(struct sockopt *, void	*, size_t);static intif_allmulti(struct ifnet *, int);/* wrappers for timers in mroute */static void mRouteNetJobAdd(MROUTE_TIMER_STRUCT* p_timer_struct_object);static MROUTE_TIMER_STRUCT* mRouteTimeout(VOIDFUNCPTR expire_routine, void* argument, int number_of_ticks);static void mRouteUntimeOut(MROUTE_TIMER_STRUCT*  p_timer_struct);#define timeout mRouteTimeout#define untimeout mRouteUntimeOut/* vxWorks wrapper for tickGet */#define GET_TIME(t)	t = tickGet(); #ifdef  _WRS_VXWORKS_5_X#define mRouteNameToPort(ignore, both)  1#else#define mRouteNameToPort igmpNameToPort#endif#ifndef MRT_ALLOC#define MRT_ALLOC KHEAP_ALLOC#endif#ifndef MRT_FREE #define MRT_FREE  KHEAP_FREE#endif/* wrapper for header length */#define	MLEN		(MSIZE - sizeof(M_BLK_HDR))	/* normal data len */#define	MHLEN		(MLEN - sizeof(M_PKT_HDR))	/* data len w/pkthdr */#define MRTDEBUG(printThis, string, param1, param2, param3, param4, param5, param6) \   {\   if ( (_func_logMsg != NULL) && (printThis) )\      (* _func_logMsg) (string, param1, param2, param3, param4, param5, param6);\   }/* bsd function wrapper */#define	MGETHDR(m, how, type) {\		m = mHdrClGet(M_DONTWAIT, MT_DATA, sizeof(*m), TRUE);\		}/* * Hash function for a source, group entry */#define MFCHASH(a, g) MFCHASHMOD(((a) >> 20) ^ ((a) >> 10) ^ (a) ^ \			((g) >> 20) ^ ((g) >> 10) ^ (g))/* * Find a route for a given origin IP address and Multicast group address * Type of service parameter to be added in the future!!! */#define MFCFIND(o, g, rt) { \	struct mfc *_rt = mfctable[MFCHASH(o,g)]; \	rt = NULL; \	++mrtstat.mrts_mfc_lookups; \	while (_rt) { \		if ((_rt->mfc_origin.s_addr == o) && \		    (_rt->mfc_mcastgrp.s_addr == g) && \		    (_rt->mfc_stall == NULL)) { \			rt = _rt; \			break; \		} \		_rt = _rt->mfc_next; \	} \	if (rt == NULL) { \		++mrtstat.mrts_mfc_misses; \	} \}/* * Macros to compute elapsed time efficiently * Borrowed from Van Jacobson's scheduling code */#define TV_DELTA(a, b, delta)  delta = (a) - (b);#define TV_LT(a, b) (((a).tv_usec < (b).tv_usec && \	      (a).tv_sec <= (b).tv_sec) || (a).tv_sec < (b).tv_sec)/* The net/3 code uses the X_ip_mrouter_set command to handle socket options in * a slightly different format.  X_ip_mrouter_cmd reformats the parameters */int X_ip_mrouter_cmd(cmd, so, m)int cmd;struct socket* so;struct mbuf* m;{ 		struct sockopt socket_option; 	int result;	socket_option.sopt_name = cmd;	if (m == NULL) 	{		return (ERROR);	}	else 	{			socket_option.sopt_val = m->m_data; 		socket_option.sopt_valsize = m->mBlkHdr.mLen; 	}	result = X_ip_mrouter_set(so, &socket_option); 	return (0);}int ip_mrouter_cmd (int cmd, struct socket* so, struct mbuf* m) {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_INFO event */    WV_NET_MARKER_2 (NET_AUX_EVENT, WV_NET_INFO, 10, 12,                     WV_NETEVENT_IPMRT_START, so->so_fd, cmd)#endif  /* INCLUDE_WVNET */#endif	return X_ip_mrouter_cmd(cmd, so, m);}/* * Handle MRT setsockopt commands to modify the multicast routing tables. */static intX_ip_mrouter_set(so, sopt)	struct socket *so;	struct sockopt *sopt;{	int	error, optval;	vifi_t	vifi;	struct	vifctl vifc;	struct	mfcctl mfc;	error = 0;	optval = 0;	switch (sopt->sopt_name) {	case MRT_INIT:		error = sooptcopyin(sopt, &optval, sizeof (optval), 				    sizeof (optval) );		optval = (int)(sopt->sopt_val);		if (error)			break;            MRTDEBUG            (                (mrtdebug &DEBUG_MFC),                "MROUTE: IP_MROUTER received ip_mrouter init so=%p, optval=%i.\n",                 (int)so,                 optval,3,4,5,6            );		error = ip_mrouter_init(so, optval);		break;	case MRT_DONE:            MRTDEBUG            (                (mrtdebug &DEBUG_MFC),			    "MROUTE: IP_MROUTER received MRT_DONE.\n",                1,2,3,4,5,6            );		error = ip_mrouter_done();		break;	case MRT_ADD_VIF:			MRTDEBUG            (                (mrtdebug &DEBUG_MFC),			    "MROUTE: IP_MROUTER received MRT_ADD_VIF.\n",                1,2,3,4,5,6            );		error = sooptcopyin(sopt, &vifc, sizeof vifc, sizeof vifc);		if (error)			break;		error = add_vif(&vifc);		break;	case MRT_DEL_VIF:			MRTDEBUG            (                (mrtdebug &DEBUG_MFC),    			"MROUTE: IP_MROUTER received MRT_DEL_VIF.\n",                1,2,3,4,5,6            );		error = sooptcopyin(sopt, &vifi, sizeof (vifi), sizeof (vifi));		if (error)			break;		error = del_vif(vifi);		break;	case MRT_ADD_MFC:	case MRT_DEL_MFC:            MRTDEBUG            (                (mrtdebug &DEBUG_MFC),                "MROUTE: IP_MROUTER received MRT_ADD/DEL_MFC.\n",                1,2,3,4,5,6            );		error = sooptcopyin(sopt, &mfc, sizeof mfc, sizeof mfc);		if (error){					MRTDEBUG(mrtdebug,"MROUTE: I am not dqing...  sooptcopyin error.\n",1,2,3,4,5,6);					break;                   }		if (sopt->sopt_name == MRT_ADD_MFC)			error = add_mfc(&mfc);		else			error = del_mfc(&mfc);		break;	case MRT_ASSERT:			MRTDEBUG            (                (mrtdebug &DEBUG_MFC),			    "MROUTE: IP_MROUTER received MRT_ASSERT.\n",                1,2,3,4,5,6            );		error = sooptcopyin(sopt, &optval, sizeof optval, 				    sizeof optval);		if (error)			break;		set_assert( (FUNCPTR) optval);		break;	case MRT_DEBUG:		MRTDEBUG        (            (mrtdebug &DEBUG_MFC),            "MROUTE: IP_MROUTER received MRT_DEBUG.\n",            1,2,3,4,5,6        );		error = sooptcopyin(sopt, &optval, sizeof optval, 				    sizeof optval);		if (error)			break;		setDebug(optval);		break;	default:#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_ERROR event */            WV_NET_MARKER_1 (NET_AUX_EVENT, WV_NET_ERROR, 23, 3,                             WV_NETEVENT_IPMRT_BADCMD, sopt->sopt_name)#endif  /* INCLUDE_WVNET */#endif		error = EOPNOTSUPP;		break;	}	return (error);}int (*ip_mrouter_set)(struct socket *, struct sockopt *) = X_ip_mrouter_set;/* * Handle MRT getsockopt commands */static intX_ip_mrouter_get(so, sopt)	struct socket *so;	struct sockopt *sopt;{	int error;	static int version = 0x0305; /* !!! why is this here? XXX */	switch (sopt->sopt_name) {	case MRT_VERSION:		error = sooptcopyout(sopt, &version, sizeof version);		break;	case MRT_ASSERT:		error = sooptcopyout(sopt, &pim_assert, sizeof pim_assert);		break;	default:		error = EOPNOTSUPP;		break;	}

⌨️ 快捷键说明

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