?? pooladdr.c
字號:
/* * * 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 + -