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

📄 rsvp_mstat.c

📁 radius协议源码÷The Radius Stack will connect to a Radius Server. This stack implementation is built upo
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * @(#) $Id: rsvp_mstat.c,v 1.1.1.1 2000/05/08 22:51:24 wenqing Exp $ *//****************************************************************************            RSVPD -- ReSerVation Protocol Daemon                USC Information Sciences Institute                Marina del Rey, California		Original Version: Shai Herzog, Derek Yeung, Nov. 1993.		Current Version:  Steven Berson & Bob Braden, May 1996  Copyright (c) 1996 by the University of Southern California  All rights reserved.  Permission to use, copy, modify, and distribute this software and its  documentation in source and binary forms for any purpose and without  fee is hereby granted, provided that both the above copyright notice  and this permission notice appear in all copies, and that any  documentation, advertising materials, and other materials related to  such distribution and use acknowledge that the software was developed  in part by the University of Southern California, Information  Sciences Institute.  The name of the University may not be used to  endorse or promote products derived from this software without  specific prior written permission.  THE UNIVERSITY OF SOUTHERN CALIFORNIA makes no representations about  the suitability of this software for any purpose.  THIS SOFTWARE IS  PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,  INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  Other copyrights might apply to parts of this software and are so  noted when applicable.********************************************************************//* *    Routines to multicast state information to status display programs. *    (Actually, could configure to send to a unicast address). * *	Version 2 -- Handles variable-length objects, and tests for *		sessions disappearing to give GONE indications. */#include "rsvp_daemon.h"#include "rsvp_api.h"#include "rsvp_mstat.h"#include "rapi_lib.h"#define d_addr		d_session->sess4_addr#define d_port		d_session->sess4_port#define _ps_phop	ps_rsvp_phop.hop4_addr#define _rs_nhop	rs_rsvp_nhop.hop_u.hop_ipv4.hop_ipaddr/* Global rsvpd control variables */extern if_rec	*if_vec;extern Session *session_hash[];extern int	probe_socket;extern int	mstat_ttl;static int	statsock = -1;static struct	sockaddr_in mcast_sin;static char	RSVPNodeName[NAME_LEN];	/* name of the current router */static char 	buff[2*STAT_MSG_SIZE];static int	max_msg_size = STAT_MSG_SIZE;static int	nSession, nStyle_Sess;static int	IsDebugSess = 0;static int	Send_Empty = 0;Object_header   NULL_OBJECT = {4, 0, 0}; /* min length NULL object *//* external declarations */char	*strtcpy(char *, char *, int);/* forward declarations */static void	status_RSVP_Path(struct sockaddr_in *);static void	status_RSVP_Resv(struct sockaddr_in *);static char	*mstat_objcpy(Object_header *, Object_header *);static void	status_send(char *, struct sockaddr_in *);static PathInfo_t *status_Path_Session(Session *, PathInfo_t *);static ResvInfo_t *fmt_WF_Resv(Session *, ResvInfo_t *);static ResvInfo_t *fmt_FF_Resv(Session *, ResvInfo_t *);static ResvInfo_t *fmt_SE_Resv(Session *, ResvInfo_t *);static void	New_Resv_Session(Session *, ResvInfo_t *, int);static void	Mark_Session(SESSION_ipv4 *, int);static void	Gone_Session(int);/* *  List of sessions.  Use this list to detect deletion of session state, *    so can explicitly notify display programs of session deletion. *    For each session entry, make simple little FSM, separately for *    Path and Resv state. */#define MAX_SL	4struct session_list {	SESSION_ipv4	sl_dest;	u_char		sl_fsms[2];	/* FSM states */#define SL_FSM_PATH	0		/* Path state FSM */#define SL_FSM_RESV	1		/* Resv state FSM */#define SL_IDLE		0		/* Session_list entry unused */#define SL_OLD		1		/* Session existed */#define SL_ACTV		2		/* Session exists now */	} Session_List[MAX_SL],	 *Gone_Sessp, *Next_Sessp;/* *	Initialize for sending status messages: *		* Socket address mcast_sin *		* UDP socket statsock *		* RSVPNodeName *		* Session list pointer Next_Sessp; */int Status_Init(char *destaddr)	{	char            buf[256];	struct in_addr	host;	char		*tp;	char		*rmsuffix(char *);	u_char          ttlval = mstat_ttl;	int             port = 0, one = 1;	(void) strcpy(buf, destaddr);	if ((tp = rmsuffix(buf)))		port = hton16(atoi(tp));	if ((host.s_addr = inet_addr(buf)) == -1) {		fprintf(stderr, "Status addr not dotted dec.: %s\n", buf);		return (-1);	}	NET_SOCKADDR_UDP_IPv4( &mcast_sin, host, port);	if ((statsock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {		log(LOG_ERR, errno, "Socket Error\n");		return(-1);	}	/* Allow socket to be reused */	if (setsockopt(statsock, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one))) {		log(LOG_ERR, errno, "Status SO_REUSE err\n");		close(statsock);		return(-1);	}	/* Set multicast TTL	 */	if (IN_MULTICAST(ntoh32(host.s_addr))) {		if (0 > setsockopt(statsock, IPPROTO_IP, IP_MULTICAST_TTL,				   (char *) &ttlval, sizeof(ttlval))) {			close(statsock);			log(LOG_ERR, errno, "Status mcast TTL err\n");			return(-1);		}	}	/* Get my node DNS name, and remove all trailing components	 */	gethostname(RSVPNodeName, NAME_LEN);	while (rmsuffix(RSVPNodeName)) {	};	/* Initialize session list pointer	 */	Next_Sessp = &Session_List[0];	return (0);}/* init_probe_socket(): Called from main() during RSVP initialization. *	Initializes socket for receiving status probes. */voidinit_probe_socket()	{	struct	sockaddr_in sin;	int	one = 1;	/*	 *	Create probe_socket, a UDP socket for receiving a state	 *	probe packet.	 */	if ((probe_socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {		log(LOG_ERR, errno, "socket", 0);		exit(-1);	}	if (setsockopt(probe_socket, SOL_SOCKET, SO_REUSEADDR, (char *) &one, 							sizeof(one))) {		log(LOG_ERR, errno, "Uisock REUSEADDR", 0);		exit(-1);	}			/*	 *	Bind to probe port.	 */	NET_SOCKADDR_UDP_IPv4(&sin, inaddr_any, htons(STAT_PROBE_PORT));	if (bind(probe_socket, (struct sockaddr *) &sin, sizeof(sin))) {		log(LOG_ERR, errno, "bind", 0);		exit(-1);	}}/* * mcast_rsvp_state():  send Path State and Resv state information *	 to remote monitor programs (e.g., dmap or rsvpeep). *	 Called from dump_ds() in rsvp_debug.c. */void mcast_rsvp_state()	{	if (statsock < -1)		return;		/* ignore call */	if (statsock < 0) {		/*		 * First call: Convert target address: <host>.<port>		 * 	and set up socket address.  If it fails, set		 *	statsock = -2 and ignore future calls.  Currently		 *      <host> must be dotted decimal string.		 */		if (Status_Init(STAT_DEST_ADDR) < 0) {			statsock = -2;			return;		}	}	/* Now format and send path and reservation state */	Send_Empty = 0;	status_RSVP_Path(&mcast_sin);	status_RSVP_Resv(&mcast_sin);}voidsend_rsvp_state(char *probe_buf, int probe_len, struct sockaddr_in *fromp)	{	/* Probe packet may generally contain list of hosts to be	 * probed and list of sessions to be probed.  For now, assume	 * only present host and all sessions.	 */	struct sockaddr_in to = *fromp;	if (probe_len < sizeof(u_int32_t) ||	    ntohl(*(u_int32_t *)probe_buf) != TYPE_RSVP_PROBE)		return;	if (statsock < -1)		return;		/* ignore call */	if (statsock < 0) {		if (Status_Init(STAT_DEST_ADDR) < 0) {			statsock = -2;			return;		}	}	/* Now format and send path and reservation state */	Send_Empty = 1;	status_RSVP_Path(&to);	status_RSVP_Resv(&to);}/* * This procedure extracts the Path State information from rsvpd * data structure, marshals it, and sends it out. */voidstatus_RSVP_Path(struct sockaddr_in *sinp)	{	RSVPInfo_t	*Infop = (RSVPInfo_t *) buff;	PathInfo_t	*Pathp, *New_Pathp;	Session   	*dst;	int		 i;	nSession = 0;	Infop->type = hton32(TYPE_RSVP_VPATH);	strtcpy(Infop->name, RSVPNodeName, NAME_LEN);	Pathp = &Infop->Session_un.pathInfo;  /* first session */	/*	 * For each session ... 	 */	for (i= 0; i < SESS_HASH_SIZE; i++)	    for (dst = session_hash[i]; dst; dst = dst->d_next) {		/*		 *   Call subroutine to move session data into packet.  Then,		 *   if packet has overflown, write out data up through the		 *   previous session, and copy new session back into first 		 *   place.  Finally, count new session and record it in		 *   cache.		 */		New_Pathp = status_Path_Session(dst, Pathp);		if ((char *) New_Pathp > &buff[max_msg_size]) {			int newlen = (char *)New_Pathp - (char *)Pathp;			status_send((char *)Pathp, sinp);			New_Pathp = &Infop->Session_un.pathInfo;			memcpy(New_Pathp, Pathp, newlen);			New_Pathp = (PathInfo_t *)					((char *)New_Pathp + newlen);			nSession = 0;		}		nSession++;		Pathp = New_Pathp;	}	/*	 * Scan my private Session_List, looking for sessions that had	 *   path state last time but have none this time, and send an	 *   "empty" entry for any that are found.	 */	Gone_Sessp = NULL;	do {		Gone_Session(SL_FSM_PATH);		if (Gone_Sessp) {			Pathp->path_session = Gone_Sessp->sl_dest;			Pathp->path_R = 0;			Pathp->nSender = 0;			New_Pathp = (PathInfo_t *) &Pathp->path_sender;			if ((char *) New_Pathp > &buff[max_msg_size]) {				status_send((char *)Pathp, sinp);				return;  /* truncate... */			}			nSession++;			Pathp = New_Pathp;		}	} while (Gone_Sessp);	/*	 * Write last data, if any	 */	if ((nSession) || Send_Empty)		status_send((char *) Pathp, sinp);}/*	Move path status of specified session into output packet at *	location Pathp, return pointer to next.  We assume an output *	buffer large enough to hold max message plus the additional *	session we will add here. */static PathInfo_t *status_Path_Session(Session *dstp, PathInfo_t *Pathp)	{	PathSender_t	*PathSp;	PSB       	*snd;	char        	*if_name, *tp;	int		nSenders = 0;	Pathp->path_session.sess_destaddr.s_addr = dstp->d_addr.s_addr;	Pathp->path_session.sess_destport = dstp->d_port;	Pathp->path_R = dstp->d_Rtimop;	HTON32(Pathp->path_R);	Mark_Session(&Pathp->path_session, SL_FSM_PATH);	PathSp = &Pathp->path_sender;	for (snd = dstp->d_PSB_list; snd != NULL; snd = snd->ps_next) {		if_name = if_vec[snd->ps_in_if].if_name;		strtcpy(PathSp->pathS_in_if, if_name, IFNAMSIZ);		PathSp->pathS_phop.s_addr = snd->_ps_phop.s_addr;		PathSp->pathS_routes = snd->ps_outif_list;		PathSp->pathS_ttd = snd->ps_ttd;		/* HTON32(PathSp->pathS_routes); */		HTON32(PathSp->pathS_ttd);		/****** NOT IN USE: LPM has this info, but not RSVP.*/		tp = mstat_objcpy(Object_of(&PathSp->pathS_policy),					    &NULL_OBJECT);		tp = mstat_objcpy(Object_of(tp), Object_of(snd->ps_templ));		tp = mstat_objcpy(Object_of(tp), Object_of(snd->ps_tspec)); 		PathSp = (PathSender_t *) tp;		nSenders++;		/**** CHECK FOR OVERFLOW ***/	}	Pathp->nSender = nSenders;	HTON32(Pathp->nSender);	return((PathInfo_t *) PathSp);}

⌨️ 快捷键说明

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