Files
m241Neelima/components/ip_net2-6.9/ipradius/src/ipradius_cmd_radiusc.c
T
2026-07-30 11:19:44 +05:30

1786 lines
57 KiB
C

/*
******************************************************************************
* INTERPEAK EXAMPLE SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipradius_cmd_radiusc.c,v $ $Revision: 1.24.16.6 $
* $Source: /home/interpeak/CVSRoot/ipradius/src/ipradius_cmd_radiusc.c,v $
* $Author: jren $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Lennart Bang <lob@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
#include "ipradius_config.h"
#define IPCOM_SHELL_HISTORY_LENGTH 10
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#define IPCOM_USE_CLIB_PROTO
#include <ipcom_type.h>
#include <ipcom_cstyle.h>
#include <ipcom_clib.h>
#include <ipcom_os.h>
#include <ipcom_err.h>
#include <ipcom_shell.h>
#include <ipcom_syslog.h>
#include <ipcom_getopt.h>
#include <ipcom_strlib.h>
#include <ipcom_file.h>
#include "ipradius.h"
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/* buf & packet size. */
#define IPRADIUS_PKT_SIZE 1472
#define IPRADIUS_BUF_SIZE 1000
/* command return codes. */
#define IPRADIUS_CMD_EXIT -2
#define IPRADIUS_CMD_HELP -3
#define IPRADIUS_CUI_FALSE IP_FALSE
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
typedef enum {
RADIUS_CUI_NOT_INUSE = 0,
RADIUS_REQUEST_CUI,
RADIUS_CUI_INUSE
}RADIUS_CUI_STATE;
RADIUS_CUI_STATE cui_state = RADIUS_CUI_NOT_INUSE;
/*
*===========================================================================
* Variables - Vars
*===========================================================================
* radiusc shell command variable handle.
*/
typedef struct Vars_struct
{
Ip_pid_t pid;
int argc;
char **argv;
Ipcom_getopt opt;
Ipcom_getline *gl;
char *buf;
char *pkt;
Ip_u32 test;
#ifdef IPCOM_USE_INET
Ip_fd fd;
#endif
#ifdef IPCOM_USE_INET6
Ip_fd fd6;
#endif
Ip_u16 serv_type;
Ip_bool valid_user;
union Ip_sockaddr_union server_addr;
union Ip_sockaddr_union server_addr2;
Ip_bool specified, have_ipaddr_n, have_ipaddr2_n, have_secret;
char shared_secret[IPRADIUS_MAX_SECRET_SIZE];
Ip_u32 intsec, intnum, intfound;
Ip_u16 pollnum, pollsec;
Ip_u32 tmosec;
char user[32];
char cui[32];
char pwd[IPRADIUS_MAX_PASSWORD_SIZE]; /* password */
char challenge[16];
Ip_u8 chap_ident;
Ip_u32 pwd_type;
Ip_u32 id;
Ip_bool have_id;
}
Vars;
/*
*===========================================================================
* Command
*===========================================================================
*/
typedef struct Command_struct
{
char *name;
int (*func)(Vars *vars);
}
Command;
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
IP_EXTERN char *ipradius_addr_to_str(union Ip_sockaddr_union *addr);
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
IP_PUBLIC int ipradius_cmd_radiusc(int argc, char **argv);
IP_STATIC int ipradius_cmd_servadd(Vars *vars);
IP_STATIC int ipradius_cmd_servdel(Vars *vars);
IP_STATIC int ipradius_cmd_access(Vars *vars);
IP_STATIC int ipradius_cmd_accounting(Vars *vars);
IP_STATIC int ipradius_cmd_accessmib(Vars *vars);
IP_STATIC int ipradius_cmd_acctmib(Vars *vars);
IP_STATIC int ipradius_cmd_close(Vars *vars);
IP_STATIC int ipradius_cmd_open(Vars *vars);
IP_STATIC int ipradius_cmd_exit(Vars *vars);
IP_STATIC int ipradius_cmd_help(Vars *vars);
IP_STATIC int ipradius_example_recv(Vars *vars, Ip_bool flush);
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
#ifndef IPRADIUS_ENABLE_REENTRANT
IP_STATIC int ipradius_radiusc_num_running;
#endif
/*
****************************************************************************
* 9 LOCAL FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipradius_errname
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC char *
ipradius_errname2(Ip_err err)
{
switch(err)
{
/* IPRADIUS */
case IPRADIUS_ERR_UNSUPPORTED_TAG:
return "UNSUPPORTED_TAG";
case IPRADIUS_ERR_UNKNOWN_PACKET_CODE:
return "UNKNOWN_PACKET_CODE";
case IPRADIUS_ERR_TOO_MANY_OUTSTANDING_REQUESTS:
return "TOO_MANY_OUTSTANDING_REQUESTS";
case IPRADIUS_ERR_INVAL_PKT_ID:
return "INVAL_PKT_ID";
case IPRADIUS_ERR_BAD_AUTHENTICATION:
return "BAD_AUTHENTICATION";
case IPRADIUS_ERR_BAD_ATTRIBUTE:
return "BAD_ATTRIBUTE";
case IPRADIUS_ERR_NO_SESSION:
return "NO_SESSION";
case IPRADIUS_ERR_SECRET_TOO_LONG:
return "SECRET_TOO_LONG";
case IPRADIUS_ERR_INVAL_PWD_LEN:
return "INVAL_PWD_LEN";
case IPRADIUS_ERR_NO_SERVER_RESPONSE:
return "NO_SERVER_RESPONSE";
case IPRADIUS_ERR_INVAL_INTERIM_ACCT_INTERVAL:
return "INVAL_INTERIM_ACCT_INTERVAL";
case IPRADIUS_ERR_SECRET_TOO_SHORT:
return "SECRET_TOO_SHORT";
case IPRADIUS_ERR_MISSING_CHAP_ATTR:
return "MISSING_CHAP_ATTR";
case IPRADIUS_ERR_INVAL_PWD_TYPE:
return "IPRADIUS_ERR_INVAL_PWD_TYPE";
case IPRADIUS_ERR_NO_SERVER:
return "IPRADIUS_ERR_NO_SERVER";
case IPRADIUS_ERR_DISCARDED_PACKET:
return "IPRADIUS_ERR_DISCARDED_PACKET";
case IPRADIUS_ERR_DUPLICATE_INDEX:
return "IPRADIUS_ERR_DUPLICATE_INDEX";
case IPRADIUS_ERR_UNSUPPORTED_PACKET_CODE:
return "IPRADIUS_ERR_UNSUPPORTED_PACKET_CODE";
case IPRADIUS_ERR_CLOSED:
return "IPRADIUS_ERR_CLOSED";
/* DEFAULT */
default:
return ipcom_err_string(err);
}
}
IP_STATIC char *
ipradius_errname(Ip_err err)
{
static char errname[100];
ipcom_snprintf(errname, 100, "error: %s", ipradius_errname2(err));
return (char *)errname;
}
/*
*===========================================================================
* ipradius_example_event_callback
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC Ip_err
ipradius_example_event_callback(int event, Ipradius_request *request,
Ipradius_header *request_packet, Ipradius_header *response_packet,
Ipradius_server *server)
{
Vars *vars;
Ip_u8 *data;
Ip_u32 type;
Ip_err retval;
Ip_u8 flen;
int len;
(void)request_packet;
(void)response_packet;
(void)server;
vars = request->cookie;
switch(event)
{
case IPRADIUS_EVENT_ACCESS_ACCEPT:
vars->valid_user = IP_TRUE;
ip_assert(request->status == IPCOM_SUCCESS);
len = ipcom_sprintf(vars->buf, "<- ipradius_event_access_accept, id = %ld [hdr %d]"IP_LF,
request->unique, (int)response_packet->id);
/* !! check attributes here. */
/* Print attributes. */
for (data = ipradius_attr_get_next(response_packet, IP_NULL);
data != IP_NULL && len < (IPRADIUS_BUF_SIZE - 25);
data = ipradius_attr_get_next(response_packet, data))
{
if (data[0] == IPRADIUS_ATTR_CUI) /* CUI */
{
len += ipcom_sprintf(vars->buf + len, "attr #%3d len %3d cui-value %s"IP_LF, data[0], data[1], (char *)&data[2]);
} else
{
len += ipcom_sprintf(vars->buf + len, "attr #%3d len %3d"IP_LF, data[0], data[1]);
}
}
ipcom_printf(vars->buf);
break;
case IPRADIUS_EVENT_ACCESS_REJECT:
ip_assert(request->status == IPCOM_ERR_FAILED);
ipcom_printf("<- ipradius_event_access_reject, id = %ld [hdr %d]"IP_LF,
request->unique, (int)response_packet->id);
break;
case IPRADIUS_EVENT_ACCOUNTING_RESPONSE:
ip_assert(request->status == IPCOM_SUCCESS);
len = ipcom_sprintf(vars->buf, "<- ipradius_event_accounting_response, id = %ld [hdr %d]"IP_LF,
request->unique, (int)response_packet->id);
vars->intfound++;
for (data = ipradius_attr_get_next(response_packet, IP_NULL);
data != IP_NULL && len < (IPRADIUS_BUF_SIZE - 25);
data = ipradius_attr_get_next(response_packet, data))
{
len += ipcom_sprintf(vars->buf + len, "attr #%3d len %3d"IP_LF, data[0], data[1]);
}
ipcom_printf(vars->buf);
break;
case IPRADIUS_EVENT_ACCOUNTING_REQUEST:
if (vars->pid == ipcom_getpid())
ipcom_printf("<- ipradius_event_accounting_request, id = %ld [hdr %d]"IP_LF,
request->unique, (int)request_packet->id);
/* Add type specific accounting variables. */
retval = ipradius_attr_get_u32(request_packet, IPRADIUS_ATTR_Acct_Status_Type, &type);
if (retval == IPCOM_SUCCESS)
{
switch(type)
{
case IPRADIUS_ACCT_Start:
if (*vars->user && ipradius_attr_find(request_packet, IPRADIUS_ATTR_User_Name, &flen) == IP_NULL)
(void)ipradius_attr_add_array(request_packet, IPRADIUS_ATTR_User_Name, (Ip_u8*)vars->user,
(Ip_u8)ipcom_strlen(vars->user));
break;
case IPRADIUS_ACCT_Stop:
break;
default:
break;
}
}
/* Add general missing accounting attributes. */
if (ipradius_attr_find(request_packet, IPRADIUS_ATTR_Acct_Session_Id, &flen) == IP_NULL)
(void)ipradius_attr_add_u32(request_packet, IPRADIUS_ATTR_Acct_Session_Id, request->unique);
break;
case IPRADIUS_EVENT_ACCESS_TIMEOUT:
if (vars->pid == ipcom_getpid())
ipcom_printf("<- ipradius_event_access_timeout, id = %ld"IP_LF, request->unique);
break;
case IPRADIUS_EVENT_ACCESS_CANCELLED:
if (vars->pid == ipcom_getpid())
ipcom_printf("<- ipradius_event_access_cancelled, id = %ld"IP_LF, request->unique);
break;
case IPRADIUS_EVENT_ACCOUNTING_TIMEOUT:
if (vars->pid == ipcom_getpid())
ipcom_printf("<- ipradius_event_accounting_timeout, id = %ld"IP_LF, request->unique);
break;
case IPRADIUS_EVENT_ACCOUNTING_CANCELLED:
if (vars->pid == ipcom_getpid())
ipcom_printf("<- ipradius_event_accounting_cancelled, id = %ld"IP_LF, request->unique);
break;
default:
IP_PANIC();
break;
}
return IPCOM_SUCCESS;
}
/*
*===========================================================================
* ipradius_run_command
*===========================================================================
*/
IP_STATIC int
ipradius_run_command(char *name, Vars *vars)
{
int i;
static const Command commands[] =
{
/* name, function */
{ "exit", ipradius_cmd_exit },
{ "quit", ipradius_cmd_exit },
{ "help", ipradius_cmd_help },
{ "usage", ipradius_cmd_help },
{ "?", ipradius_cmd_help },
{ "servadd", ipradius_cmd_servadd },
{ "servdel", ipradius_cmd_servdel },
{ "access", ipradius_cmd_access },
{ "accounting",ipradius_cmd_accounting },
{ "accessmib", ipradius_cmd_accessmib },
{ "acctmib", ipradius_cmd_acctmib },
{ "close", ipradius_cmd_close },
{ "open", ipradius_cmd_open },
{ 0, 0}
};
for (i = 0; commands[i].name; i++)
if (ipcom_strcmp(name, commands[i].name) == 0)
{
return commands[i].func(vars);
}
ipcom_printf("unknown command '%s':"IP_LF, name);
return -1;
}
/*
*===========================================================================
* ipradius_cmd_exit
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC int
ipradius_cmd_exit(Vars *vars)
{
(void)vars;
return IPRADIUS_CMD_EXIT;
}
/*
*===========================================================================
* ipradius_cmd_help
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC int
ipradius_cmd_help(Vars *vars)
{
(void)vars;
return IPRADIUS_CMD_HELP;
}
/*
*===========================================================================
* ipradius_cmd_servadd
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC int
ipradius_cmd_servadd(Vars *vars)
{
Ipradius_server server;
int retval;
if (vars->have_ipaddr_n == IP_FALSE)
{
ipcom_printf("missing modifier '-servip'"IP_LF);
return -1;
}
if (vars->server_addr.sin.sin_port == 0)
{
ipcom_printf("missing modifier '-port'"IP_LF);
return -1;
}
if (vars->have_secret == IP_FALSE)
{
ipcom_printf("missing modifier '-secret'"IP_LF);
return -1;
}
/* Add a RADIUS server. */
ipcom_memset(&server, 0, sizeof(Ipradius_server));
server.index = 0; /* let ipradius choose server index. */
ipcom_memcpy(&server.server_addr, &vars->server_addr, sizeof(union Ip_sockaddr_union));
server.server_type = vars->serv_type;
server.pollnum = vars->pollnum;
server.pollsec = vars->pollsec;
ipcom_strcpy((char *)server.shared_secret, vars->shared_secret);
server.shared_secret_len = (Ip_u32)ipcom_strlen((char *)server.shared_secret);
#ifdef IPCOM_USE_INET6
if (server.server_addr.sa.sa_family == IP_AF_INET6)
{
server.server_addr.sin6.sin6_flowinfo =0 ;
}
#endif
retval = ipradius_server_add(&server); /*lint -e429 */
if (retval != IPCOM_SUCCESS)
{
ipcom_printf("failed to add RADIUS server : '%s'"IP_LF, ipradius_errname(retval));
return -1;
}
else
ipcom_printf("added radius server entry (%s)"IP_LF, ipradius_addr_to_str(&server.server_addr));
return 0;
}
/*
*===========================================================================
* ipradius_cmd_servdel
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC int
ipradius_cmd_servdel(Vars *vars)
{
int retval;
Ipradius_server server;
if (vars->have_ipaddr_n == IP_FALSE)
{
ipcom_printf("missing modifier '-servip'"IP_LF);
return -1;
}
if (vars->server_addr.sin.sin_port == 0)
{
ipcom_printf("missing modifier '-port'"IP_LF);
return -1;
}
ipcom_memset(&server, 0, sizeof(Ipradius_server));
ipcom_memcpy(&server.server_addr, &vars->server_addr, sizeof(union Ip_sockaddr_union));
server.server_type = vars->serv_type;
server.pollnum = vars->pollnum;
server.pollsec = vars->pollsec;
retval = ipradius_server_remove(&server);
if (retval != IPCOM_SUCCESS)
{
ipcom_printf("failed to remove RADIUS server : '%s'"IP_LF, ipradius_errname(retval));
return -1;
}
else
ipcom_printf("removed radius server entry"IP_LF);
return 0;
}
/*
*===========================================================================
* ipradius_cmd_access
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC int
ipradius_cmd_access(Vars *vars)
{
int retval;
Ipradius_request request;
Ipradius_header *packet;
Ip_u8 errattr;
packet = ipradius_access_request_pkt_malloc();
if (packet == IP_NULL)
{
ipcom_printf("error - out of heap memory (or closed)"IP_LF);
return -1;
}
if (!*vars->user)
{
ipcom_printf("missing modifier '-user'"IP_LF);
if (ipradius_access_request_pkt_free(packet))
ipcom_printf("failed to free radius pkt"IP_LF);
return -1;
}
if (!*vars->pwd && vars->pwd_type != IPRADIUS_No_Password)
{
ipcom_printf("missing modifier '-pwd'"IP_LF);
if (ipradius_access_request_pkt_free(packet))
ipcom_printf("failed to free radius pkt"IP_LF);
return -1;
}
if (((int)*vars->cui != IPRADIUS_CUI_FALSE) && (ipcom_strcmp(vars->cui, "none") == 0))
cui_state = RADIUS_REQUEST_CUI;
if (((int)*vars->cui != IPRADIUS_CUI_FALSE) && (ipcom_strcmp(vars->cui, "none") != 0))
cui_state = RADIUS_CUI_INUSE;
/***** Add attributes here! *****/
(void)ipradius_attr_add_array(packet, IPRADIUS_ATTR_User_Name, (Ip_u8*)vars->user, (Ip_u8)ipcom_strlen(vars->user));
#ifdef IPTESTENGINE
{
char *user;
Ip_u8 len;
user = (char *)ipradius_attr_get_array(packet, IPRADIUS_ATTR_User_Name, &len);
if(ipcom_memcmp(vars->user, user, ipcom_strlen(vars->user)))
{
ipcom_printf("failed to get attribute value"IP_LF);
if (ipradius_access_request_pkt_free(packet))
ipcom_printf("failed to free radius pkt"IP_LF);
return -1;
}
}
#endif
if (cui_state == RADIUS_REQUEST_CUI)
{
*vars->cui = '\0';
ipcom_printf(" adding none cui\n");
(void)ipradius_attr_add_array(packet, IPRADIUS_ATTR_CUI, (Ip_u8*)vars->cui, (Ip_u8)ipcom_strlen(vars->cui));
} else if (cui_state == RADIUS_CUI_INUSE)
{
ipcom_printf(" adding cui\n");
(void)ipradius_attr_add_array(packet, IPRADIUS_ATTR_CUI, (Ip_u8*)vars->cui, (Ip_u8)ipcom_strlen(vars->cui));
}
if (vars->pwd_type == IPRADIUS_CHAP_Password)
{
(void)ipradius_attr_add_array(packet, IPRADIUS_ATTR_CHAP_Challenge, (Ip_u8*)vars->challenge, 16);
}
#ifdef IPTESTENGINE
{
Ip_u32 data;
(void)ipradius_attr_add_u32(packet, IPRADIUS_ATTR_Tunnel_Medium_Type, 0);
(void)ipradius_attr_change_u32(packet, IPRADIUS_ATTR_Tunnel_Medium_Type, IPRADIUS_TUNNEL_MEDIUM_TYPE_IPV4);
(void)ipradius_attr_get_u32(packet, IPRADIUS_ATTR_Tunnel_Medium_Type, &data);
if (data != IPRADIUS_TUNNEL_MEDIUM_TYPE_IPV4)
{
ipcom_printf("failed to chage attribute value"IP_LF);
if (ipradius_access_request_pkt_free(packet))
ipcom_printf("failed to free radius pkt"IP_LF);
return -1;
}
}
#else
(void)ipradius_attr_add_u32(packet, IPRADIUS_ATTR_Tunnel_Medium_Type, IPRADIUS_TUNNEL_MEDIUM_TYPE_IPV4);
#endif
/***** Fill in request structure and send access request. *****/
ipcom_memset(&request, 0, sizeof(Ipradius_request));
request.cookie = vars;
request.unique = vars->id;
request.pwd_type = vars->pwd_type;
ipcom_strcpy(request.pwd, vars->pwd);
request.pwd_len = (Ip_u32)ipcom_strlen(request.pwd);
request.chap_ident = vars->chap_ident;
/* Set RADIUS socket descriptor and event callback. */
#ifdef IPCOM_USE_INET
request.fd = vars->fd;
#endif
#ifdef IPCOM_USE_INET6
request.fd6 = vars->fd6;
#endif
request.event_callback = ipradius_example_event_callback;
/* IP address or port specified, set a desired server. */
if (vars->specified == IP_TRUE)
{
request.num_servers = 1;
ipcom_memcpy(&request.serv_list[0].server_addr, &vars->server_addr, sizeof(union Ip_sockaddr_union));
request.serv_list[0].server_type = vars->serv_type;
request.serv_list[0].pollnum = vars->pollnum;
request.serv_list[0].pollsec = vars->pollsec;
if (vars->have_ipaddr2_n)
{
request.num_servers++;
ipcom_memcpy(&request.serv_list[1].server_addr, &vars->server_addr2, sizeof(union Ip_sockaddr_union));
request.serv_list[1].server_type = vars->serv_type;
request.serv_list[1].pollnum = vars->pollnum;
request.serv_list[1].pollsec = vars->pollsec;
}
}
else
request.num_servers = 0;
vars->valid_user = IP_FALSE;
#ifdef IPTESTENGINE
{
Ip_u32 attemps;
if (ipradius_get_numattempts(packet, &attemps) || attemps
|| ipradius_check_request(request.unique))
{
ipcom_printf("failed to get number of attempts or failed to check request"IP_LF);
if (ipradius_access_request_pkt_free(packet))
ipcom_printf("failed to free radius pkt"IP_LF);
return -1;
}
}
#endif
retval = ipradius_access_request(packet, &request, &errattr);
if (retval != IPCOM_SUCCESS)
{
ipcom_printf("radius access request failed : '%s' (attr=%d)"IP_LF, ipradius_errname(retval), errattr);
return -1;
}
else
{
if (cui_state == RADIUS_REQUEST_CUI)
ipcom_printf("sending access request(s) with none cui..."IP_LF);
else if (cui_state == RADIUS_CUI_INUSE)
ipcom_printf("sending access request(s) wit cui..."IP_LF);
else
ipcom_printf("sending access request(s)..."IP_LF);
/* Wait for the 'Access' reply. */
if (ipradius_example_recv(vars, IP_FALSE) == 0)
ipcom_printf("User '%s' access: %s"IP_LF, vars->user, vars->valid_user ? "valid" : "invalid");
cui_state = RADIUS_CUI_NOT_INUSE;
}
return 1;
}
/*
*===========================================================================
* ipradius_cmd_accounting
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC int
ipradius_cmd_accounting(Vars *vars)
{
Ip_err retval;
Ipradius_request request;
if (!*vars->user)
{
ipcom_printf("missing modifier '-user'"IP_LF);
return -1;
}
if (vars->intnum != 0 && vars->intsec == 0)
{
ipcom_printf("missing/illegal modifier '-intsec' (-intnum != 0 requires intsec != 0)"IP_LF);
return -1;
}
if (vars->have_id == IP_FALSE)
{
ipcom_printf("missing modifier '-id'"IP_LF);
return -1;
}
ipcom_memset(&request,0,sizeof(Ipradius_request));
request.cookie = vars;
request.unique = vars->id;
request.pwd_type = vars->pwd_type;
ipcom_strcpy(request.pwd, vars->pwd);
request.pwd_len = (Ip_u32)ipcom_strlen(request.pwd);
request.chap_ident = vars->chap_ident;
/* Set RADIUS socket descriptor and event callback. */
#ifdef IPCOM_USE_INET
request.fd = vars->fd;
#endif
#ifdef IPCOM_USE_INET6
request.fd6 = vars->fd6;
#endif
request.event_callback = ipradius_example_event_callback;
/* IP address or port specified, set a desired server. */
if (vars->specified == IP_TRUE)
{
request.num_servers = 1;
ipcom_memcpy(&request.serv_list[0].server_addr, &vars->server_addr, sizeof(union Ip_sockaddr_union));
request.serv_list[0].server_type = vars->serv_type;
request.serv_list[0].pollnum = vars->pollnum;
request.serv_list[0].pollsec = vars->pollsec;
if (vars->have_ipaddr2_n)
{
request.num_servers++;
ipcom_memcpy(&request.serv_list[1].server_addr, &vars->server_addr2, sizeof(union Ip_sockaddr_union));
request.serv_list[1].server_type = vars->serv_type;
request.serv_list[1].pollnum = vars->pollnum;
request.serv_list[1].pollsec = vars->pollsec;
}
}
else
request.num_servers = 0;
/* Flush unread packets. */
(void)ipradius_example_recv(vars, IP_TRUE);
/* Start the accounting. */
ipcom_printf(IP_LF"starting accounting for id = %ld"IP_LF, vars->id);
retval = ipradius_accounting_session_start(&request, vars->intnum ? vars->intsec : 0);
if (retval != IPCOM_SUCCESS)
{
ipcom_printf("radius accounting start failed : '%s'"IP_LF, ipradius_errname(retval));
return -1;
}
/* Wait for the 'Start' reply. */
if (ipradius_example_recv(vars, IP_FALSE) == -1)
return -1;
ipcom_printf("started accounting for id = %ld"IP_LF, vars->id);
/* Sleep two seconds. */
(void)ipcom_sleep(2);
/* Wait for the interim 'Update' replies. */
for (vars->intfound = 0; vars->intfound < vars->intnum; )
{
ipcom_printf(IP_LF);
(void)ipcom_sleep(IP_MAX(vars->intsec,1));
(void)ipradius_example_recv(vars, IP_FALSE);
}
/* Stop the accounting. */
ipcom_printf(IP_LF"stopping accounting for id = %ld"IP_LF, vars->id);
retval = ipradius_accounting_session_stop(vars->id, 1 /* User Request */);
if (retval != IPCOM_SUCCESS)
{
ipcom_printf(IP_LF"radius accounting stop failed : '%s'"IP_LF, ipradius_errname(retval));
return -1;
}
/* Wait for the 'Stop' reply. */
if (ipradius_example_recv(vars, IP_FALSE) == 0)
ipcom_printf("stopped accounting for id = %ld"IP_LF, vars->id);
else
ipcom_printf("failed to stop accounting for id = %ld"IP_LF, vars->id);
return 1;
}
/*
*===========================================================================
* ipradius_cmd_accessmib
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC int
ipradius_cmd_accessmib(Vars *vars)
{
Ip_tag globctrl[5];
Ip_tag servctrl[33]; /* 14 tags + their values + 1 end tag +4 bytes addr = 33*/
Ipradius_server server;
int i, retval;
char str[64];
(void)vars;
/* Clean server IP and port so they do not match (use only index) */
ipcom_memset(&server, 0, sizeof(Ipradius_server));
/* Get RFC2618 2 scalars. */
globctrl[0] = IPRADIUS_CTRLT_GET_AuthInvalidServerAddresses;
globctrl[2] = IPRADIUS_CTRLT_GET_AuthIdentifier;
globctrl[4] = IP_TAG_END;
retval = ipradius_ctrl(globctrl);
if (retval != IPCOM_SUCCESS)
{
ipcom_printf("radiusc accessmib - #1 ipradius_ctrl() failed : '%s'"IP_LF, ipradius_errname(retval));
return -1;
}
ipcom_printf("RFC 2618 - Radius Authentication Client MIB:"IP_LF
"-------------------------------------------"IP_LF
"radiusAuthClientInvalidServerAddresses = %ld"IP_LF
"radiusAuthClientIdentifier = %s"IP_LF, (Ip_u32)globctrl[1], (char *)globctrl[3]);
/* Get server table by use of NEXT entry */
globctrl[0] = IPRADIUS_CTRLT_GET_NEXT_SERVER;
globctrl[1] = 0; /* index 0 -> indicates first get-next */
globctrl[2] = IP_TAG_END;
/* prepare servctrl used in ipradius_server_ctrl() function to get server variables. */
servctrl[0] = IPRADIUS_SCTRLT_GET_AuthServerAddress;
servctrl[6] = IPRADIUS_SCTRLT_GET_AuthServerPortNumber;
servctrl[8] = IPRADIUS_SCTRLT_GET_AuthRoundTripTime;
servctrl[10] = IPRADIUS_SCTRLT_GET_AuthAccessRequests;
servctrl[12] = IPRADIUS_SCTRLT_GET_AuthAccessRetransmissions;
servctrl[14] = IPRADIUS_SCTRLT_GET_AuthAccessAccepts;
servctrl[16] = IPRADIUS_SCTRLT_GET_AuthAccessRejects;
servctrl[18] = IPRADIUS_SCTRLT_GET_AuthAccessChallenges;
servctrl[20] = IPRADIUS_SCTRLT_GET_AuthMalformedAccessResponses;
servctrl[22] = IPRADIUS_SCTRLT_GET_AuthBadAuthenticators;
servctrl[24] = IPRADIUS_SCTRLT_GET_AuthPendingRequests;
servctrl[26] = IPRADIUS_SCTRLT_GET_AuthTimeouts;
servctrl[28] = IPRADIUS_SCTRLT_GET_AuthUnknownTypes;
servctrl[30] = IPRADIUS_SCTRLT_GET_AuthPacketsDropped;
servctrl[32] = IP_TAG_END;
/* Loop through server table and print their scalars. */
for (i = 1;;i++)
{
retval = ipradius_ctrl(globctrl);
if (retval != IPCOM_SUCCESS)
{
ipcom_printf("radiusc accessmib - #2 ipradius_ctrl() failed : '%s'"IP_LF, ipradius_errname(retval));
return -1;
}
/* server index is now set in globctrl[1]. if 0, end of server list. */
if (globctrl[1] == 0)
break;
server.index = (Ip_u32)globctrl[1]; /* set index in server struct to get server info. */
server.server_type = IPRADIUS_ACCESS_SERVER;
/* get and print this server table: */
retval = ipradius_server_ctrl(&server, servctrl);
if (retval == IPCOM_ERR_NOT_FOUND)
continue;
if (retval != IPCOM_SUCCESS)
{
ipcom_printf("radiusc accessmib - ipradius_server_ctrl() failed : '%s'"IP_LF, ipradius_errname(retval));
return -1;
}
#ifdef IPCOM_USE_INET
if(servctrl[1] == IP_AF_INET)
{
ipcom_inet_ntop(IP_AF_INET, &(servctrl[2]), str, sizeof(str)) ;
}
#endif
#ifdef IPCOM_USE_INET6
if(servctrl[1] == IP_AF_INET6)
{
ipcom_inet_ntop(IP_AF_INET6, &(servctrl[2]), str, sizeof(str)) ;
}
#endif
ipcom_printf(IP_LF"Server #%d:"IP_LF
"radiusAuthServerIndex = %ld"IP_LF
"radiusAuthServerAddress = %s"IP_LF
"radiusAuthClientServerPortNumber = %d"IP_LF
"radiusAuthClientRoundTripTime = %ld"IP_LF
"radiusAuthClientAccessRequests = %ld"IP_LF
"radiusAuthClientAccessRetransmissions = %ld"IP_LF
"radiusAuthClientAccessAccepts = %ld"IP_LF
, i
, server.index
, str
, IP_SWAP16(((Ip_u16)servctrl[7]))
, servctrl[9]
, servctrl[11]
, servctrl[13]
, servctrl[15]);
ipcom_printf("radiusAuthClientAccessRejects = %ld"IP_LF
"radiusAuthClientAccessChallenges = %ld"IP_LF
"radiusAuthClientMalformedAccessResponses = %ld"IP_LF
"radiusAuthClientBadAuthenticators = %ld"IP_LF
"radiusAuthClientPendingRequests = %ld"IP_LF
"radiusAuthClientTimeouts = %ld"IP_LF
"radiusAuthClientUnknownTypes = %ld"IP_LF
"radiusAuthClientPacketsDropped = %ld"IP_LF
, servctrl[17]
, servctrl[19]
, servctrl[21]
, servctrl[23]
, servctrl[25]
, servctrl[27]
, servctrl[29]
, servctrl[31]);
}
return 0;
}
/*
*===========================================================================
* ipradius_cmd_acctmib
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC int
ipradius_cmd_acctmib(Vars *vars)
{
Ip_tag globctrl[5];
Ip_tag servctrl[31]; /* 13 tags + their values + 1 end tag +4 bytes addr= 31 */
Ipradius_server server;
int i, retval;
char str[64];
(void)vars;
/* Clean server IP and port so they do not match (use only index) */
ipcom_memset(&server, 0, sizeof(Ipradius_server));
/* Get RFC2620 2 scalars. */
globctrl[0] = IPRADIUS_CTRLT_GET_AccInvalidServerAddresses;
globctrl[2] = IPRADIUS_CTRLT_GET_AccIdentifier;
globctrl[4] = IP_TAG_END;
retval = ipradius_ctrl(globctrl);
if (retval != IPCOM_SUCCESS)
{
ipcom_printf("radiusc acctmib - #1 ipradius_ctrl() failed : '%s'"IP_LF, ipradius_errname(retval));
return -1;
}
ipcom_printf("RFC 2620 - Radius Accounting Client MIB:"IP_LF
"--------------------------------------------"IP_LF
"radiusAccClientInvalidServerAddresses = %ld"IP_LF
"radiusAccClientIdentifier = %s"IP_LF, (Ip_u32)globctrl[1], (char *)globctrl[3]);
/* Get server table by use of NEXT entry */
globctrl[0] = IPRADIUS_CTRLT_GET_NEXT_SERVER;
globctrl[1] = 0; /* index 0 -> indicates first get-next */
globctrl[2] = IP_TAG_END;
/* prepare servctrl used in ipradius_server_ctrl() function to get server variables. */
servctrl[0] = IPRADIUS_SCTRLT_GET_AccServerAddress;
servctrl[6] = IPRADIUS_SCTRLT_GET_AccServerPortNumber;
servctrl[8] = IPRADIUS_SCTRLT_GET_AccRoundTripTime;
servctrl[10] = IPRADIUS_SCTRLT_GET_AccRequests;
servctrl[12] = IPRADIUS_SCTRLT_GET_AccRetransmissions;
servctrl[14] = IPRADIUS_SCTRLT_GET_AccResponses;
servctrl[16] = IPRADIUS_SCTRLT_GET_AccMalformedResponses;
servctrl[18] = IPRADIUS_SCTRLT_GET_AccBadAuthenticators;
servctrl[20] = IPRADIUS_SCTRLT_GET_AccPendingRequests;
servctrl[22] = IPRADIUS_SCTRLT_GET_AccTimeouts;
servctrl[24] = IPRADIUS_SCTRLT_GET_AccUnknownTypes;
servctrl[26] = IPRADIUS_SCTRLT_GET_AccPacketsDropped;
servctrl[28] = IP_TAG_END;
/* Loop through server table and print their scalars. */
for (i = 1;;i++)
{
retval = ipradius_ctrl(globctrl);
if (retval != IPCOM_SUCCESS)
{
ipcom_printf("radiusc acctmib - #2 ipradius_ctrl() failed : '%s'"IP_LF, ipradius_errname(retval));
return -1;
}
/* server index is now set in globctrl[1]. if 0, end of server list. */
if (globctrl[1] == 0)
break;
server.index = (Ip_u32)globctrl[1]; /* set index in server struct to get server info. */
server.server_type = IPRADIUS_ACCOUNTING_SERVER;
/* get and print this server table: */
retval = ipradius_server_ctrl(&server, servctrl);
if (retval == IPCOM_ERR_NOT_FOUND)
continue;
if (retval != IPCOM_SUCCESS)
{
ipcom_printf("radiusc acctmib - ipradius_server_ctrl() failed : '%s'"IP_LF, ipradius_errname(retval));
return -1;
}
#ifdef IPCOM_USE_INET
if(servctrl[1] == IP_AF_INET)
{
ipcom_inet_ntop(IP_AF_INET, &(servctrl[2]), str, sizeof(str)) ;
}
#endif
#ifdef IPCOM_USE_INET6
if(servctrl[1] == IP_AF_INET6)
{
ipcom_inet_ntop(IP_AF_INET6, &(servctrl[2]), str, sizeof(str)) ;
}
#endif
ipcom_printf(IP_LF"Server #%d:"IP_LF
"radiusAccServerIndex = %ld"IP_LF
"radiusAccServerAddress = %s"IP_LF
"radiusAccClientServerPortNumber = %d"IP_LF
"radiusAccClientRoundTripTime = %ld"IP_LF
"radiusAccClientRequests = %ld"IP_LF
"radiusAccClientRetransmissions = %ld"IP_LF
"radiusAccClientResponses = %ld"IP_LF
"radiusAccClientMalformedResponses = %ld"IP_LF
"radiusAccClientBadAuthenticators = %ld"IP_LF
"radiusAccClientPendingRequests = %ld"IP_LF
"radiusAccClientTimeouts = %ld"IP_LF
"radiusAccClientUnknownTypes = %ld"IP_LF
"radiusAccClientPacketsDropped = %ld"IP_LF
, i
, server.index
, str
, IP_SWAP16(((Ip_u16)servctrl[7]))
, servctrl[9]
, servctrl[11]
, servctrl[13]
, servctrl[15]
, servctrl[17]
, servctrl[19]
, servctrl[21]
, servctrl[23]
, servctrl[25]
, servctrl[27]
);
}
return 0;
}
/*
*===========================================================================
* ipradius_cmd_close
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC int
ipradius_cmd_close(Vars *vars)
{
int retval;
(void)vars;
retval = ipradius_close();
if (retval != IPCOM_SUCCESS)
{
ipcom_printf("radius close failed : '%s'"IP_LF, ipradius_errname(retval));
return -1;
}
else
ipcom_printf("closed radius"IP_LF);
return 0;
}
/*
*===========================================================================
* ipradius_cmd_open
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
static int
ipradius_cmd_open(Vars *vars)
{
Ipradius_open conf;
Ip_err retval;
(void)vars;
/* Open IPRADIUS */
ipcom_strcpy(conf.ipradius_NAS_Identifier,"Interpeak example NAS");
conf.ipradius_NAS_Identifier_size = (Ip_u32)ipcom_strlen(conf.ipradius_NAS_Identifier);
conf.access_request_attribute_size = IPRADIUS_access_request_attribute_size;
conf.accounting_request_attribute_size = IPRADIUS_accounting_request_attribute_size;
conf.conf[0] = IP_TAG_END;
retval = ipradius_open(&conf);
if (retval != IPCOM_SUCCESS)
{
ipcom_printf("radius open failed : '%s'"IP_LF, ipradius_errname(retval));
return -1;
}
else
ipcom_printf("opened radius"IP_LF);
return 0;
}
/*
*===========================================================================
* ipradius_example_recv
*===========================================================================
* Description:
* Parameters:
* Returns:
*/
IP_STATIC int
ipradius_example_recv(Vars *vars, Ip_bool flush)
{
int maxfd, num, tot = 0;
Ip_fd_set read_set;
struct Ip_timeval tmo;
Ip_fd fd;
again:
IP_FD_ZERO(&read_set);
#ifdef IPCOM_USE_INET
IP_FD_SET(vars->fd, &read_set);
maxfd = (int)vars->fd;
#else
maxfd = -1;
#endif
#ifdef IPCOM_USE_INET6
IP_FD_SET(vars->fd6, &read_set);
maxfd = (int)IP_MAX(vars->fd6, maxfd);
#endif
tmo.tv_usec = 0;
tmo.tv_sec = flush == IP_TRUE ? 0 : vars->tmosec;
num = ipcom_socketselect(maxfd + 1, &read_set, IP_NULL, IP_NULL, &tmo);
if (num < 0)
{
ipcom_printf("ipcom_socketselect() failed, errno = %d"IP_LF, ipcom_errno);
return -1;
}
else if (num == 0)
{
if (flush == IP_FALSE)
ipcom_printf("error: timeout... no valid server reply."IP_LF);
else if (tot > 0)
ipcom_printf("flushed %d packets"IP_LF, tot);
return -1;
}
/* Got a packet waiting... */
else if (num == 1)
{
Ip_err retval;
Ip_ssize_t length;
Ip_socklen_t addrlen;
union Ip_sockaddr_union from_addr;
fd = IP_INVALID_SOCKET;
#ifdef IPCOM_USE_INET
if (IP_FD_ISSET(vars->fd, &read_set))
{
fd = vars->fd;
addrlen = sizeof(struct Ip_sockaddr_in);
}
#endif
#ifdef IPCOM_USE_INET6
if (IP_FD_ISSET(vars->fd6, &read_set))
{
fd = vars->fd6;
addrlen = sizeof(struct Ip_sockaddr_in6);
}
#endif
ip_assert(fd != IP_INVALID_SOCKET);
/* Read the packet. */
length = ipcom_recvfrom(fd, vars->pkt, IPRADIUS_PKT_SIZE, 0, &from_addr.sa, &addrlen);
if (length <= 0)
{
ipcom_printf("ipcom_recvfrom() failed, errno = %d"IP_LF, ipcom_errno);
goto again;
}
if (flush == IP_TRUE)
{
tot++;
goto again;
}
/* Pass packet to RADIUS for input parsing. */
retval = ipradius_read(vars->pkt, (Ip_size_t)length, &from_addr.sa);
if (retval != IPCOM_SUCCESS)
{
ipcom_printf("ipradius_read() failed : '%s'"IP_LF, ipradius_errname(retval));
goto again;
}
/* Valid packet, return. */
return 0;
}
IP_PANIC();
ipcom_printf("ipcom_socketselect() internal error, num = %d"IP_LF, num);
return -1;
}
/*
*===========================================================================
* ipradius_setup
*===========================================================================
* Description:
* Parameters:
* Returns:
*/
IP_STATIC Ip_err
ipradius_setup(Vars *vars)
{
#ifndef IPRADIUS_ENABLE_REENTRANT
ipradius_radiusc_num_running++;
#endif
/* Set default config. */
ipcom_memset(vars, 0, sizeof(Vars));
#ifdef IPCOM_USE_INET
vars->fd = IP_INVALID_SOCKET;
#endif
#ifdef IPCOM_USE_INET6
vars->fd6 = IP_INVALID_SOCKET;
#endif
vars->pid = ipcom_getpid();
vars->server_addr.sin.sin_port = ip_htons(1812);
vars->server_addr2.sin.sin_port = ip_htons(1812);
vars->chap_ident = 1;
vars->pollnum = 3;
vars->pollsec = 3;
vars->intsec = 5;
vars->tmosec = 30;
vars->pwd_type = IPRADIUS_PAP_Password;
vars->serv_type = IPRADIUS_FULL_SERVER;
ipcom_strcpy(vars->challenge, "123456789012345");
vars->buf = ipcom_malloc(IPRADIUS_BUF_SIZE);
if (vars->buf == IP_NULL)
{
ipcom_printf("out of buf memory."IP_LF);
goto badout;
}
vars->pkt = ipcom_malloc(IPRADIUS_PKT_SIZE);
if (vars->pkt == IP_NULL)
{
ipcom_printf("out of pkt memory."IP_LF);
goto badout;
}
vars->gl = ipcom_getline_init(IPCOM_SHELL_HISTORY_LENGTH);
if (vars->gl == IP_NULL)
{
ipcom_printf("out of readline memory."IP_LF);
goto badout;
}
#ifdef IPCOM_USE_INET
/* Get RADIUS client IPv4 UDP socket. */
vars->fd = ipcom_socket(IP_AF_INET, IP_SOCK_DGRAM, 0);
if (vars->fd != IP_INVALID_SOCKET)
{
struct Ip_sockaddr_in addr;
/* Bind socket to a local random port. */
ipcom_memset(&addr, 0, sizeof(addr));
IPCOM_SA_LEN_SET(&addr, sizeof(struct Ip_sockaddr_in));
addr.sin_family = IP_AF_INET;
if (ipcom_bind(vars->fd, (struct Ip_sockaddr *)&addr, sizeof(addr)) < 0)
{
ipcom_printf("failed to bind RADIUS UDP socket, errno = %d"IP_LF, ipcom_errno);
ipcom_socketclose(vars->fd);
vars->fd = IP_INVALID_SOCKET;
}
}
else
ipcom_printf("failed to get RADIUS IPv4 UDP socket, errno = %d"IP_LF, ipcom_errno);
#endif
#ifdef IPCOM_USE_INET6
/* Get RADIUS client IPv6 UDP socket. */
vars->fd6 = ipcom_socket(IP_AF_INET6, IP_SOCK_DGRAM, 0);
if (vars->fd6 != IP_INVALID_SOCKET)
{
struct Ip_sockaddr_in6 addr6;
/* Bind socket to a local random port. */
ipcom_memset(&addr6, 0, sizeof(addr6));
IPCOM_SA_LEN_SET(&addr6, sizeof(struct Ip_sockaddr_in6));
addr6.sin6_family = IP_AF_INET6;
if (ipcom_bind(vars->fd6, (struct Ip_sockaddr *)&addr6, sizeof(addr6)) < 0)
{
ipcom_printf("failed to bind RADIUS IPv6 UDP socket, errno = %d"IP_LF, ipcom_errno);
ipcom_socketclose(vars->fd6);
vars->fd6 = IP_INVALID_SOCKET;
}
}
else
ipcom_printf("failed to get RADIUS IPv6 UDP socket, errno = %d"IP_LF, ipcom_errno);
#endif
return IPCOM_SUCCESS;
badout:
return IPCOM_ERR_FAILED;
}
/*
*===========================================================================
* ipradius_cleanup
*===========================================================================
* Description:
* Parameters:
* Returns:
*/
IP_STATIC void
ipradius_cleanup(Vars *vars)
{
#ifndef IPRADIUS_ENABLE_REENTRANT
ipradius_radiusc_num_running--;
#endif
if (vars->buf != IP_NULL)
ipcom_free(vars->buf);
if (vars->pkt != IP_NULL)
ipcom_free(vars->pkt);
if (vars->argv)
ipcom_free(vars->argv);
if (vars->gl)
ipcom_getline_exit(vars->gl);
#ifdef IPCOM_USE_INET
if (vars->fd != IP_INVALID_SOCKET)
(void)ipcom_socketclose(vars->fd);
#endif
#ifdef IPCOM_USE_INET6
if (vars->fd6 != IP_INVALID_SOCKET)
(void)ipcom_socketclose(vars->fd6);
#endif
}
/*
*===========================================================================
* ipradius_cmd_radiusc
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC int
ipradius_cmd_radiusc(int argc, char **argv)
{
Vars vars;
int c;
Ip_err retval;
static struct Ip_option long_options[] =
{
{"servip", 1, 0, 0},
{"port", 1, 0, 0},
{"secret", 1, 0, 0},
{"id", 1, 0, 0},
{"pwd", 1, 0, 0},
{"pwdtype", 1, 0, 0},
{"user", 1, 0, 0},
{"cui", 1, 0, 0},
{"intsec", 1, 0, 0},
{"servtype", 1, 0, 0},
{"pollnum", 1, 0, 0},
{"pollsec", 1, 0, 0},
{"servip2", 1, 0, 0},
{"tmosec", 1, 0, 0},
{"intnum", 1, 0, 0},
{0, 0, 0, 0}
};
(void)argc;
(void)argv;
#ifndef IPRADIUS_ENABLE_REENTRANT
if (ipradius_radiusc_num_running != 0)
{
ipcom_printf("IPRADIUS not compiled to be reentrant and shell command already in use."IP_LF);
return 1;
}
#endif
/* Open radius client. */
if (ipradius_setup(&vars) != IPCOM_SUCCESS)
goto leave;
/* Command loop. */
for (;;)
{
/* Print prompt. */
(void)ipcom_fflush(ip_stdout);
ipcom_printf("radiusc> ");
(void)ipcom_fflush(ip_stdout);
/* Get command line. */
if (ipcom_getline(IP_INVALID_SOCKET, vars.buf, IPRADIUS_BUF_SIZE, IP_TRUE, vars.gl, 9 /* promptlen */) < 0)
{
ipcom_printf("end of line, aborting."IP_LF);
goto leave;
}
if (!*vars.buf)
continue;
retval = ipcom_parse_argstr(vars.buf, &vars.argc, &vars.argv);
if (retval != IPCOM_SUCCESS)
{
ipcom_printf("argument error."IP_LF);
continue;
}
/* init this request. */
*vars.user = '\0';
*vars.cui = IPRADIUS_CUI_FALSE;
*vars.pwd = '\0';
vars.specified = IP_FALSE;
vars.have_ipaddr_n = IP_FALSE;
vars.have_ipaddr2_n = IP_FALSE;
vars.have_secret = IP_FALSE;
vars.have_id = IP_FALSE;
/* ipcom_getopt() loop. */
ipcom_getopt_clear_r(&vars.opt);
vars.opt.long_only = 1;
vars.opt.long_options = long_options;
while((c = ipcom_getopt_r(vars.argc, vars.argv, "t", &vars.opt)) != -1)
{
switch (c)
{
case 0:
switch(vars.opt.long_index)
{
case 0: /* servip */
#ifdef IPCOM_USE_INET
if (ipcom_inet_pton(IP_AF_INET, vars.opt.optarg, &vars.server_addr.sin.sin_addr) == 1)
{
vars.server_addr.sa.sa_family = IP_AF_INET;
IPCOM_SA_LEN_SET(&vars.server_addr.sa, sizeof(struct Ip_sockaddr_in));
vars.specified = IP_TRUE;
vars.have_ipaddr_n = IP_TRUE;
break;
}
#endif
#ifdef IPCOM_USE_INET6
if (ipcom_inet_pton(IP_AF_INET6, vars.opt.optarg, &vars.server_addr.sin6.sin6_addr) == 1)
{
vars.server_addr.sa.sa_family = IP_AF_INET6;
IPCOM_SA_LEN_SET(&vars.server_addr.sa, sizeof(struct Ip_sockaddr_in6));
vars.specified = IP_TRUE;
vars.have_ipaddr_n = IP_TRUE;
break;
}
#endif
ipcom_printf("invalid server IP address."IP_LF);
goto usage;
case 1: /* port */
if (*vars.opt.optarg < '0' || *vars.opt.optarg > '9')
{
ipcom_printf("server port must be specified by number."IP_LF);
goto usage;
}
vars.server_addr.sin.sin_port = (Ip_u16)ipcom_atoi(vars.opt.optarg);
vars.server_addr.sin.sin_port = ip_htons(vars.server_addr.sin.sin_port);
vars.specified = IP_TRUE;
break;
case 2: /* secret */
if (ipcom_strlen(vars.opt.optarg) < IPRADIUS_MAX_SECRET_SIZE)
{
ipcom_strcpy(vars.shared_secret, vars.opt.optarg);
vars.have_secret = IP_TRUE;
}
break;
case 3: /* id */
if (*vars.opt.optarg < '0' || *vars.opt.optarg > '9')
{
ipcom_printf("id must be specified as a number."IP_LF);
goto usage;
}
vars.id = (Ip_u32)ipcom_atoi(vars.opt.optarg);
vars.have_id = IP_TRUE;
break;
case 4: /* pwd */
if (ipcom_strlen(vars.opt.optarg) < IPRADIUS_MAX_PASSWORD_SIZE)
ipcom_strcpy(vars.pwd, vars.opt.optarg);
break;
case 5: /* pwdtype */
if (*vars.opt.optarg < '0' || *vars.opt.optarg > '2')
{
ipcom_printf( "password type (0 = no, 1 = PAP, 2 = CHAP)."IP_LF);
goto usage;
}
vars.pwd_type = (Ip_u32)ipcom_atoi(vars.opt.optarg);
break;
case 6: /* user */
if (ipcom_strlen(vars.opt.optarg) < 32)
ipcom_strcpy(vars.user, vars.opt.optarg);
break;
case 7: /* cui */
if (ipcom_strlen(vars.opt.optarg) < 32)
ipcom_strcpy(vars.cui, vars.opt.optarg);
break;
case 8: /* intsec */
if (*vars.opt.optarg < '0' || *vars.opt.optarg > '9')
{
ipcom_printf("specify interim accounting interval in seconds."IP_LF);
goto usage;
}
vars.intsec = (Ip_u32)ipcom_atoi(vars.opt.optarg);
break;
case 9: /* servtype */
if (*vars.opt.optarg < '1' || *vars.opt.optarg > '3')
{
ipcom_printf( "server type (1 = access, 2 = account, 3 = full)."IP_LF);
goto usage;
}
vars.serv_type = (Ip_u16)ipcom_atoi(vars.opt.optarg);
break;
case 10: /* pollnum */
if (*vars.opt.optarg < '0' || *vars.opt.optarg > '9')
{
ipcom_printf("specify pollnum as a number."IP_LF);
goto usage;
}
vars.pollnum = (Ip_u16)ipcom_atoi(vars.opt.optarg);
break;
case 11: /* pollsec */
if (*vars.opt.optarg < '0' || *vars.opt.optarg > '9')
{
ipcom_printf("specify pollsec in seconds."IP_LF);
goto usage;
}
vars.pollsec = (Ip_u16)ipcom_atoi(vars.opt.optarg);
break;
case 12: /* servip2 */
#ifdef IPCOM_USE_INET
if (ipcom_inet_pton(IP_AF_INET, vars.opt.optarg, &vars.server_addr2.sin.sin_addr) == 1)
{
vars.server_addr2.sa.sa_family = IP_AF_INET;
IPCOM_SA_LEN_SET(&vars.server_addr2.sa, sizeof(struct Ip_sockaddr_in));
vars.have_ipaddr2_n = IP_TRUE;
break;
}
#endif
#ifdef IPCOM_USE_INET6
if (ipcom_inet_pton(IP_AF_INET6, vars.opt.optarg, &vars.server_addr2.sin6.sin6_addr) == 1)
{
vars.server_addr2.sa.sa_family = IP_AF_INET6;
IPCOM_SA_LEN_SET(&vars.server_addr2.sa, sizeof(struct Ip_sockaddr_in6));
vars.have_ipaddr2_n = IP_TRUE;
break;
}
#endif
ipcom_printf("invalid server2 IP address."IP_LF);
goto usage;
case 13: /* tmosec */
if (*vars.opt.optarg < '0' || *vars.opt.optarg > '9')
{
ipcom_printf("specify tmosec in seconds."IP_LF);
goto usage;
}
vars.tmosec = (Ip_u32)ipcom_atoi(vars.opt.optarg);
break;
case 14: /* intnum */
if (*vars.opt.optarg < '0' || *vars.opt.optarg > '9')
{
ipcom_printf("specify number of interim accounting messagess."IP_LF);
goto usage;
}
vars.intnum = (Ip_u32)ipcom_atoi(vars.opt.optarg);
break;
default:
ipcom_printf ("unknown option %s", long_options[vars.opt.long_index].name);
if (vars.opt.optarg)
ipcom_printf(" with arg %s", vars.opt.optarg);
ipcom_printf(IP_LF);
goto usage;
}
break;
case 't':
vars.test = 1;
ipcom_printf("using testmode"IP_LF);
break;
default:
goto usage;
}
}
/* arg check. */
if (*vars.pwd && vars.pwd_type == IPRADIUS_No_Password)
{
ipcom_printf( " missing modifier '-pwdtype'"IP_LF);
goto usage;
}
/****** Run the command. ******/
/* c = -1 or 0 continue;
c = <count> to receive stuff>
*/
c = ipradius_run_command(vars.argv[0], &vars);
if (c == IPRADIUS_CMD_EXIT)
goto leave;
else if (c == IPRADIUS_CMD_HELP)
goto usage;
/* Next command... */
continue;
usage:
ipcom_printf("Interpeak IPRADIUS radius client command, version 2.4"IP_LF
"Copyright (c) 2000-2005, Interpeak AB <www.interpeak.com>"IP_LF
"usage: <command> [modifier(s)...]"IP_LF
"\tCommands:"IP_LF);
ipcom_printf("\t exit\t\t\t exit radius client command"IP_LF
"\t help\t\t\t help usage"IP_LF
"\t open\t\t\t global open radius client"IP_LF
"\t close\t\t\t global close radius client"IP_LF
"\t servadd\t\t add radius server entry"IP_LF
"\t servdel\t\t delete radius server entry"IP_LF
"\t access\t\t\t send radius access request"IP_LF
"\t accounting\t\t start&stop accounting"IP_LF
"\t accessmib\t\t list access mib (RFC 2618)"IP_LF
"\t acctmib\t\t list accounting mib (RFC 2620)"IP_LF);
ipcom_printf("\tPossible modifiers:"IP_LF
"\t -servip <ip>\t\t radius server IPv4/IPv6 address"IP_LF
"\t -servip2 <ip>\t\t 2nd radius server IPv4/IPv6 address"IP_LF
"\t -port <port>\t\t radius server port (default 1812)"IP_LF
"\t -secret <secret>\t radius server secret"IP_LF
"\t -id <id>\t\t user unique handle (default 0)"IP_LF
"\t -user <name>\t\t user login name"IP_LF
"\t -cui <value>\t\t Chargeable User Identity (none/value)"IP_LF
"\t -pwd <pwd>\t\t user login password"IP_LF);
ipcom_printf("\t -pwdtype <type>\t user password type (1 = PAP, 2 = CHAP)"IP_LF
"\t -intsec <val>\t\t interim accounting interval (default 5 sec)"IP_LF
"\t -intnum <val>\t\t number of interim accounting polls (default 0)"IP_LF
"\t -servtype <type>\t server type (1 = accs, 2 = acct, 3 = full)"IP_LF
"\t -tmosec <sec>\t\t server timeout in seconds (default 30)"IP_LF
"\t -pollnum <num>\t\t number of request tries (default 3)"IP_LF
"\t -pollsec <sec>\t\t number of seconds between each request (default 3)"IP_LF);
continue;
}
leave:
(void)ipcom_fflush(ip_stdout);
ipradius_cleanup(&vars);
return 0;
}
/*
****************************************************************************
* 10 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/