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

📄 rsvp_diag.c

📁 radius协议源码÷The Radius Stack will connect to a Radius Server. This stack implementation is built upo
💻 C
📖 第 1 页 / 共 2 页
字号:
			/* Last hop... */			Init_Object(droute, ROUTE, ROUTE_ipv4);			Obj_Length(droute) -= sizeof(d_resp->resp_in_addr); 			droute->R_pointer_ipv4 = -1;			pkt->pkt_len += Obj_Length(droute);		}		else {			/* Not last hop; copy save route obj to resp tail.			 */			assert(dr_old != NULL);			droute = (ROUTE *)((char *)pkt->pkt_data + pkt->pkt_len);			Move_Object(dr_old, droute);			free(dr_old);		}		/* 	update the route object		 */		droute->R_pointer_ipv4++;			route(droute,droute->R_pointer_ipv4) = d_resp->resp_in_addr;		Obj_Length(droute) += sizeof(d_resp->resp_in_addr);		/* 	Add the (new) route object (back) into the map		 */		pkt->pkt_len += sizeof(d_resp->resp_in_addr);		pkt->pkt_map->rsvp_route = droute ;		/*      Set the ROUTEBIG error if the pkt_len has exceed ed		 *	packet_MTU, but only after updating the route object.		 */		if ( !(flags & DREQ_TRIMFWD) && pkt->pkt_len > pkt->packet_MTU)		  d_resp->resp_Rerror |= (RSVP_Erv_Diag_ROUTEBIG << 4);	}	/* 	if no error bit is set, no flags are set, 	 * 	forward the DREQ packet , else goto send_diag_reply	 */	if((DIAG_RESPONSE_RERROR(d_resp) == RSVP_Err_NONE) && 	   !(flags & (DREQ_TRIMFWD | DREQ_MAXHOP)) &&	   (map_if_addr(&saddr) < 0)) {		mode = send_pkt_out_if(IF_UNICAST(fw_if),fwhop, pkt);		if (mode< 0)			return -1;		return 0;	}	return(send_diag_reply(pkt,in_vif,flags,fwhop,fw_if,d_resp));}/* * accept_diag_reply() : Forwarding incoming diagnostic response messages *			 (DREP Forwarding)	 */intaccept_diag_reply(int in_vif, struct packet *pkt){	DIAGNOSTIC		*diagnostic;	u_char			H ;	int			mode;	RSVP_HOP		hopp;	net_addr		laddr;	net_addr		toaddr;	Init_Object(&hopp, RSVP_HOP, RSVP_HOP_ipv4);		diagnostic = pkt->rsvp_diagnostic;	H = DIAG_HBIT(diagnostic);	NET_SET_ADDR_IPv4(&laddr,diagnostic->diag_laddr);	NET_SET_ADDR3_UDP_IPv4(&toaddr,diagnostic->diag_raddr,diagnostic->diag_rport);	/* 	Are we the LAST_HOP ? */	if (map_if_addr(&laddr) >=0) {		if (IN_MULTICAST(ntoh32(diagnostic->diag_raddr.s_addr))) 			pkt->pkt_ttl = diagnostic->diag_ttl ;		mode = send_pkt_to(-1, &toaddr, pkt);	}	else if(H == 1) {			/*	We are in the middle of a HBH DREP		 */		pkt->rsvp_droute->R_pointer_ipv4 --;		hopp.hop4_addr = route(pkt->rsvp_droute, pkt->rsvp_droute->R_pointer_ipv4);		mode = send_pkt_out_if(-1, &hopp, pkt);	}	else			 	/*	These two cases are exceptions, not included for 	 	 *	in the specification   					 	 */	    if (IN_MULTICAST(ntoh32(diagnostic->diag_raddr.s_addr))) {		    hopp.hop4_addr = diagnostic->diag_laddr ;		    mode = send_pkt_out_if(-1, &hopp, pkt);	}	else {		    mode = send_pkt_to(-1, &toaddr, pkt);			  	}	if (mode <0)		return -1;	return 0;}/*  * send_diag_reply : Used primarily to send diagnostic replies.  *		     In the fragmentation case, we will trim a DREP, *		     build and send a DREP, and forward a *new* DREQ *		     to the enclosed prev hop. */int send_diag_reply(	struct packet *pkt, 	int in_vif,	u_char flags,	RSVP_HOP *fwhop, int fw_if,	DIAG_RESPONSE *ldresp){	DIAG_RESPONSE		*drespo, *dresp;	RSVP_HOP		hopp;	int			offset, old_off ,i ,mode;	int			outif;        u_char          	H ;	struct packet 		lpkt, *fwd_pkt = &lpkt;	packet_map 		mapp, *fwd_map = &mapp;	Session			*destp;	net_addr		laddr;	net_addr		toaddr;	bitmap	bmp;	int rv;		bmp_rst(&bmp);	H  =  DIAG_HBIT(pkt->rsvp_diagnostic);	dresp = ldresp;	destp = locate_session(pkt->rsvp_sess);	NET_SET_ADDR_IPv4(&laddr,pkt->rsvp_diagnostic->diag_laddr);	NET_SET_ADDR3_UDP_IPv4(&toaddr,pkt->rsvp_diagnostic->diag_raddr,			       pkt->rsvp_diagnostic->diag_rport);	Init_Object(&hopp, RSVP_HOP, RSVP_HOP_ipv4);		/*      If there is no error and we need to trim and forward	 */        if ((flags & DREQ_TRIMFWD) && DIAG_RESPONSE_RERROR(dresp) == RSVP_Err_NONE) {/* 	XXX??? 	Currently the packet duplication code is a trick. *		We use the current packet data buffer, and send out two packets,  *	       	with the appropriate map changes each time. For the DREQ forwarded  * 		upstream, the packet and map data structues are created anew.  * 		May need to revisit this section later. */		*fwd_pkt = *pkt ;		*fwd_map = *pkt->pkt_map ;		fwd_pkt->pkt_map = fwd_map ;		assert(fwd_pkt->pkt_data->rsvp_type == RSVP_DREQ);		assert(fwd_pkt->pkt_map->rsvp_msgtype == RSVP_DREQ);/* 	Compute the fragment offset, in terms of number of response *	object bytes already, and update current offset. */		drespo = pkt->pkt_map->rsvp_diag_response;		old_off = offset = pkt->rsvp_diagnostic->diag_frag_off ;		for (i=0; i<pkt->pkt_map->rsvp_resplist; i++) {			offset += Obj_Length(drespo);			(char *)drespo += Obj_Length(drespo);		}		fwd_pkt->pkt_map->rsvp_diag_response = NULL;		fwd_pkt->pkt_map->rsvp_resplist = 0;		  		fwd_pkt->pkt_map->rsvp_diag->diag_frag_off = offset;			/* 	Continue and forward the trimmed DREQ packet upstream */		mode = send_pkt_out_if(IF_UNICAST(fw_if),fwhop, fwd_pkt);		if (mode < 0)		  return -1 ;/*	Set the More Fragment bit on the original packet, indicating fragmentation  *	since this will be the first DREP, and restore the frag_off. */		pkt->pkt_map->rsvp_diag->diag_replymode |= 0x01;		pkt->pkt_map->rsvp_diag->diag_frag_off = old_off;	}/*  	Send the DREP after turning the packet to a DREP from a DREQ. */	pkt->pkt_data->rsvp_type = RSVP_DREP;	pkt->pkt_map->rsvp_msgtype = RSVP_DREP;/* 	Current DREP : If any error bit is set, send the packet back to either last_hop * 	or response address. */	if (DIAG_RESPONSE_RERROR(dresp) != RSVP_Err_NONE) {		if ( map_if_addr(&laddr) < 0 ) {		  if (H == 1 || IN_MULTICAST(ntoh32(pkt->rsvp_diagnostic->diag_raddr.s_addr))) {			  hopp.hop4_addr = pkt->rsvp_diagnostic->diag_laddr; 			  /* outif = unicast_route(hop_addr(&hopp)); */			  rv = rsrr_route_query((void *)0, (void *)0, (net_addr *)0,					hop_addr(&hopp), 0, (int *)0, &bmp);			  if (rv == -1) {				log(LOG_ERR,errno,"Unicast route lookup failure");				return -1;			  }			  outif = bmptoif(&bmp);			  mode = send_pkt_out_if(outif, &hopp, pkt);		  }		        }			else /* last hop */				mode = send_pkt_to(-1, &toaddr, pkt);		if (mode < 0)			return (-1);		return 0;	}	else {		/*	No errors, valid DREP to send, either because		 *	of DREQ_MAXHOP, or the DREQ_TRIMFWD case, or		 *	XXXX we reached the sender RSVP router XXXX		 */		if (H == 0 || ( map_if_addr(&laddr) >= 0)) {			mode = send_pkt_to(-1, &toaddr, pkt);		}		else 	{			assert(pkt->rsvp_droute != NULL);			pkt->rsvp_droute->R_pointer_ipv4--;			hopp.hop4_addr = route(pkt->rsvp_droute, 				pkt->rsvp_droute->R_pointer_ipv4);			/* outif = unicast_route(hop_addr(&hopp)); */			rv = rsrr_route_query((void *)0, (void *)0, (net_addr *)0,					hop_addr(&hopp), 0, (int *)0, &bmp);			if (rv == -1) {				log(LOG_ERR,errno,"Unicast route lookup failure");				return -1;			}			outif = bmptoif(&bmp);			mode = send_pkt_out_if(outif ,&hopp, pkt);		}		if (mode <0)			return -1;		return 0;	}}/* locate_RSB_diag(): * *      This routine is similar to locate_RSB, but tailor made for Diagnostic  * 	message support. It returns an RSB if a reservation exists, for the *	given session, next hop, and sender (specified by filter) * *	in_vif : this is the vif the diagnostic request came in on. */RSB *  locate_RSB_diag(Session *destp, RSVP_HOP *nhopp, FILTER_SPEC *sfiltp,								int in_vif) {	RSB *rp = NULL ;	RSB *cd_rp = NULL;  /* 	cd_rp is used to save off a candidate RSB for the case detailed below */	for (rp = destp->d_RSB_list; rp != NULL; rp = rp->rs_next) {		if (!hop_addr_eq(nhopp,&rp->rs_nhop)) {/* 	Kluge? for the case, where the diag request landed on a  * 	broadcast multi-acess network (part of the reverse path). *      There may be valid reservations on this router's BMA network interface,  * 	but NHOPs may be different routers, not necessarily the router from  * 	where the diag request got forwarded. But we still want to record the  * 	LLB state for this OIF, so we just find some RSB for the same OIF *      and call LL_GetInfo as usual. (OIF for the reservation is the incoming VIF  * 	from the diagnostic request.  *  * 	Due to wierdness in unicast routing or the presence of tunnels, the diag request  * 	may land up on the wrong interface. The definition of the diagnositc message header  * 	has been changed to include for the HOP object with the LIH field, to handle this  * 	problem. (version 3 of the specification). When this code is brought upto date, the * 	LIH value extracted from the HOP object (in a forwarded DIAG_REQ packet) will be used  * 	instead of the in_vif value for correct behaviour.  */			if(in_vif != rp->rs_OIf)			  continue;			else 			  if(!cd_rp) /* 	the rules to choose a candidate RSB are those that apply for  * 	selecting a routine RSB  */			    if(Style_is_Shared(rp->rs_style) || 			       match_filt2star(sfiltp, rp->rs_filtstar)) {				    cd_rp = rp;				    continue;			    }		}		if(Style_is_Shared(rp->rs_style) || 		   match_filt2star(sfiltp, rp->rs_filtstar))		  break;	}	if (rp) 	  return(rp);	else 	  return(cd_rp);}

⌨️ 快捷键说明

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