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

📄 rsvp_main.c

📁 radius协议源码÷The Radius Stack will connect to a Radius Server. This stack implementation is built upo
💻 C
📖 第 1 页 / 共 3 页
字号:
static voidsigint_handler(int sig){	log(LOG_ERR, 0, "Exiting on signal %d\n", sig);	final();	_exit(sig);}/* * init_rsvp():  Initialize rsvpd.  Read the vif info from the  *	kernel, initialize the sockets, and start the timer. */static intinit_rsvp(void){	int i;	extern STYLE	Style_Obj;	/* Zero out and initialize headers of some global objects	 */	Init_Object(&Style_Obj, STYLE, STYLE_CTYPE);	FD_ZERO(&fds);		/*	Misc initializations	 */ 	memset(session_hash, 0, SESS_HASH_SIZE*sizeof(Session *));	memset(key_assoc_table, 0, KEY_TABLE_SIZE * sizeof(KEY_ASSOC));	Key_Assoc_Max = 0;	/*	 *	Initialize encapsulation group G* and ports Pu, Pu', and	 *	set up encapsulation socket addr structure.	 */	if (inet_pton(AF_INET,RSVP_ENCAP_GROUP,&encap_group) != 1){		log(LOG_ERR, errno, "Encap grp addr", 0);		return(-1);	}	encap_port = hton16((u_int16_t) RSVP_ENCAP_PORT);	encap_portp = hton16((u_int16_t) RSVP_ENCAP_PORTP);	NET_SET_ADDR3_UDP_IPv4(&encap_mc_addr,encap_group,encap_port)#ifdef	USE_IPV6	if (inet_pton(AF_INET6,RSVP_ENCAP_GROUP6,&encap_group6) != 1){		log(LOG_ERR, errno, "Encap grp addr 6", 0);		return(-1);	}	NET_SET_ADDR3_UDP_IPv6(&encap_mc_addr6,encap_group6,encap_port)#endif	/* USE_IPV6 */	rsrr_interface_query(1);#ifdef	USE_IPV6	if (FAILED(net_init(encap_port,encap_portp,			&encap_group,&encap_group6,FALSE))) {#else	/* USE_IPV6 */	if (FAILED(net_init(encap_port,encap_portp,&encap_group,FALSE))) {#endif	/* USE_IPV6 */		log(LOG_ERR,errno,"net_init");		return(SYS_ERROR);	}	/* In case mrouted is slow */	rsrr_initial_reply = 1;	rsrr_dispatch();	/*	 *	Look for a configuration file and apply it.  For interfaces	 *	whose LL init routine is not specified in config file, set	 *	default LL (pt-pt|LAN)	 */	read_config_file("rsvpd.conf");	for (i = 0; i < if_num; i++) {		if (IsNumAPI(i))			continue;		if (*if_vec[i].if_LLifv.LL_NewFlow_p == NULL)			KernTC_if_init(i); /* default traffic control */	}	print_ifs();	if (FAILED(net_poll_list(&fds))) {        log(LOG_ERR,errno,"net_poll_list");        return(SYS_ERROR);    }	/*	Initialize:	 *	--  probe_socket: socket for receiving status probes	 *	--  api_socket: API listen socket	 *	--  Timer routines	 *	--  kernel traffic control	 */	init_probe_socket();	init_api();	init_timer(MAX_TIMER_Q);	return (0);}intstatus_probe(int ifd)	{	char            recv_buf[MAX_PKT];	struct sockaddr_in from;	int             from_len, recv_len;	from_len = sizeof(from);	memset((char *) &from, 0, from_len);	recv_len = recvfrom(ifd, recv_buf, sizeof(recv_buf),			    0, (struct sockaddr *) & from, &from_len);	if (recv_len < 0) {		log(LOG_ERR, errno, "recvfrom", 0);		return(-1);	}	send_rsvp_state(recv_buf, recv_len, &from);	return(0);}/* * start_UDP_encap(vif_no): Called to initialize for UDP encapsulation *	on specified vif number. */intstart_UDP_encap(int vif)	{		IF_FLAGS(vif) |= IF_FLAG_UseUDP;	return(0);}#define Clear_LL_Vector(n) memset(&if_vec[n].if_LLifv, 0, sizeof(LLDAL_calls_t))/* *  if_list_init(): *		Initialize  table describing physical interfaces, *		if_vec[0...if_num].  Return number of interfaces if_num. *		The last element corresponds to the API. */intif_list_init() {	int		if_num = 0;	struct ifreq ifr;	struct if_nameindex *p,*q;	struct if_attributes *l;	struct sockaddr *s;	net_addr addr;#if DEBUG	if (Test_mode) {		/* Test mode: read file named .rsvp.ifs containing:		 *	<if name> <if address> <remote addr>		 */		FILE *fp = fopen(".rsvp.ifs", "r");		char	buff[80], ipaddrstr[64], ifname[32], rmtaddrstr[64];				if (fp == NULL) {			fprintf(stderr, "Error reading .rsvpifs\n");			exit(1);		}		if_vec = (if_rec *) calloc(MAX_INTERFACES, sizeof(if_rec));		tsttun_vec = (net_addr *) calloc(RSRR_MAX_VIFS_V2+1, sizeof(net_addr));		tst_sock2if = (int *) calloc(256, sizeof(int));		memset(tst_sock2if, -1, 4*256);		while (fgets(buff, sizeof(buff), fp)) {			if (if_num >= (MAX_INTERFACES - 1)) {				fprintf(stderr, ".rsvpifs file too big\n");				exit(1);			}			sscanf(buff, "%s %s %s", ifname, ipaddrstr, rmtaddrstr);			if_vec[if_num].if_flags = 0;			if_vec[if_num].if_index = if_num;			if_vec[if_num].if_unicast = if_num;			strncpy(if_vec[if_num].if_name, ifname, IFNAMSIZ);			net_addr_ascii(&addr,ipaddrstr);			NET_SET_IF_PHY(&if_vec[if_num].if_addr,addr,if_num);			net_addr_ascii(&tsttun_vec[if_num],rmtaddrstr);			if_num++;		}		strcpy(if_vec[if_num].if_name, "API"); 		if_vec[if_num].if_unicast = if_num;		api_num = if_num;		return(++if_num);	}#endif		p = if_nameindex();	if(p == NULL)		return(0);	if_vec = (if_rec *) calloc(MAX_INTERFACES, sizeof(if_rec));	for(q = p; q->if_name != NULL; q++) {		if (strncmp("lo",q->if_name,2) == 0)			continue;		l = if_attributes(q->if_index);		for(s = l->addr; s != NULL; s = (++l)->addr) {			switch (s->sa_family) {				case AF_INET:					if (local_v4 == -1)						if (l->flags&IFF_UP)							local_v4 = if_num;					break;#ifdef	USE_IPV6				case AF_INET6:					if (local_v6 == -1)						if (l->flags&IFF_UP)							local_v6 = if_num;					break;#endif	/* USE_IPV6 */				default:					continue;			}			if (if_num == (MAX_INTERFACES - 1)) {				log(LOG_ERR,0,"Too Many Network Interfaces");				break;			}			strncpy(if_vec[if_num].if_name, q->if_name, IFNAMSIZ);			net_addr_assign(&addr,s);			NET_SET_IF_PHY(&if_vec[if_num].if_addr,addr,				q->if_index);			if_vec[if_num].if_index = q->if_index;			if_vec[if_num].if_unicast = if_num;			strncpy(ifr.ifr_name,q->if_name,sizeof(ifr.ifr_name));			if_vec[if_num].if_flags = 				(l->flags&IFF_UP) ? IF_FLAG_IFF_UP : 0;			if_vec[if_num].if_flags |= 				(l->flags&IFF_MULTICAST) ? IF_FLAG_IFF_MC : 0;			if_vec[if_num].if_udpttl = RSVP_TTL_ENCAP;			if_vec[if_num].prefix = l->prefix;			Clear_LL_Vector(if_num);  /* for safety */			if_num++;		}	}	if_freenameindex(p);	/* Add one more entry corresponding to API	 */	Clear_LL_Vector(if_num);	/* No intserv link layer for API */	strcpy(if_vec[if_num].if_name, "API");	if_vec[if_num].if_unicast = if_num;	if_vec[if_num].if_flags = IF_FLAG_IFF_UP;	/* Well, yes */	if_vec[if_num].prefix = 0;	NET_SET_IF_PHY(&if_vec[if_num].if_addr,api_address,0);	api_num = if_num;	return (++if_num);}/* * init_api() initializes the api between the daemon and client applications. * The daemon listens for incoming requests (coming on a unix socket) from * application, and stores some local info about these requests. This info * includes a copy of an RSVP packet with the needed info, that will be * refreshed and throughn in every refresh period. */voidinit_api(){	int	i;	struct sockaddr_un server;	/* struct sockaddr_in myaddr; */	int 	addr_len;	memset(api_table, 0, sizeof(api_table));	/*	if ((api_udp_socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {		log(LOG_WARNING, errno, "opening api_udp_socket\n");	}	else {		myaddr.sin_family = htons(AF_INET);		myaddr.sin_port = htons(API_PORT);		myaddr.sin_addr.s_addr = 0;		if (FAILED(bind(api_udp_socket,(struct sockaddr *)&myaddr, 			sizeof(myaddr)))) {			log(LOG_WARNING, errno, "bind() for api_udp_socket\n");		}	}	*/	(void) unlink(SNAME);	/* The unix socket name */	if ((api_socket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {		log(LOG_WARNING, errno, "opening socket\n");		assert(NULL);	/* i.e. abort() */	}	server.sun_family = AF_UNIX;	(void) strcpy(server.sun_path, SNAME);#ifdef STANDARD_C_LIBRARY	/*	 * This is only necessary for Net/2 and later, but it's never	 * incorrect on earlier systems, so do it.	 */	addr_len = (offsetof(struct sockaddr_un, sun_path)		    + strlen(server.sun_path));#else	addr_len = sizeof(server.sun_family) + strlen(server.sun_path);#endif#ifdef SOCKADDR_LEN	server.sun_len = addr_len;#endif	if (bind(api_socket, (struct sockaddr *) & server, addr_len) < 0) {		log(LOG_WARNING, errno, "bind");		assert(NULL);	/* i.e. abort() */	}	if (chmod(SNAME,SMODE) == -1)		log(LOG_WARNING, errno, "chmod of API socket");	i = 1;#ifdef SOLARIS	if (fcntl(api_socket, F_SETFL, (fcntl(api_socket, F_GETFL) | O_NONBLOCK)) == -1) {		log(LOG_ERR, errno, "Setting Non-blocking I/O\n");		exit(-1);	}#else	if (ioctl(api_socket, FIONBIO, &i) == -1) {		log(LOG_ERR, errno, "Setting Non-blocking I/O\n");		exit(-1);	}#endif /* SOLARIS */	(void) listen(api_socket, 10);	/* Maximum pending req. at one time */}/* * api_input(): reads an API request from UNIX pipe, and processes it. *		First 4 bytes are length of following request. */intapi_input(int fd) {	int             rc, len, nr;	int		sid;	char            recv_buf[MAX_MSG];	rsvp_req	*req = (rsvp_req *) recv_buf;	int		ret_val = 0;	/*	if (fd == api_udp_socket)		rc = recvfrom(fd,recv_buf,sizeof(recv_buf),0,NULL,NULL);	else {	*/	rc = read(fd, &len, sizeof(int));#ifdef USE_NET_BO	NTOH32(len);#endif	if (rc != sizeof(int)) {		if (rc == 0) {            		/*              		 *  Application quit or died rather than closed             		 *  the RSVP connection; not an error.          		 */      			ret_val = 0;			goto err_exit;		}		else {			log(LOG_ERR, errno, "Error in API read\n");			ret_val = -1;			goto err_exit;		}        }	nr = len;	while (nr) {		rc = read(fd, (char *) req, nr);		if (rc <= 0) {			ret_val = RAPI_ERR_NORSVP;			goto err_exit;		}		nr -= rc;	}	/*	}	*/	if (req->rq_type == API_DEBUG) {		char *cmd = (char *)req + sizeof(rsvp_req);		ntoh_rapi_cmd((rapi_cmd_t *)cmd);		return(api_cmd(fd, (rapi_cmd_t *)cmd));	}	else if (req->rq_type == API2_STAT)		/* Trigger event upcalls to return status */		return(api_status(req));	/*	if (NetByteOrderReq(req) || fd == api_udp_socket)	*/	if (NetByteOrderReq(req))		ntoh_api_request(req, rc);  /* Convert to host byte order */		/*	Locate or create local sid for this request, given the	 *	fd (Unix pipe) on which it arrived, the process from which	 *	it came, and client's sid.	 */	sid = find_sid(fd, req->rq_pid, req->rq_a_sid);	if (sid < 0 && req->rq_type == API2_REGISTER) { 		/*  First message; look for available slot. 		 */ 		sid = find_free_sid(fd, req->rq_pid, req->rq_a_sid);              		if (sid < 0) { /* XXX api error */ 			log(LOG_WARNING, 0, "API: too many sessions\n"); 			return (-1); 		}		memset(&api_table[sid], 0, sizeof(api_rec)); 		api_table[sid].api_fd = fd; 		api_table[sid].api_pid = req->rq_pid; 		api_table[sid].api_a_sid = req->rq_a_sid; 		num_sessions++; 	}	else if (sid < 0) { 		log(LOG_ERR, 0, "API: req %d from ?? pid= %dAsid= %d\n",				req->rq_type, req->rq_pid, req->rq_a_sid); 		return(-1); 	}	if (process_api_req(sid, req, rc) < 0) {		/* Return code = -1 => release the session.		 */		api_table[sid].api_fd = 0;		rsvp_api_close(sid);		if (req->rq_type != API_CLOSE) {			/* Even though only one session had error,			 * close the Unix socket to the process.			 */			(void) close(fd);			FD_CLR(fd, &fds);			return(-1);		}	}	return(0);err_exit:	/*	No message from which to derive the SID, but we 	 *	have to close all sids that used that fd.	 */ 	for (sid = 0; sid < API_TABLE_SIZE; sid++) { 		if (api_table[sid].api_fd == fd) {			api_table[sid].api_fd = 0;				/* prevent upcall */			process_api_req(sid, NULL, 0);			rsvp_api_close(sid); 		}	}    	/* 	Now close the socket.	 */          	FD_CLR(fd, &fds); 	(void) close(fd); 	return ret_val; }intsid_hash(int fd, int pid, int client_sid) { 	u_int32_t ufd = fd; 	u_int32_t upid = pid; 	u_int32_t u_client_sid = client_sid;	return ((((ufd*65599 + upid)*65599) + u_client_sid)*65599) % 							API_TABLE_SIZE; }  /* * find_sid(): Search API table to locate sid for this fd, pid, and client_sid * *	Use open hash table.  Return -1 if no match. */intfind_sid(int fd, int pid, int client_sid) 	{ 	int first_sid = sid_hash(fd, pid, client_sid); 	int test_sid, i; 	api_rec * test_rec;  	for (i=0, test_sid=first_sid; i<API_TABLE_SIZE;  test_sid++, i++) 		{		if (test_sid >= API_TABLE_SIZE) 			test_sid -= API_TABLE_SIZE;  		test_rec = &api_table[test_sid];        		if (test_rec->api_fd == fd 			&& test_rec->api_pid == pid 			&& test_rec->api_a_sid == client_sid) 				return test_sid;		else if (test_rec->api_fd == 0)			return(-1);	}	return -1;                        /* no match */ }  /*  find_free_sid():  Returns sid for a free slot in API table api_table[], *		for this fd, pid and client_sid.  Does not allocate. */intfind_free_sid(int fd, int pid, int client_sid) 	{ 	int first_sid = sid_hash(fd, pid, client_sid); 	int test_sid, i; 	api_rec * test_rec;  	/* do not allow hash table to get more than half full */ 	if (num_sessions >= MAX_SESSIONS) 		return -1;  	for (i=0, test_sid=first_sid; i<API_TABLE_SIZE; test_sid++, i++) 		{		if (test_sid >= API_TABLE_SIZE) 			test_sid -= API_TABLE_SIZE;  		test_rec = &api_table[test_sid];        		if (test_rec->api_fd == 0) 			return test_sid; 	}	return -1;                        /* no match */ } /*  *	Release API session */voidrsvp_api_close(int sid) {	api_rec *recp = &api_table[sid];	del_from_timer((char *) (unsigned long)sid, TIMEV_API);	api_free_packet(&recp->api_p_packet);	api_free_packet(&recp->api_r_packet);	num_sessions--;}/* * refresh_api():  Called from process_api_req when new request *	arrives from API, and periodically from timer.  It injects *	stored API packets into the processing as if they had arrived *	from the network (except API packets are in host byte order). * *      Returns 0 normally to restart timer, -1 to kill timer. */intrefresh_api(int sid) {	api_rec		*recp = &api_table[sid];	int		rc;	/*	 *  Make sure the process still exists before keeping the message	 *  alive.	 */

⌨️ 快捷键说明

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