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

📄 rsrr_rsrr.c

📁 radius协议源码÷The Radius Stack will connect to a Radius Server. This stack implementation is built upo
💻 C
📖 第 1 页 / 共 3 页
字号:
			log(LOG_ERR, 0,"VIF config error\n");			return(-1);		}		break;#ifdef	USE_IPV6	case RSRR_SOCK_V6UX:		if (rsrr_use_v2_ipv6) {			/* 			 * Use RSRR v2 format 			 */			struct rsrr_vif *vifs;			/*			 * skip over RSRR header			 */			vifs = (struct rsrr_vif *)(rsrr_recv_buf+RSRR_HEADER_LEN);			/*			 * loop through all the interfaces from the 			 * interface reply			 */			for (vf = 0; vf < rsrr_in->num; vf++) {				/*				 * loop through the if_vec[] table we kept				 */				for (i = 0; i < lnum; i++) {					/* 					 * Skip over API interface 					 */					if (IsNumAPI(i))						continue;					if (((vifs[vf].family == AF_INET) && 						(vifs[vf].addr_v4.s_addr ==						NET_GET_ADDR_IPv4(&NET_GET_IF_PHY_ADDR(&GET_IF(i))).s_addr)) ||						((vifs[vf].family == AF_INET6) && 						(IN6_ARE_ADDR_EQUAL(&vifs[vf].addr_v6,						&NET_GET_ADDR_IPv6(&NET_GET_IF_PHY_ADDR(&GET_IF(i))))))) {						/*						 * fill out the table for doing conversion between						 * the interfaces used in gated and the ones used						 * in rsvpd						 */						gated_to_rsvpd[vifs[vf].id] = i;						if (BIT_TST(vifs[vf].status,RSRR_M_DISABLED_BIT))							if_vec[i].if_flags &= ~IF_FLAG_IFF_UP;						else							if_vec[i].if_flags |= IF_FLAG_IFF_UP;						break;					}				}			}		}		else {			/* 			 * Gotta be an error 			 */			log(LOG_ERR,0,"Only RSRRv2 supports IPv6",0);			return(-1);		}		break;#endif	/* USE_IPV6 */	default:		return -1;	}	return 0;}/*  * Send a Route Query to routing for a dest-source pair.  */intrsrr_send_rq(pp, sp, af, src, dst, note)	void *pp;		/* PSB pointer */	void *sp;		/* Session pointer */	u_char af;	net_addr *src;	net_addr *dst;	int note;{    struct rsrr_header *rsrr;    int sendlen;    int rv;    /*      * Set up Route Query message      */    rsrr = (struct rsrr_header *) rsrr_send_buf;    rsrr->type = RSRR_ROUTE_QUERY;    rsrr->flags = 0;    rsrr->num = 0;    if (note)		BIT_SET(rsrr->flags,RSRR_NOTIFICATION_BIT);	switch(af) {	case AF_INET:		if (rsrr_use_v1_ipv4) {			/* 			 * USE RSRR v1 			 */			struct rsrrv1_rq *route_query;			rsrr->version = 1;			route_query = (struct rsrrv1_rq *)(rsrr_send_buf + RSRR_HEADER_LEN);			route_query->dest_addr = NET_GET_ADDR_IPv4(net_addr_ip(dst));			route_query->source_addr = NET_GET_ADDR_IPv4(net_addr_ip(src));			route_query->query_id = rsrr_qt_getid(pp);			/* 			 * Get the message size. 			 */			sendlen = RSRRV1_RQ_LEN;			if (IsDebug(DEBUG_RSRR)) {			log(LOG_DEBUG, 0, "> Route Query (%s %s) Notify= %d\n",				inet_fmt(route_query->source_addr.s_addr,s1),				inet_fmt(route_query->dest_addr.s_addr,s2),				BIT_TST(rsrr->flags,RSRR_NOTIFICATION_BIT));			}			/* 			 * Send it. 			 */			if (rsrr_send(RSRR_SOCK_V4UX,sendlen) >= 0) {				/* 				 * Cache the query if note is not zero, otherwise it is				 * only used to remove the route from route change 				 * notification list in the daemon.				 */				if (note)					rsrr_qt_cache(route_query->query_id,pp,sp,src,dst);				/*				 * asynchronous route query/reply				 * return the query ID				 */				return route_query->query_id;			}			else				return -1;		}		else if (rsrr_use_v2_ipv4) {			/* 			 * USE RSRR v2 			 */			struct rsrr_rq *route_query;			rsrr->version = 2;			route_query = (struct rsrr_rq *)(rsrr_send_buf + RSRR_HEADER_LEN);			route_query->family = (u_short) AF_INET;			route_query->length = (u_short) sizeof (struct in_addr);			route_query->dst_v4 = NET_GET_ADDR_IPv4(net_addr_ip(dst));			route_query->src_v4 = NET_GET_ADDR_IPv4(net_addr_ip(src));			route_query->query_id = rsrr_qt_getid(pp);			/* 			 * Get the message size. 			 */			sendlen = RSRR_RQ_LEN;			if (IsDebug(DEBUG_RSRR)) {			log(LOG_DEBUG, 0, "> Route Query (%s %s) Notify= %d\n",				inet_fmt(route_query->src_v4.s_addr,s1),				inet_fmt(route_query->dst_v4.s_addr,s2),				BIT_TST(rsrr->flags,RSRR_NOTIFICATION_BIT));			}			/* 			 * Send it. 			 */			if (rsrr_send(RSRR_SOCK_V4UX,sendlen) >= 0) {				/* 				 * Cache the query if note is not zero, otherwise it is				 * only used to remove the route from route change 				 * notification list in the daemon.				 */				if (note)					rsrr_qt_cache(route_query->query_id,pp,sp,src,dst);				/*				 * asynchronous route query/reply				 * return the query ID				 */				return route_query->query_id;			}			else				return -1;		}		break;#ifdef	USE_IPV6	case AF_INET6:		if (rsrr_use_v2_ipv6) {			/* 			 * USE RSRR v2 			 */			struct rsrr_rq *route_query;			rsrr->version = 2;			route_query = (struct rsrr_rq *)(rsrr_send_buf + RSRR_HEADER_LEN);			route_query->family = (u_short) AF_INET6;			route_query->length = (u_short) sizeof (struct in6_addr);			route_query->dst_v6 = NET_GET_ADDR_IPv6(net_addr_ip(dst));			route_query->src_v6 = NET_GET_ADDR_IPv6(net_addr_ip(src));			route_query->query_id = rsrr_qt_getid(pp);			/* 			 * Get the message size. 			 */			sendlen = RSRR_RQ_LEN;			if (IsDebug(DEBUG_RSRR)) {			log(LOG_DEBUG, 0, "> Route Query (%s %s) Notify= %d\n",				ip6_sprintf(&(route_query->src_v6)),				ip6_sprintf(&(route_query->dst_v6)),				BIT_TST(rsrr->flags,RSRR_NOTIFICATION_BIT));			}			/* 			 * Send it. 			 */			if (rsrr_send(RSRR_SOCK_V6UX,sendlen) >= 0) {				/* 				 * Cache the query if note is not zero, otherwise it is				 * only used to remove the route from route change 				 * notification list in the daemon.				 */				if (note)					rsrr_qt_cache(route_query->query_id,pp,sp,src,dst);				/*				 * asynchronous route query/reply				 * return the query ID				 */				return route_query->query_id;			}			else				return -1;		}		else if (rsrr_use_v1_ipv6) {			/*			 * IPv6 and RSRRv1?  Not possible			 */			log(LOG_ERR,0,"Only RSRRv2 supports IPv6");			rv = -1;		}		break;#endif	/* USE_IPV6 */	default:		log(LOG_ERR,errno,"No support for AF = %d",af);		rv = -1;		break;	}	return rv;}/*  * Accept a Route Reply from routing.  Find the related session and sender * structures and issue a PATH refresh if needed. */intrsrr_accept_rr_ux(sock_type, rsrr)	u_char sock_type;    struct rsrr_header *rsrr;{    net_addr src;    net_addr dst;    int rv;	int in_lih;	bitmap  out_bmp;	bitmap y;	int note = 0;	u_char tree_type = RSRR_SENDER_TREE;	memset(s,0,sizeof(s));	bmp_rst(&out_bmp);	bmp_rst(&y);	if (sock_type == RSRR_SOCK_V4UX) {		/* 		 * IPv4 		 */		if (rsrr_use_v1_ipv4) {			/* 			 * RSRR v1 			 */			struct rsrrv1_rr *route_reply;			route_reply=(struct rsrrv1_rr *)(rsrr_recv_buf+RSRR_HEADER_LEN);			/*			 * IPv4 mrouted uses virtual interfaces, so we need to 			 * shift the replying incoming interface and the outgoing			 * bitmap			 */			in_lih  = route_reply->in_vif + shift;			bmp_create(route_reply->out_vif_bm, &y);			bmp_shift(&y, &out_bmp, shift);			/* 			 * Reject errors. 			 */			if (BIT_TST(rsrr->flags,RSRR_ERROR_BIT)) {				/* 				 * Delete any associated cache entry so that we 				 * can re-use the query id.				 */				rsrr_qt_delete(route_reply->query_id);				if (IsDebug(DEBUG_RSRR))					log(LOG_DEBUG,0,						"Rejecting Route Reply because Error bit set.\n");				return -1;			}			if (IsDebug(DEBUG_RSRR)) {				log(LOG_DEBUG, 0,					"< Route Reply (%s %s) in vif %d out vifs %s Notify= %d\n",					inet_fmt(route_reply->source_addr.s_addr,s1),					inet_fmt(route_reply->dest_addr.s_addr,s2),					(u_char)(in_lih), bm_expand(&out_bmp, s),					BIT_TST(rsrr->flags,RSRR_NOTIFICATION_BIT));			}			if (BIT_TST(rsrr->flags,RSRR_NOTIFICATION_BIT))				note = 1;			if (RSRR_USE_SHARED(rsrr->flags))				tree_type = RSRR_HYBRID_UNIDIRECTIONAL_SHARED_TREE;			else if (RSRR_USE_ALL_SHARED(rsrr->flags))				tree_type = RSRR_UNIDIRECTIONAL_SHARED_TREE;			NET_SET_ADDR_IPv4(&src,route_reply->source_addr);			NET_SET_ADDR_IPv4(&dst,route_reply->dest_addr);			rv = rsrr_route_reply(route_reply->query_id,&src,&dst,					in_lih,(bitmap*)&(out_bmp), note, tree_type);			return rv;		}		else if (rsrr_use_v2_ipv4) {			/* 			 * RSRR v2 			 */			struct rsrr_rr *route_reply;			route_reply = (struct rsrr_rr *)(rsrr_recv_buf + RSRR_HEADER_LEN);			/*			 * IPv4 mrouted uses virtual interfaces, so we need to 			 * shift the replying incoming interface and the outgoing			 * bitmap			 */			in_lih  = route_reply->in_vif + shift;			bmp_convert(&(route_reply->out_vif_bm), &y);			bmp_shift(&y, &out_bmp, shift);			/* 			 * Reject errors. 			 */			if (BIT_TST(rsrr->flags,RSRR_ERROR_BIT)) {				/* 				 * Delete any associated cache entry so that we 				 * can re-use the query id.				 */				rsrr_qt_delete(route_reply->query_id);				if (IsDebug(DEBUG_RSRR))					log(LOG_DEBUG,0,						"Rejecting Route Reply because Error bit set.\n");				return -1;			}			if (IsDebug(DEBUG_RSRR)) {				log(LOG_DEBUG, 0,					"< Route Reply (%s %s) in vif %d out vifs %s Notify= %d\n",					inet_fmt(route_reply->src_v4.s_addr,s1),					inet_fmt(route_reply->dst_v4.s_addr,s2),					(u_char)(in_lih), bm_expand(&out_bmp,s),					BIT_TST(rsrr->flags,RSRR_NOTIFICATION_BIT));			}			if (BIT_TST(rsrr->flags,RSRR_NOTIFICATION_BIT))				note = 1;			NET_SET_ADDR_IPv4(&src,route_reply->src_v4);			NET_SET_ADDR_IPv4(&dst,route_reply->dst_v4);			tree_type = route_reply->tree_type;			rv = rsrr_route_reply(route_reply->query_id,&src,&dst,					in_lih, (bitmap *)&(out_bmp), note, tree_type);			return rv;		}	}#ifdef	USE_IPV6	else if (sock_type == RSRR_SOCK_V6UX) {		/* 		 * IPv6 		 */		if (rsrr_use_v2_ipv6) {			/*			 * RSRR v2			 */			struct rsrr_rr *route_reply;			rsrr_bmp tmpbmp;			route_reply = (struct rsrr_rr *)(rsrr_recv_buf + RSRR_HEADER_LEN);			/*			 * For IPv6 mrouting daemon, no virtual interface used, 			 * but we need to do conversion between the interface			 * used in gated and the one used in rsvpd.  The			 * gated_to_rsvpd[] table was set up during the			 * interface reply phase			 */			in_lih  = gated_to_rsvpd[route_reply->in_vif];			convert(&(route_reply->out_vif_bm), &tmpbmp);			bmp_convert(&tmpbmp, &out_bmp);			/* 			 * Reject errors. 			 */			if (BIT_TST(rsrr->flags,RSRR_ERROR_BIT)) {				/* 				 * Delete any associated cache entry so that we 				 * can re-use the query id.				 */				rsrr_qt_delete(route_reply->query_id);				if (IsDebug(DEBUG_RSRR))					log(LOG_DEBUG,0,						"Rejecting Route Reply because Error bit set.\n");				return -1;			}			if (IsDebug(DEBUG_RSRR)) {				log(LOG_DEBUG, 0,					"< Route Reply (%s %s) in vif %d out vifs %s Notify= %d\n",					ip6_sprintf(&(route_reply->src_v6)),					ip6_sprintf(&(route_reply->dst_v6)),					(u_char)(in_lih), bm_expand(&out_bmp,s),					BIT_TST(rsrr->flags,RSRR_NOTIFICATION_BIT));			}			if (BIT_TST(rsrr->flags,RSRR_NOTIFICATION_BIT))				note = 1;			NET_SET_ADDR_IPv6(&src,route_reply->src_v6);			NET_SET_ADDR_IPv6(&dst,route_reply->dst_v6);			tree_type = route_reply->tree_type;			rv = rsrr_route_reply(route_reply->query_id,&src,&dst,					in_lih, (bitmap *)&(out_bmp), note, tree_type);			return rv;		}		else if (rsrr_use_v1_ipv6) {			/*			 * RSRRv1 and IPv6.  Not possible			 */			log(LOG_ERR,0,"Only RSRRv2 supports IPv6");			return -1;		}	}#endif	/* USE_IPV6 */	return 0;}/*  * Initialize the query table.  */voidrsrr_qt_init(){    int i;    for (i=0; i<RSRR_QT_SIZE; i++)		rsrr_qt[i] = (struct rsrr_query_table *) NULL;}u_longrsrr_qt_getid(pt)	void *pt;{	return ((u_long)((u_long)pt & 0xffffffff));}/*  * Cache a query id in the query table with its associated  * source/destination combination. */voidrsrr_qt_cache(query_id,pp,sp,src,dst)    u_long query_id;    void *pp;	/* PSB pointer */    void *sp;	/* Session pointer */    net_addr *src;    net_addr *dst;{    struct rsrr_query_table *qt;    int hash = RSRR_QT_HASH(query_id);    qt = rsrr_qt[hash];    while (qt) {		if (qt->query_id == query_id) {			/* 			 * We somehow managed to duplicate a query id.  			 * Amazing! Ditch the old one.			 */			qt->query_id = query_id;			qt->ptrP = pp;			qt->ptrS = sp;			qt->src = *src;			qt->dst = *dst;			return;		}		qt = qt->next;    }    /*      * Cache entry doesn't already exist.  Create one and insert at     * front of list.     */    qt = (struct rsrr_query_table *) malloc(sizeof(struct rsrr_query_table));    if (qt == NULL) {		Log_Mem_Full("RSRR cache");		return;    }    qt->query_id = query_id;    qt->ptrP = pp;    qt->ptrS = sp;    qt->src = *src;    qt->dst = *dst;    qt->next = rsrr_qt[hash];    rsrr_qt[hash] = qt;}/*  * Lookup a query id in the table.  */struct rsrr_query_table *rsrr_qt_lookup(query_id)    u_long query_id;{    struct rsrr_query_table *qt;    int hash = RSRR_QT_HASH(query_id);    qt = rsrr_qt[hash];    while(qt) {		if (qt->query_id == query_id)			return qt;		qt = qt->next;    }    return qt;}/*  * Delete a query id from the table.  */voidrsrr_qt_delete(query_id)    u_long query_id;{    struct rsrr_query_table *qt, *qt_prev;    int hash = RSRR_QT_HASH(query_id);    qt = rsrr_qt[hash];    while(qt) {	if (qt->query_id == query_id) {	    if (qt == rsrr_qt[hash])			/* 			 * Deleting first entry. 			 */			rsrr_qt[hash] = qt->next;	    else			qt_prev->next = qt->next;	    free(qt);	    return;	}	qt_prev = qt;	qt = qt->next;    }}voidSetNotifyBit(psbp, note)	PSB *psbp; 	int note;{	if (note)	    /* 	     * Routing can do route change notification.  Set bit in	     * sender structure that indicates RSRR no longer needs to	     * send queries.	     */	    BIT_SET(psbp->ps_rsrr_flags,  PSBF_RSRR_NOTIFY);	else	    /* 	     * Clear the bit just in case it was set. 	     */	    BIT_CLR(psbp->ps_rsrr_flags,  PSBF_RSRR_NOTIFY);}#endif /* ! HOST_ONLY *//* * The interface list in gated is different from the one being used in * rsvpd, thus we need to do some conversion for the bitmap returned  * from gated to the one in rsvpd.  For example, the interface table * in gated includes loop-back interfaces, and it has different ordering * for the interfaces of the same physical interface.  We have built a  * conversion table gated_to_rsvpd[] during interface reply, now we  * use it to do the conversion. */rsrr_bmp *convert(rsrr_bmp *x, rsrr_bmp *y) {	int i,j,d,m;	for (i=0; i<(RSRR_MAX_VIFS_V2/NBBY); i++)		y->bm[i]=0;	for (i=0; i<RSRR_MAX_VIFS_V2; i++) {		d = i/NBBY;		m = i%NBBY;		if ((x->bm[d]) & (1<<m)) {			j = gated_to_rsvpd[i];			d = j/NBBY;			m = j%NBBY;			y->bm[d] |= (1 << m);		}	}	return y;}

⌨️ 快捷键说明

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