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

📄 rapi_lib.c

📁 radius协议源码÷The Radius Stack will connect to a Radius Server. This stack implementation is built upo
💻 C
📖 第 1 页 / 共 4 页
字号:
		return(rapi_dispatch_fd(rsvp_socket));	return RAPI_ERR_OK;}intrapi_version()	{#if     (defined(SOLARIS) && defined(RTAP))        init_rapi();#endif  /* (defined(SOLARIS) && defined(RTAP)) */	return RAPI_VERSION;}#ifdef ISI_TEST/*  rapi_status(): *	Trigger Path Event and/or Resv Event upcalls for specified sid, *	or, if sid = 0, all sid's in this process. */intrapi_status(	rapi_sid_t sid,	int	flags)		/* Direction flags */	{	char		req_buf[MAX_MSG];	rsvp_req	*req = (rsvp_req *) req_buf;	rapi_errno = RAPI_ERR_OK;	if (sid && !is_valid(sid)) {		return RAPI_ERR_BADSID;	}	memset((char *)req, 0, sizeof(req_buf));	req->rq_type = API2_STAT;	if (sid)		req->rq_dest = sid_vec[sid].dest; /* already in host BO */	req->rq_flags = flags;	(void)send_req(req, sizeof(rsvp_req), sid, rsvp_socket);	return (rapi_errno);	}#endif /* ISI_TEST *//*  The following routine is not part of the official RAPI interface. *	It is a management interface to rsvpd. */rapi_sid_trapi_rsvp_cmd(rapi_cmd_t *cmd, int *errnop)	{	char		*req_buf;	rsvp_req	*req;	int             lsid = NULL_SID;	int             old = 0;	char		*cp;	int		tmp_socket = -1;  				/* temporary socket to */ 				/* be used in sending debug cmd */  	int		n;	rapi_errno = RAPI_ERR_OK;	if (init_flag == 0) {		if (init_rapi()<0) {			rapi_errno = RAPI_ERR_NORSVP;			goto exit;		}	}	n = sizeof(int)*cmd->rapi_cmd_len;	if (!(req_buf = malloc(n+sizeof(rsvp_req)))) {		rapi_errno = RAPI_ERR_MEMFULL;		goto exit;	}	/* Use any free sid entry	 */ 	if ((lsid = Get_free_slot()) < 0) {		rapi_errno = RAPI_ERR_MAXSESS;		goto exit;	}	mark_sid_inuse(lsid);		req  = (rsvp_req *) req_buf;	req->rq_type = API_DEBUG;	cp = req_buf + sizeof(rsvp_req);	memcpy(cp, cmd, n);#ifdef USE_NET_BO	hton_rapi_cmd((rapi_cmd_t *)cp);#endif	cp += n;	/* Grab a temporary socket to connect to the daemon so that 	 * we can safely expect a reply to our request as the next 	 * thing sent along on the socket. 	 */	tmp_socket = connect_to_daemon(DEBUG_RSVP_CONNECTION_SERIAL_NUM);         if (tmp_socket < 0) {		rapi_errno = RAPI_ERR_NORSVP;	}	else {		send_req(req, cp-req_buf, lsid, tmp_socket);		close(tmp_socket);  /* get rid of the tmp socket */	}	mark_sid_free(lsid);exit:	if (errnop)		*errnop = rapi_errno;		if (req_buf)		free(req_buf);	return old;}/********************************************************** *       Initialization and I/O Routines * **********************************************************//* Common routine to format a REGISTER request and send it to *	the daemon.  Returns rapi_errno. */rapi_sid_tcommon_register(	rapi_sid_t		sid,	struct sockaddr		*LHost,	/* Source host, port */	int			flags,  /* Session or sender flags */	rapi_filter_t *		sender_template,  /* (Optional) */	rapi_tspec_t  *		sender_tspec,	rapi_adspec_t *		sender_adspec,	rapi_policy_t *		sender_policy,	int			ttl)	{	char			req_buf[API_REGIS_BUF_LEN];	char			*End_buf = &req_buf[API_REGIS_BUF_LEN];	rsvp_req		*req = (rsvp_req *) req_buf;	char 			*cp;	rapi_filter_t		fl, *flp;	rapi_errno = RAPI_ERR_OK;	/*	 *  Build REGISTER request and send to daemon	 */	memset((char *)req, 0, API_REGIS_BUF_LEN);	req->rq_type = API2_REGISTER;	req->rq_dest = sid_vec[sid].dest;	req->rq_protid = sid_vec[sid].protid;	req->rq_nflwd = 0;	req->rq_flags = flags;	req->rq_ttl = ttl;	if (LHost != NULL || sender_template != NULL) {		/*	rapi_sender call.		 */		cp = copy_policy_i2d(sender_policy, req->rq_policy, End_buf, 0);		if (!cp)			return rapi_errno;		/*		 *	If sender_template is NULL, use LHost.		 */		if (sender_template == NULL) {			/*	GPI session must have sender template			 */			if (flags&RAPI_GPI_SESSION)				return RAPI_ERR_GPISESS;			sockaddr2filterbase(LHost, flp = &fl);		} else {			if (!GPIness_matches(sender_template))				return RAPI_ERR_GPI_CONFLICT;			flp = sender_template;		}				cp = (char *) copy_sender_desc(flp,				 sender_tspec, sender_adspec,				(API_FlowDesc *) cp, End_buf);		if (!cp)			return rapi_errno;		req->rq_nflwd = 1;	} else {		cp = copy_policy_i2d(NULL, req->rq_policy, End_buf, 0);		if (!cp)			return rapi_errno;	}#ifdef USE_NET_BO	HTON16(req->rq_nflwd);#endif	send_req(req, cp-req_buf, sid, rsvp_socket);	return(rapi_errno);}/*	Find and return index of free slot in table, or return -1 if *	table is full.  If succeeds, clears slot to zero. */intGet_free_slot()	{	int sid;	/* To avoid ambiguity, we avoid using sid = zero.	 */	for (sid = 1; sid <= max_sid ; sid++)		if (!sid_vec[sid].in_use)			return(sid);	if (sid < MAX_RAPI_SESS) {		max_sid = sid;		memset((char *)&sid_vec[sid], 0, sizeof(sid_rec));		return(sid);	}	return(-1);	/* Table full */}static voidsig_pipe(int sig)	{	/*	 * This has to be fixed.  A SIGPIPE typically means the server	 * dropped the connection.  The client either needs to die, or to try	 * to reestablish the connection.	 */	/* 	 * TBD:  call client handler with appropriate error 	 */	fprintf(stderr, "Got a SIGPIPE\n");	signal(SIGPIPE, sig_pipe);}static intinit_rapi()	{	struct sockaddr_in x;	pid = getpid();	signal(SIGPIPE, sig_pipe);	(void)memset((char *) sid_vec, 0, sizeof(sid_vec));	init_flag = 1;	rapi_errno = RAPI_ERR_OK;	rsvp_socket_refs = 0;	NET_SOCKADDR_IPv4(&x,inaddr_any)	net_addr_assign(&api_address,(struct sockaddr *) &x);	api_addr_assign(&api_address2,(struct sockaddr *) &x);	/*	Open a single pipe that this process will use 	 *	to talk to the rsvp daemon.	 */ 	rsvp_socket = connect_to_daemon(MAIN_RSVP_CONNECTION_SERIAL_NUM);	return((rsvp_socket < 0) ? -1 : 0);}staticstruct sockaddr *get_local_address(unsigned short port){	char name[MAXHOSTNAMELEN];	struct hostent *hp;	struct in_addr in;	static struct sockaddr_in sin;	if (FAILED(gethostname(name,MAXHOSTNAMELEN)))		return(NULL);	if (inet_pton(AF_INET,name,&in) == 1) {		NET_SOCKADDR_UDP_IPv4(&sin,in,port);		return((struct sockaddr *) &sin);	}	hp = gethostbyname2(name,AF_INET);	if (hp != NULL) {		memcpy(&in,hp->h_addr,hp->h_length);		NET_SOCKADDR_UDP_IPv4(&sin,in,port);		return((struct sockaddr *) &sin);	}	return(NULL);}staticintconnect_to_daemon_tcp(int serial_no){	int sock,ret;	struct sockaddr *s;	if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {		perror("opening socket");		return (-1);	}#ifdef        SOLARIS	if (fcntl(sock,F_SETFL,fcntl(sock,F_GETFL) | O_NONBLOCK) == -1) {		perror("Setting Non-blocking I/O");		return(-1);	}#endif        /* SOLARIS */	s = get_local_address(hton16(API_PORT));	if (s == NULL)		return(-1);	ret = connect(sock, s,sizeof(struct sockaddr_in));#ifdef  SOLARIS	if ((ret >= 0) || (errno == EINPROGRESS)) {#else   /* SOLARIS */	if (ret >= 0) {#endif  /* SOLARIS */		return (sock);	}	close(sock);	return (-1);}staticintconnect_to_daemon_unix(int serial_no){	int             sock, ret, addr_len;	struct sockaddr_un name, server;	if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {		perror("opening socket");		return (-1);	}	sprintf(client_namestr, "%s.%u.%u", LNAME, pid, serial_no);	unlink(client_namestr);	name.sun_family = AF_UNIX;	strcpy(name.sun_path, client_namestr);#ifdef STANDARD_C_LIBRARY	addr_len = (offsetof(struct sockaddr_un, sun_path)		    + strlen(name.sun_path));#else	addr_len = sizeof(name.sun_family) + strlen(name.sun_path);#endif#ifdef SOCKADDR_LEN	name.sun_len = addr_len;#endif	if (bind(sock, (struct sockaddr *) & name, addr_len) < 0) {		perror("bind");		goto BadOpen;	}#ifdef        SOLARIS	if (fcntl(sock,F_SETFL,fcntl(sock,F_GETFL) | O_NONBLOCK) == -1) {		perror("Setting Non-blocking I/O");		exit(-1);	}#endif        /* SOLARIS */	server.sun_family = AF_UNIX;	strcpy(server.sun_path, SNAME);#ifdef STANDARD_C_LIBRARY	addr_len = (offsetof(struct sockaddr_un, sun_path)		    + strlen(server.sun_path));#else	addr_len = sizeof(server.sun_family) + strlen(server.sun_path);#endif#if BSD >= 199103	server.sun_len = addr_len;#endif	ret = connect(sock, (struct sockaddr *) &server,						 sizeof(struct sockaddr_un));#ifdef  SOLARIS	if ((ret >= 0) || (errno == EINPROGRESS)) {#else   /* SOLARIS */	if (ret >= 0) {#endif  /* SOLARIS */		unlink(client_namestr);		return (sock);	}BadOpen:	close(sock);	unlink(client_namestr);	return (-1);}staticintconnect_to_daemon(int serial_no){	int sock;	sock = connect_to_daemon_unix(serial_no);	if (sock < 0)		return(connect_to_daemon_tcp(serial_no));	return(sock);}/*	Send request to daemon.  Send 4 bytes containing length of *	req structure, followed by req structure itself. * *	JBG: added sock as an argument to the following so that the  *	debug interface can open its own temporary socket and use it.  */ static intsend_req(rsvp_req * req, int len, long sid, int sock)	{	struct iovec iov[2];	int nlen = len;	req->rq_pid = pid;	req->rq_a_sid = sid;	req->rq_version = VERSION_API;#ifdef USE_NET_BO	HTON32(req->rq_pid);	HTON32(req->rq_a_sid);	HTON32(nlen);	req->rq_flags |= API_NET_BO;#endif	iov[0].iov_base = (char *) (&nlen); 	iov[0].iov_len  = sizeof(int); 	iov[1].iov_base = (char *) req; 	iov[1].iov_len  = len;   #ifdef SOLARISretry:      #endif /* SOLARIS */	if (writev(sock, iov, 2) == -1)  {#ifdef SOLARIS		int retry_cnt = 0;				if((errno == EAGAIN) && (retry_cnt++ < 5)) {			/* Hack to get around race condition where			 *  we get to this operation before the non-blocking			 *  connect completes.			 */			sleep(2);			goto retry;		}#endif /* SOLARIS */					rapi_errno = RAPI_ERR_SYSCALL;	}	return(0);}intrapi_dispatch_fd(int fd_val)	{	char		*resp_buf = NULL;	rsvp_resp	*resp;	int		i, len, n, nr, size;	int		n_filter, n_flowspec, n_adspec;	rapi_filter_t	*api_filter = NULL, *tapi_filt;	rapi_flowspec_t *api_flowspec = NULL, *tapi_spec;	rapi_adspec_t	*api_adspec = NULL, *tapi_adspp;	char		*eapi_filt, *eapi_spec, *eapi_adspp;	API_FilterSpec	*fltr;	API_Flowspec	*flow;	API_Adspec	*adspp;	sid_rec		*sidp;	struct SOCKADDR enode;	char		*cp;	rapi_errno = RAPI_ERR_OK;		/*	Response is sent as a 4-byte length field followed by	 *	that many bytes of response data.  Read length and	 *	then malloc buffer.	 */	n = read(fd_val, &len, sizeof(int));#ifdef USE_NET_BO	NTOH32(len);#endif	if (n == 0) {	/* EOF => RSVP daemon is gone... ! */		rapi_errno = RAPI_ERR_NORSVP;		goto err_exit;	}	else if (n < sizeof(int)) {		rapi_errno = RAPI_ERR_SYSCALL;		goto err_exit;	/* some error in the mechanism */	}	if (n == -1) {		rapi_errno = RAPI_ERR_NORSVP;		goto err_exit;	}	if (!(resp_buf = malloc(len))) {		rapi_errno = RAPI_ERR_MEMFULL;		goto err_exit;	}	resp = (rsvp_resp *)resp_buf;	nr = len;	cp = resp_buf;	while (nr) {		n = read(fd_val, cp, nr);		if (n <= 0) {			rapi_errno = RAPI_ERR_NORSVP;			goto err_exit;		}		nr -= n;		cp += n;	}	/* This version always sends in a request in network byte order;	 *	we assume that rsvpd sends a response in network byte order.	 */#ifdef USE_NET_BO	NTOH32(resp->resp_a_sid);	NTOH32(resp->resp_style);	NTOH16(resp->resp_errval);	NTOH16(resp->resp_nflwd);#endif	sidp = &sid_vec[resp->resp_a_sid];			/* XXX should validate a_sid */	sockaddr_assign((struct sockaddr *) &enode,&resp->resp_errnode);	if (resp->resp_nflwd == 0) {		/* Special case: nflwd == 0; means teardown of state.		 * Invoke the client's upcall routine		 */		if (sidp->event_rtn)	  	  (*(sidp->event_rtn)) (			(rapi_sid_t) resp->resp_a_sid,			(rapi_eventinfo_t) resp->resp_type,			resp->resp_style, 			resp->resp_errcode, resp->resp_errval,			(struct sockaddr *) &enode,			resp->resp_errflags,			0, NULL, 0, NULL, 0, NULL,			sidp->event_rtn_arg	   	 );		goto err_exit;	}	/*	Malloc space for filtspec, flowspec, adspec lists for app	 *	 *	NB:  allocating space based on worst case sizes.	 *      XXX Could 'parse' vbl-length info to determine actual sizes	 */	size = sizeof(rapi_filter_t) * resp->resp_nflwd;	if ((api_filter = malloc(size)) == NULL) {		rapi_errno = RAPI_ERR_MEMFULL;		goto err_exit;	}	eapi_filt = (char *)api_filter + size;	size = sizeof(rapi_flowspec_t) * resp->resp_nflwd;	if ((api_flowspec = malloc(size)) == NULL) {		rapi_errno = RAPI_ERR_MEMFULL;		goto err_exit;	}	eapi_spec = (char *)api_flowspec + size;	/*  Copy list of (filterspec, flowspec) pairs into 2 areas	 */	tapi_filt = api_filter;	tapi_spec = api_flowspec;	n_filter = n_flowspec = n_adspec = 0;

⌨️ 快捷键说明

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