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

📄 rsrr.c

📁 radius协议源码÷The Radius Stack will connect to a Radius Server. This stack implementation is built upo
💻 C
📖 第 1 页 / 共 2 页
字号:
	case NET_ADDR_IPv4:		/* 		 * IPv4 Unicast 		 */		if (!IN_IS_ADDR_MULTICAST(&(NET_GET_ADDR_IPv4(net_addr_ip(dst))))) {			if (NoUnicast)				return -1;			if (src == 0) {			/* correct, go on */				rv = unicast_route(dst);				if (rv == -1) {					/* 					 * Error occurred 					 */					return (-1);				}#if defined(PF_ROUTE)  && !defined(sgi_53) && !defined(linux)				else if (rv == 0 && asynchronous == 1) {					/* 					 * Asynchronous reply, 					 * return sequence number 					 */					return seq;				}#endif      /* PF_ROUTE */				else {					/* 					 * Synchronous reply,					 * set up bitmap then return					 */					bmp_set(bmp, rv);					asynchronous = 1;					return (0);				}			}			else {				log(LOG_ERR,errno,"Invalid IPv4 unicast address for query",0);				return (-1);			}		}		/* 		 * IPv4 Multicast 		 */		else {			if (NoV4Mroute)				return -1;			/* 			 * Make sure src is not null, and it's not multicast 			 * address 			 */			if (src != 0 && 				!IN_IS_ADDR_MULTICAST(&(NET_GET_ADDR_IPv4(net_addr_ip(src))))) {#ifdef	HOST_ONLY				assert(0);#else	/* !HOST_ONLY */				/* 				 * send out the route query if this route query is not 				 * intended to delete the route change notification				 * cache in the routing daemon or if it is, make sure 				 * RSRRv2 is the one used by IPv4 multicast routing 				 * daemon, since the current implementation of RSRR 				 * stub in mrouted uses RSRRv1 and it has no processing				 * for route change notification cache delete request				 * from rsvpd.				 * rv is either -1 for error or query_id 				 */				if (note || rsrr_use_v2_ipv4)					rv = rsrr_send_rq(psb, ses, AF_INET, src, dst, note);				return rv;#endif	/* !HOST_ONLY */			}			else {				log(LOG_ERR,errno,"Invalid IPv4 multicast address for query",0);				return (-1);			}		}		break;#ifdef	USE_IPV6	case NET_ADDR_IPv6:		/* 		 * IPv6 Unicast 		 */		if (!IN6_IS_ADDR_MULTICAST(&NET_GET_ADDR_IPv6(net_addr_ip(dst)))) {			if (NoUnicast)				return -1;			if (src == 0) {			/* correct, go on */				rv = unicast_route(dst);				if (rv == -1) {					/* 					 * Error occurred 					 */					return (-1);				}#if defined(PF_ROUTE)  && !defined(sgi_53) && !defined(linux)				else if (rv == 0 && asynchronous == 1) {					/* 					 * Asynchronous reply 					 */					return seq;				}#endif      /* PF_ROUTE */				else {					/* 					 * Synchronous reply 					 */					bmp_set(bmp, rv);					asynchronous = 1;					return (0);				}			}			else {				log(LOG_ERR,errno,"Incorrect address for query",0);				return (-1);			}		}		/* 		 * IPv6 Multicast 		 */		else {			if (NoV6Mroute)				return -1;			/* 			 * Make sure src is not null, and it's not multicast 			 * address 			 */			if (src != 0 && 				!IN6_IS_ADDR_MULTICAST(&NET_GET_ADDR_IPv6(net_addr_ip(src)))) {				if (NoV6Mroute) return -1;#ifdef	HOST_ONLY				assert(0);#else	/* !HOST_ONLY */				/* 				 * send out route query				 * rv is either -1 for error or query_id 				 */				rv = rsrr_send_rq(psb, ses, AF_INET6, src, dst, note);				return rv;#endif	/* !HOST_ONLY */			}		}		break;#endif	/* USE_IPV6 */	default:		log(LOG_ERR,errno,"No such type exists",0);		return (-1);	}	/* 	 * if here, must be an error 	 */	return -1;}#endif	/* HOST_ONLY *//* * The corresponding upcall for rsrr_route_query() after a route_query * or for notification of route changes * * Argument: qid - query ID.  Could be PSB address in multicast case, *				    or rtm_seq in routing socket case. *			 src - source address *			 dst - destination address *			 iif - incoming interface *			 bmp - outgoing interface bitmap *			 tree_type - type of tree for this route * * Returns:  0 if succeed. */int rsrr_route_reply(u_long qid, net_addr *src, net_addr *dst, 	int iif, bitmap *bmp, int note, u_char tree_type){    struct rsrr_query_table *qt;	Session *dp;	PSB *sp;	int i;	/* 	 * Unicast case 	 */	if (src == (net_addr *)0 && dst != (net_addr *)0) {		/* 		 * Unicast routing reply, result is stored in bmp,		 * which should be the global variable bmp_unicast.		 */		if (unicast_query_waiting == 1) {			/* 			 * Asynchronous route reply 			 */			unicast_result_ready = 1;			return 0;		}		else {			/* 			 * route change notification 			 */			for (i= 0; i < SESS_HASH_SIZE; i++) {			  for (dp = session_hash[i]; dp != NULL; dp = dp->d_next) {				switch (NET_GET_TYPE(net_addr_ip(dst))) {				case NET_ADDR_IPv4:					/* 					 * IPv4 unicast case 					 */					if (dp->d_session->sess4_addr.s_addr == 						NET_GET_ADDR_IPv4(net_addr_ip(dst)).s_addr) {						/* 						 * Found session with same group/dest address. 						 */						for (sp=dp->d_PSB_list; sp != NULL; sp=sp->ps_next) {								SetNotifyBit(sp, note);								rsrr_update(dp, sp, iif, bmp);						}					}					break;#ifdef	USE_IPV6				case NET_ADDR_IPv6:					/* 					 * IPv6 unicast case 					 */					if (IN6_ARE_ADDR_EQUAL(&dp->d_session->sess6_addr, 						&NET_GET_ADDR_IPv6(net_addr_ip(dst)))) {						/* 						 * Found session with same group/dest address. 						 */						for (sp=dp->d_PSB_list; sp != NULL; sp=sp->ps_next) {								SetNotifyBit(sp, note);								rsrr_update(dp, sp, iif, bmp);						}					}					break;#endif	/* USE_IPV6 */				default:					break;				}			  }		  	}		}		return 0;	}	/* 	 * Multicast case 	 */    /* 	 * Check if query id is cached. 	 */    qt = rsrr_qt_lookup(qid);    if (qt != NULL) {		SetNotifyBit((PSB *)(qt->ptrP), note);		/* 		 * Update PSB with new route info, then complete process of		 * path info with any needed refreshes.		 */		rsrr_update((Session *)(qt->ptrS), (PSB *)(qt->ptrP), iif, bmp);		/* 		 * Delete the query entry from the table.  We only use the 		 * table for pending queries.  Route change notification 		 * queries can suffer a longer lookup because they are rare.		 */		rsrr_qt_delete(qt->query_id);		return 0;    }    /* 	 * None cached.  Must scan entire state list looking for 	 * affected sessions and senders.     */    for (i= 0; i < SESS_HASH_SIZE; i++) {      for (dp = session_hash[i]; dp != NULL; dp = dp->d_next) {      	switch (NET_GET_TYPE(net_addr_ip(dst))) {		case NET_ADDR_IPv4:      		/* 			 * IPv4 multicast case 			 */			if (dp->d_session->sess4_addr.s_addr == 				NET_GET_ADDR_IPv4(net_addr_ip(dst)).s_addr) {				/* 				 * Found session with same group/dest address. 				 */				/* 				 * Find matching senders. If sender in RSRR is zero,				 * the tree is a shared tree, so match all senders.				 */				for (sp = dp->d_PSB_list; sp != NULL; sp = sp->ps_next) {					if ((NET_GET_ADDR_IPv4(net_addr_ip(src)).s_addr == 0) ||						(sp->ps_templ->filt4_srcaddr.s_addr ==							NET_GET_ADDR_IPv4(net_addr_ip(src)).s_addr)) {						SetNotifyBit(sp, note);						rsrr_update(dp, sp, iif, bmp);					}				}			}			break;#ifdef	USE_IPV6		case NET_ADDR_IPv6:			/* 			 * IPv6 multicast case 			 */			if (IN6_ARE_ADDR_EQUAL(&dp->d_session->sess6_addr, 				&NET_GET_ADDR_IPv6(net_addr_ip(dst)))) {				/* 				 * Found session with same group/dest address. 				 */				/* 				 * Find matching senders. If sender in RSRR is zero,				 * the tree is a shared tree, so match all senders.				 */				for (sp = dp->d_PSB_list; sp != NULL; sp = sp->ps_next) {					if (IN6_ARE_ADDR_EQUAL(&NET_GET_ADDR_IPv6(net_addr_ip(src)),						&in6addr_any) || 						(IN6_ARE_ADDR_EQUAL(&sp->ps_templ->filt6_srcaddr,						&NET_GET_ADDR_IPv6(net_addr_ip(src))))) {						SetNotifyBit(sp, note);						rsrr_update(dp, sp, iif, bmp);					}				}			}			break;#endif	/* USE_IPV6 */		default:			break;		}	  }    }	return 0;}/* *	Update path state using route reply */voidrsrr_update(dp, sp, inif, bmp)    Session *dp;    PSB *sp;    int inif;    bitmap *bmp;{	net_addr *addr = net_addr_ip(session_addr(dp->d_session));    /* 	 * Remember that the multicast forwarding entry doesn't include     * the vif over which data originates if the sender is local to     * the router.   Set the bit now.     */    if (session_multicast(dp->d_session)) {	    if (IsHopAPI(&sp->ps_phop))  {			switch (addr->type) {			case NET_ADDR_IPv4:				if (!NoV4Mroute)					bmp_set(bmp, if_vec[sp->ps_originvif].if_index - 						if_vec[0].if_index +1 + api_num);				else					bmp_set(bmp, sp->ps_originvif);				break;#ifdef	USE_IPV6			case NET_ADDR_IPv6:				bmp_set(bmp, sp->ps_originvif);				break;#endif	/* USE_IPV6 */			default:				break;			}		}	}    /* 	 * Call common routine to update the state.     */    route_update(dp, sp, inif, *bmp);    finish_path(dp, sp);}/* * bmptoif() searches through the bitmap, finds the bit which is set, * confirm it is the only bit which is set, then return that number. * 		- Argument:	bitmap with one-bit set (bitmap*) *		- Returns:	interface number (int) */int bmptoif(bitmap *bmp){	int i;	char s[100];	bitmap y;	/* 	 * No bit is set 	 */	if (bmp_zero(bmp)) return -1;	/* 	 * Search from the right-most bit of the bitmap 	 */	for (i=0; i < BMP_SIZE*NBBY; i++) {		if (bmp_tst(bmp, i)) {			y = *bmp;			bmp_clr(&y, i);			/* 			 * make sure only 1 bit is set 			 */			if (bmp_zero(&y)) {				return i;			}			else {				log(LOG_DEBUG,0,"RSRR: bmp = %d",bm_expand(bmp,s));				return -1;			}		}	}	return -1;}/* * Convert IPv6 address to printable (loggable) representation. */#ifdef	USE_IPV6static char digits[] = "0123456789abcdef";static int ipv6round = 0;char *ip6_sprintf(addr)        register struct in6_addr *addr;{        static char ipv6buf[8][46];        register int i;        register char *cp;        register u_int16_t *a = (u_int16_t *)addr;        register u_int8_t *d;        int dcolon = 0;	ipv6round = (ipv6round + 1) & 7;	cp = ipv6buf[ipv6round];        for (i = 0; i < 8; i++) {                if (dcolon == 1) {                        if (*a == 0) {				if (i == 7)					*cp++ = ':';                                a++;                                continue;                        } else                                dcolon = 2;                }                if (*a == 0) {                        if (dcolon == 0 && i == 7) {                                *cp++ = '0';                                *cp++ = '0';                                break;                        }                        if (dcolon == 0 && *(a + 1) == 0) {				if (i == 0)	                                *cp++ = ':';                                *cp++ = ':';                                dcolon = 1;                        } else {                                *cp++ = '0';                                *cp++ = ':';                        }			a++;                        continue;                }                d = (u_int8_t *)a;                *cp++ = digits[*d >> 4];                *cp++ = digits[*d++ & 0xf];                *cp++ = digits[*d >> 4];                *cp++ = digits[*d & 0xf];                *cp++ = ':';                a++;        }        *--cp = 0;        return (ipv6buf[ipv6round]);}#endif	/* USE_IPV6 */

⌨️ 快捷键说明

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