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

📄 rsvp_mstat.c

📁 radius协议源码÷The Radius Stack will connect to a Radius Server. This stack implementation is built upo
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *   This procedure extracts reservation state information from rsvpd *   data structures, marshals it, and sends it in one or more UDP packets. */voidstatus_RSVP_Resv(struct sockaddr_in *sinp){	RSVPInfo_t	*Infop = (RSVPInfo_t *) buff;	ResvInfo_t	*Resvp = (ResvInfo_t *) buff;	ResvInfo_t	*New_Resvp;	Session		*dst;	int		i;	nSession = 0;	Infop->type = hton32(TYPE_RSVP_VRESV);	strtcpy(Infop->name, RSVPNodeName, NAME_LEN);	Resvp = &Infop->Session_un.resvInfo;  /* first session */	/*	 * For each session, marshal data for each style, if any.	 */	for (i= 0; i < SESS_HASH_SIZE; i++)	    for (dst = session_hash[i]; dst; dst = dst->d_next) {		nStyle_Sess = 0;		New_Resvp = fmt_WF_Resv(dst, Resvp);		New_Resvp = fmt_FF_Resv(dst, New_Resvp);		New_Resvp = fmt_SE_Resv(dst, New_Resvp);		if ((char *) New_Resvp > &buff[max_msg_size]) {			int newlen = (char *)New_Resvp - (char *)Resvp;			status_send((char *)Resvp, sinp);			New_Resvp = &Infop->Session_un.resvInfo;			memcpy(New_Resvp, Resvp, newlen);			New_Resvp = (ResvInfo_t *)				((char *)New_Resvp + newlen);			nSession = 0;		}		nSession += nStyle_Sess;		Resvp = New_Resvp;	}	/*	 * Scan my private Session_List, looking for sessions that had	 *   resv state last time but have none this time, and send an	 *   "empty" entry for any that are found (but truncate if fill	 *   buffer).	 */	Gone_Sessp = NULL;	do {		Gone_Session(SL_FSM_RESV);		if (Gone_Sessp) {			Resvp->resv_session = Gone_Sessp->sl_dest;			Resvp->resv_style = 0;  /* => all styles! */			Resvp->resv_R = 0;			Resvp->nStruct = 0;			New_Resvp = (ResvInfo_t *) 							mstat_objcpy(Object_of(&Resvp->resv_policy),					    &NULL_OBJECT);			if ((char *) New_Resvp > &buff[max_msg_size]) {				status_send((char *)Resvp, sinp);				return;  /* truncate... */			}			nSession++;			Resvp = New_Resvp;		}	} while (Gone_Sessp);	/*	 * Write last data, if any	 */	if ((nSession) || Send_Empty)		status_send((char *)Resvp, sinp); }static ResvInfo_t *fmt_WF_Resv(Session *dst, ResvInfo_t *Resvp)	{	ResvWF_t	*Rp;	char		*if_name, *tp;	int		nResv = 0;	RSB		*rf;	/* Compute offset into buffer, considering variable-length part	 * (policy data) in 2nd level header.  Actually fill it in later	 * if we marshal one or more 3rd level headers.	 */	Rp = (ResvWF_t *) mstat_objcpy(Object_of(&Resvp->resv_policy),					    &NULL_OBJECT);	/*	 *   Scan sender list for wildcard sender, and for that sender,	 *   the vector of outgoing interfaces, and marshal any	 *   reservation state that is found; nResv is count.	 */	for (rf = dst->d_RSB_list; rf; rf = rf->rs_next) {		if (rf->rs_style != STYLE_WF)			continue;		if (rf->rs_OIf == api_num)			if_name = LOCAL_HOST;		else			if_name = if_vec[rf->rs_OIf].if_name;		strtcpy(Rp->WF_if, if_name, IFNAMSIZ);		Rp->WF_ttd = rf->rs_ttd;		Rp->WF_nexthop = rf->_rs_nhop;		HTON32(Rp->WF_ttd);		tp = mstat_objcpy(Object_of(&Rp->WF_flowspec), 					Object_of(rf->rs_spec));		Rp = (ResvWF_t *) mstat_objcpy(Object_of(tp),					&NULL_OBJECT);		/*** XXX CHECK OVERFLOW?? ***/		nResv++;	}	/*   If we found any WF reservation state, set up 2nd level header	 *   and advance output pointer.  If buffer full, send it.	 */	if (nResv) {		nStyle_Sess++;		New_Resv_Session(dst, Resvp, RAPI_RSTYLE_WILDCARD);		Resvp->nStruct = nResv;		HTON32(Resvp->nStruct);		Resvp = (ResvInfo_t *) Rp;	}	return(Resvp);}static ResvInfo_t *fmt_FF_Resv(Session *dst, ResvInfo_t *Resvp)	{	ResvFF_t	*Rp;	int		nResv = 0;	char		*if_name, *tp;	RSB		*rf;	Rp = (ResvFF_t *) mstat_objcpy(Object_of(&Resvp->resv_policy),					    &NULL_OBJECT);	for (rf = dst->d_RSB_list; rf; rf = rf->rs_next) {		if (rf->rs_style != STYLE_FF)			continue;		if (rf->rs_OIf == api_num)			if_name = LOCAL_HOST;		else			if_name = if_vec[rf->rs_OIf].if_name;		strtcpy(Rp->FF_if, if_name, IFNAMSIZ);		Rp->FF_ttd = rf->rs_ttd;		Rp->FF_nexthop = rf->_rs_nhop;		HTON32(Rp->FF_ttd);		tp = mstat_objcpy(Object_of(&Rp->FF_flowspec),				Object_of(rf->rs_spec));		Rp = (ResvFF_t *) mstat_objcpy(Object_of(tp),				Object_of(rf->rs_filter0));		nResv++;			/* XXX CHECK FOR OVERFLOW */	}	/*   If we found any FF reservation state, set up 2nd level header	 *   and advance output pointer.  If buffer full, send it.	 */	if (nResv) {		nStyle_Sess++;		New_Resv_Session(dst, Resvp, RAPI_RSTYLE_FIXED);		Resvp->nStruct = nResv;		HTON32(Resvp->nStruct);		Resvp = (ResvInfo_t *) Rp;	}	return(Resvp);}static ResvInfo_t *fmt_SE_Resv(Session *dst, ResvInfo_t *Resvp)	{	ResvSE_t	*Rp;	int		nResv = 0, i;	char		*if_name, *tp;	RSB		*rf;	Rp = (ResvSE_t *) mstat_objcpy(Object_of(&Resvp->resv_policy),					    &NULL_OBJECT);	for (rf = dst->d_RSB_list; rf; rf = rf->rs_next) {		if (rf->rs_style != STYLE_SE)			continue;		if (rf->rs_OIf == api_num)			if_name = LOCAL_HOST;		else			if_name = if_vec[rf->rs_OIf].if_name;		strtcpy(Rp->SE_if, if_name, IFNAMSIZ);		Rp->SE_ttd = rf->rs_ttd;		Rp->SE_nexthop = rf->_rs_nhop;		HTON32(Rp->SE_ttd);		tp = mstat_objcpy(Object_of(&Rp->SE_flowspec),						Object_of(rf->rs_spec));		Rp->nSE_filts = rf->rs_fcount;		HTON32(Rp->nSE_filts);		for (i = 0; i < rf->rs_fcount; i++) {			tp = mstat_objcpy(Object_of(tp),						Object_of(rf->rs_Filtp(i)));		}		Rp = (ResvSE_t *)tp;		nResv++;			/* CHECK FOR OVERFLOW */	}	/*   If we found any SE reservation state, set up 2nd level header	 *   and advance output pointer.  If buffer full, send it.	 */	if (nResv) {		nStyle_Sess++;		New_Resv_Session(dst, Resvp, RAPI_RSTYLE_SE);		Resvp->nStruct = nResv;		HTON32(Resvp->nStruct);		Resvp = (ResvInfo_t *) Rp;	}	return(Resvp);}static voidNew_Resv_Session(Session *dst, ResvInfo_t *Resvp, int styleid)	{	Resvp->resv_session.sess_destaddr.s_addr = dst->d_addr.s_addr;	Resvp->resv_session.sess_destport = dst->d_port;	Mark_Session(&Resvp->resv_session, SL_FSM_RESV);	Resvp->resv_style = styleid;	HTON32(Resvp->resv_style);	Resvp->resv_R = dst->d_Rtimor;	HTON32(Resvp->resv_R);	mstat_objcpy(Object_of(&Resvp->resv_policy), &NULL_OBJECT);}static voidstatus_send(char *bp, struct sockaddr_in *sinp)	{	RSVPInfo_t *Infop = (RSVPInfo_t *) buff;	int	   len = bp - buff;		Infop->nSession = nSession;	HTON32(Infop->nSession);	if (sendto(statsock, buff, len, 0, (struct sockaddr *) sinp,					 sizeof(struct sockaddr_in)) < 0)			log(LOG_WARNING, errno, "sendto\n");	nSession = 0;}/* *  Copy variable-length RSVP object -- flowspec, filterspec, ... or NULL       */static char *mstat_objcpy(Object_header *dstp, Object_header *srcp){	char *tp;	if (srcp)		memcpy(dstp, srcp, Obj_Length(srcp));	else		memcpy(dstp, &NULL_OBJECT, 4);	tp = (char *)Next_Object(dstp);#if BYTE_ORDER == LITTLE_ENDIAN	hton_object(dstp);#endif	return(tp);}	/* *  Look up destination (session) [in network byte order] in local session   *  table, and mark it active. */static voidMark_Session(SESSION_ipv4 *sesp, int FSMid)	{	struct session_list *slp, *avail_slp = NULL;	for (slp = Session_List; slp < Next_Sessp; slp++) {		if (slp->sl_fsms[FSMid] == SL_IDLE) {			if (slp->sl_fsms[SL_FSM_PATH] == SL_IDLE &&			    slp->sl_fsms[SL_FSM_RESV] == SL_IDLE) {				/* Entry not in use... clean it up */				slp->sl_dest.sess_destaddr.s_addr = 0;				slp->sl_dest.sess_destport = 0;				avail_slp = slp;			}			continue;		}		if (slp->sl_dest.sess_destaddr.s_addr == 						sesp->sess_destaddr.s_addr &&		    slp->sl_dest.sess_destport == sesp->sess_destport) {			slp->sl_fsms[FSMid] = SL_ACTV;			if (IsDebugSess)				fprintf(stderr, "%d ACTV %8.8X\n", FSMid, 						(u_int) slp);			return;		}	}	/*	 *   Session is new... add it to table.	 */	if (avail_slp == NULL) {		/* Did not find an unused slot.  Extend table (if poss.) */		if (Next_Sessp >= &Session_List[MAX_SL])			return;  /* Table is full, ignore this session */		avail_slp = Next_Sessp++;	}	if (IsDebugSess)		fprintf(stderr, "%d NEW %8.8X <- ACTV\n", FSMid, 						(u_int) avail_slp);	avail_slp->sl_dest = *sesp;	avail_slp->sl_fsms[FSMid] = SL_ACTV;		}/* *  Calling this procedure sets Gone_Sessp to point to an entry *  in the session_list that has been deleted, or to NULL if there *  are no more such entries. */static voidGone_Session(int FSMid)	{	if (Gone_Sessp == NULL)		Gone_Sessp = &Session_List[0];	else		Gone_Sessp++;	while (Gone_Sessp < Next_Sessp) {		switch (Gone_Sessp->sl_fsms[FSMid]) {		case SL_OLD:			/*			 *  Was there previously, but isn't now.  Change to			 *  IDLE state and return to process send GONE status.			 */			Gone_Sessp->sl_fsms[FSMid] = SL_IDLE;			if (IsDebugSess)				fprintf(stderr,				"%d GONE %8.8X <- IDLE\n",					 FSMid, (u_int) Gone_Sessp);			return;		case SL_ACTV:			if (IsDebugSess)				fprintf(stderr, "%d UNMARK %8.8X <- OLD\n", 					FSMid, (u_int) Gone_Sessp);			Gone_Sessp->sl_fsms[FSMid] = SL_OLD;			break;		default:			break;		}		Gone_Sessp++;	}	Gone_Sessp = NULL;}/* * Remove any final suffix .<chars> (if any) from the end of a given string * by storing a NULL on top of the dot.  Return a pointer to the beginning of * <chars>, or NULL if there is no suffix.  **ShOULD ALLOW ':'** */char           *rmsuffix(cp)	char	*cp;{	char	*tp;	tp = cp + strlen(cp) - 1;	while (*tp != '.' && tp >= cp)		tp--;	if (*tp != '.')		return (NULL);	*tp = '\0';	return ((char *) tp + 1);}

⌨️ 快捷键说明

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