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

📄 pooladdr.c

📁 RADIUS协议的认证计费服务
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * *      Copyright (c) 1996 Ascend Communications, Inc. *      All rights reserved. * *      Permission to copy, display, distribute and make derivative works *      from this material in whole or in part for any purpose is granted *      provided that the above copyright notice and this paragraph are *      duplicated in all copies.  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. * *//* * Copyright [C] The Regents of the University of Michigan and Merit Network, * Inc. 1992, 1993, 1994, 1995, 1996, 1997, 1998 All Rights Reserved * * Permission to use, copy, and modify this software and its documentation  * for any purpose and without fee is hereby granted, provided:  * * 1) that the above copyright notice and this permission notice appear in all *    copies of the software and derivative works or modified versions thereof,  * * 2) that both the copyright notice and this permission and disclaimer notice  *    appear in all supporting documentation, and  * * 3) that all derivative works made from this material are returned to the *    Regents of the University of Michigan and Merit Network, Inc. with *    permission to copy, to display, to distribute, and to make derivative *    works from the provided material in whole or in part for any purpose. * * Users of this code are requested to notify Merit Network, Inc. of such use * by sending email to aaa-admin@merit.edu * * Please also use aaa-admin@merit.edu to inform Merit Network, Inc of any * derivative works. * * Distribution of this software or derivative works or the associated * documentation is not allowed without an additional license. * * Licenses for other uses are available on an individually negotiated * basis.  Contact aaa-license@merit.edu for more information. * * THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE REGENTS OF THE * UNIVERSITY OF MICHIGAN AND MERIT NETWORK, INC. DO NOT WARRANT THAT THE * FUNCTIONS CONTAINED IN THE SOFTWARE WILL MEET LICENSEE'S REQUIREMENTS OR * THAT OPERATION WILL BE UNINTERRUPTED OR ERROR FREE.  The Regents of the * University of Michigan and Merit Network, Inc. shall not be liable for any * special, indirect, incidental or consequential damages with respect to any * claim by Licensee or any third party arising from use of the software. * * Merit AAA Server Support * Merit Network, Inc. * 4251 Plymouth Road, Suite C. * Ann Arbor, Michigan, USA 48105-2785 * * attn:  John Vollbrecht * voice: 734-764-9430 * fax:   734-647-3185 * email: aaa-admin@merit.edu * *//* * * Public entry points in this file: * */static char     rcsid[] = "$Id: pooladdr.c,v 1.1.1.1 2001/08/10 20:49:28 bonze Exp $";#include	<sys/types.h>#include	<sys/param.h>#include	<sys/time.h>#include	<sys/errno.h>#include	<sys/file.h>#include	<sys/wait.h>#include	<sys/socket.h>#include	<net/if.h>#include	<netinet/in.h>#include	<stdio.h>#include	<netdb.h>#include	<errno.h>#include	<signal.h>#include	<memory.h>#include	<syslog.h>#include	"radius.h"#ifndef IP_ADDR_POOLstatic AATV     ip_alloc_aatv = DEF_AATV_DIRECT("IPPOOL", fatal_action);AATVPTR         rad_ip_pool_aatv = & ip_alloc_aatv;#else	/* IP_ADDR_POOL */extern char     recv_buffer[RAD_RECV_BUFFER_SIZE];extern char     send_buffer[RAD_SEND_BUFFER_SIZE];extern int      debug_flag;extern int      spawn_flag;     /* 0 => no spawning, 1 => spawning allowed */extern char    *radius_dir;static int      sockfd = -1;static u_char   timeout;static char     white_space[] = " \t\r\n";static int      ip_address_recv PROTO((UINT4, AUTH_REQ *));static int      ip_address_send PROTO((int, void *, UINT4, ipaddr_t,					ADDRESS_CHUNK *, int));static int      parse_global PROTO((char *, ADDRESS_CHUNK *));static UINT4    parse_hosts PROTO((void));static int      parse_pool PROTO((char *, ADDRESS_CHUNK **));static void     pool_time_out PROTO((int));RADIPA_PACKET  *reorder_integers PROTO((char*));static int      try_connect PROTO((UINT4));UINT4           addr;#define	IP_POOL_TIME	3 * 60 /* Need a response within this time period */static void     pool_init PROTO((AATV *));static int      pool_addr PROTO((AUTH_REQ *, int, char *));static void     pool_cleanup PROTO((void));static AATV     ip_alloc_aatv = DEF_AATV_FREPLY_FULL("IPPOOL", -1, pool_init,							NULL, pool_addr,							pool_cleanup, 0);AATVPTR         rad_ip_pool_aatv = & ip_alloc_aatv;/************************************************************************* * *	Function: pool_init * *	Purpose: Initialize the TCP connection to the RADIPAD daemon. * *************************************************************************/static voidpool_init (unused)AATV   *unused;{	UINT4           addr;	static int      init_count = 0;	static char    *func = "pool_init";	dprintf(2, (LOG_AUTH, LOG_DEBUG, "%s: entered", func));	init_count++;	if (init_count <= 1)	/* Ensure that users file is read into core. */	{		return;	}	if (sockfd == -1)	{		sockfd = socket (AF_INET, SOCK_STREAM, 0); /* for TCP */	}	/* This assumes the users file has been read into memory.  See above. */	if ((addr = parse_hosts ()) == INADDR_ANY)	{		logit (LOG_DAEMON, LOG_ERR,			"%s: No server listed for RADIPAD", func);		return;	}	return;} /* end of pool_init () *//************************************************************************* * *	Function: pool_addr * *	Purpose: This is an AATV action function for the *		 PW_ASCEND_RADIPA_ALLOCATE [50] and *		 PW_ASCEND_RADIPA_RELEASE [51] requests. * *************************************************************************/static intpool_addr (authreq, value, afpar)AUTH_REQ       *authreq;int             value;char           *afpar;{	int             cmd;	int             count;	int             how_many;	int             loop_count;	int             result;	ipaddr_t        addr;	UINT4           daemon;	UINT4           ip_address;	UINT4           router_ip_address;	UINT4           z = (UINT4) 0;	ADDRESS_CHUNK   chunks_0[MAX_ADDRESS_CHUNKS];	ADDRESS_CHUNK  *chunks = chunks_0;	ADDRESS_CHUNK  *payload;	VALUE_PAIR     *vp;	char           *user_name;	struct sockaddr_in sin;	sigset_t        signals;	struct sigaction action;	struct sigaction a_save;	static char    *func = "pool_addr";	dprintf(2, (LOG_AUTH, LOG_DEBUG, "%s: entered", func));	/* Set up alarm and signal handler to bail us out if we take too long */	alarm (IP_POOL_TIME); /* Make it pretty long */	memset ((char *) &action, '\0', sizeof (action));	sigemptyset (&signals);			/* Init signal enable mask */	sigaddset (&signals, SIGALRM);  	action.sa_handler = pool_time_out;	/* Set up our timeout handler */	sigaction (SIGALRM, &action, &a_save);	/* Ready to handle it */	sigprocmask (SIG_UNBLOCK, &signals, NULL);	/* Now allow alarm */	/* If one was pending, we just took it. */	timeout = (u_char) 0;	/* Initing now will ignore any pending alarm */	if ((vp = get_vp (authreq->cur_request, PW_NAS_IP_ADDRESS)) == NULL_VP)	{		missing_attribute (authreq, func, PW_NAS_IP_ADDRESS, NULL);		sigaction (SIGALRM, &a_save, NULL);	/* Restore state. */		return EV_NAK;	}	router_ip_address = vp->lvalue;	if (authreq->code == PW_ASCEND_RADIPA_ALLOCATE)	{		if ((vp = get_vp (authreq->cur_request,					PW_USER_NAME)) == NULL_VP)		{			missing_attribute (authreq, func, PW_USER_NAME, NULL);			sigaction (SIGALRM, &a_save, NULL); /* Restore state. */			return EV_NAK;		}		user_name = vp->strvalue;	/* name of the router */		count = parse_pool (user_name, &chunks);		if (count == 0)		{			dprintf(2, (LOG_AUTH, LOG_DEBUG,				"zero address chunks for %s", func, user_name));			avpair_add (&authreq->cur_request,						PW_FRAMED_IP_ADDRESS, &z, 0);			sigaction (SIGALRM, &a_save, NULL); /* Restore state. */			return EV_ACK;		}	}	else /* was PW_ASCEND_RADIPA_RELEASE */	{		if ((vp = get_vp (authreq->cur_request,					PW_FRAMED_IP_ADDRESS)) == NULL_VP)		{			missing_attribute (authreq, func,						PW_FRAMED_IP_ADDRESS, NULL);			sigaction (SIGALRM, &a_save, NULL); /* Restore state. */			return EV_NAK;		}		ip_address = vp->lvalue;	/* address to release */	}	/* This assumes the users file has been read into memory. */	if ((daemon = parse_hosts ()) == INADDR_ANY)	{		logit (LOG_DAEMON, LOG_ERR,			"%s: No server listed for RADIPAD", func);		sigaction (SIGALRM, &a_save, NULL);	/* Restore state. */		return EV_NAK;	}	if (authreq->code == PW_ASCEND_RADIPA_ALLOCATE)	{		cmd = RADIPA_ALLOCATE;		addr = INADDR_NONE;		payload = chunks;		how_many = count;	}	else /* was PW_ASCEND_RADIPA_RELEASE */	{		cmd = RADIPA_RELEASE;		addr = ip_address;		payload = (ADDRESS_CHUNK *) NULL;		how_many = 0;	} 	loop_count = 0;	do	{		if (ip_address_send (cmd, authreq, router_ip_address,						addr, payload, how_many) < 0)		{			result = try_connect (daemon);			switch (result)			{			    case 1:		/* Address was in use. */				sleep (2);				loop_count++;				break;			    case 0:				loop_count = 3;	/* Indicate done with loop. */				break;			    case -1:		/* Some error occurred. */				/* Restore signal state. */				sigaction (SIGALRM, &a_save, NULL);				return EV_NAK;			}			continue;		} 		break;	} while (loop_count < 2);	for (;;) /* Block for RADIPAD packet in this child process. */	{		if (ip_address_recv (daemon, authreq) < 0)		{			sigaction (SIGALRM, &a_save, NULL); /* Restore state. */			return EV_NAK;		}		sigaction (SIGALRM, &a_save, NULL);	/* Restore state. */		return EV_ACK;		/* It's a success! */	}} /* end of pool_addr () *//************************************************************************* * *	Function: pool_cleanup * *	Purpose: Release the socket file descriptor. * *************************************************************************/static voidpool_cleanup (){	static char    *func = "pool_cleanup";	dprintf(2, (LOG_AUTH, LOG_DEBUG, "%s: entered", func));	close (sockfd);	sockfd = -1;	return;} /* end of pool_cleanup () *//************************************************************************* * *	Function: ip_address_send * *	Purpose: Sends IP address pool requests to RADIPAD. * *	Returns: number of bytes sent, or *		 -1, otherwise. * *************************************************************************/static intip_address_send (code, handle, router_address, ipaddr, chunks, count)int             code;void           *handle;UINT4           router_address;ipaddr_t        ipaddr;ADDRESS_CHUNK  *chunks;int             count;{	int             bytes_sent;	int             total_length;	RADIPA_PACKET  *packet;	static char    *func = "ip_address_send";	dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: entered", func));	packet = (RADIPA_PACKET *) send_buffer;	packet->rp_code = (char) code; /* RADIPA_ALLOCATE or RADIPA_RELEASE */	packet->rp_pad = ~0;	packet->rp_count = htons(count);	packet->rp_handle = handle;	packet->rp_router_address = router_address;	packet->rp_ip_address = htonl(ipaddr);	if (code == RADIPA_ALLOCATE)	{

⌨️ 快捷键说明

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