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

📄 radlast.c

📁 This program is a RADIUS RFC-compliant daemon, which is derived from original Livingston Enterprise
💻 C
字号:
/* * Copyright (C) 1999-2002 Francesco P. Lovergine.  * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms stated in the LICENSE file which should be * enclosed with sources. */static char rcsid[] = "$Id: radlast.c,v 1.8.2.1 2004/08/02 18:40:07 flovergine Exp $";# define __MAIN__#include	"yard.h"#include	"global.h"char *progname = NULL;char username[USERNAME_MAX];static int brief = 0;static int extended = 0;static const char *port_type_str(int type){    switch (type) {	case 0:	    return "ASYN";	case 1:	    return "SYNC";	case 2:	    return "ISDN";	case 3:	    return "V120";	case 4:	    return "V110";	default:	    return "UNKN";    }    /* not reached */    return "Unknown";}static const char * proto_type_str(int proto){    switch (proto) {	case P_TELNET:	    return "TELN";	case P_RLOGIN:	    return "RLOG";	case P_TCP_CLEAR:	    return "DATA";	case P_PORTMASTER:	    return "PM";	case P_PPP:	    return "PPP";	case P_SLIP:	    return "SLIP";	case P_CSLIP:	    return "CSLP";	default:	    return "UNK";    }    /* not reached */    return "UNK";}static int parse_width(char **format){  int width=0;  char *endstr;  if ( isdigit(**format) || **format=='+' || **format=='-' )    {    width=(int)strtol(*format,&endstr,10);    *format=endstr;    }  return width;}/* *	Function: parse_formatstr() * 	Purpose: parse a -F format string and outputs as required all *		 radlast fields. * *	Format tokens are: *		%l	Username *		%p	Port ID *		%a	NAS ip address *		%k	Port type *		%c	Client ip address *		%d	Date in ctime format *		%t	Online time in secs *		%T	Online time in HH:MM:SS format *		%i	Input traffic in bytes *		%I	Input traffic in KBytes *		%o	Output traffic in bytes *		%O	Output traffic in KBytes *		%m	Total traffic in bytes *		%M	Total traffic in KBytes *		%s	Input speed in bps (or UNKNOWN) *		%S	Output speed in bps (or UNKNOWN) *		%A	NAS called id (or UNKNOWN) *		%#	Client calling id (or UNKNOWN) *		\n \t \\ \% %% As obvious :-) * *	Tokens can include an integer signed value for alignment with * 	the same sense of printf() format value. */static void parse_formatstr( char *formatstr,radlast rl ){  char port_str[100];  char nas_ip[100];  char client_ip[100];  char fstr[100];  char *str_time;  int  width;  char *ptr;  time_t login_time;  if ( formatstr == NULL ) return;  memset(port_str, 0, sizeof(port_str));  memset(nas_ip, 0, sizeof(nas_ip));  memset(client_ip, 0, sizeof(client_ip));  login_time = rl.ut_time;  str_time = ctime(&login_time); str_time[19] = '\0';  snprintf(port_str, 	   sizeof(port_str),            "%4.4s-%02d",           port_type_str(rl.ent.port_type),           rl.ent.port);  ipaddr2str(nas_ip, sizeof(nas_ip), rl.nas_ip);  ipaddr2str(client_ip, sizeof(client_ip), rl.client_ip);  while ( *formatstr )    {    switch ( *formatstr )      {      case '%':        formatstr++;        width=parse_width(&formatstr);        if (width) snprintf(fstr,sizeof(fstr),"%%%d",width);        else strcpy(fstr,"%");	switch (*formatstr)	  {	  case 'l':	    strcat(fstr,"s"); printf(fstr,rl.login); 	    break;	  case 'p':	    strcat(fstr,"s"); printf(fstr,port_str); 	    break;	  case 'a':	    strcat(fstr,"s"); printf(fstr,nas_ip); 	    break;	  case 'k':	    strcat(fstr,"s"); printf(fstr,proto_type_str(rl.ent.proto)); 	    break;	  case 'c':	    strcat(fstr,"s"); printf(fstr,client_ip); 	    break;	  case 'd':	    strcat(fstr,"s"); printf(fstr,str_time); 	    break;	  case 't':	    strcat(fstr,"ld"); printf(fstr,rl.length); 	    break;	  case 'T':	    ptr=fstr+50;	    snprintf(ptr,sizeof(fstr)/2,"%dh:%dm:%ds",		   (int)(rl.length/3600),                   (int)((rl.length%3600)/60),                   (int)((rl.length%3600)%60)); 	    strcat(fstr,"s");	    printf(fstr,ptr);	    break;	  case 'i':	    strcat(fstr,"ld"); printf(fstr,rl.inb); 	    break;	  case 'I':	    strcat(fstr,"ldKB"); printf(fstr,rl.inb/1024); 	    break;	  case 'o':	    strcat(fstr,"ld"); printf(fstr,rl.outb); 	    break;	  case 'O':	    strcat(fstr,"ldKB"); printf(fstr,rl.outb/1024); 	    break;	  case 'm':	    strcat(fstr,"ld"); printf(fstr,rl.outb+rl.inb); 	    break;	  case 'M':	    strcat(fstr,"ldKB"); printf(fstr,(rl.outb+rl.inb)/1024); 	    break;	  case 's':	    if (rl.rxrate) {	      strcat(fstr,"d"); printf(fstr,rl.rxrate); 	    }	    else {	      strcat(fstr,"s"); printf(fstr,"NONE");	    }	    break;	  case 'S':	    if (rl.txrate) {	      strcat(fstr,"d"); printf(fstr,rl.txrate); 	    }	    else {	      strcat(fstr,"s"); printf(fstr,"NONE");	    }	    break;	  case 'A':	    strcat(fstr,"s"); 	    printf(fstr,strlen(rl.calledid)?rl.calledid:"NONE"); 	    break;	  case '#':	    strcat(fstr,"s"); 	    printf(fstr,strlen(rl.callingid)?rl.callingid:"NONE"); 	    break;	  case '%':	    putchar('%');	  default:	    break;	  }        break;      case '\\':        formatstr++;        switch(*formatstr)	  {	  case 'n':	    printf("\n");	    break;	  case 't':	    printf("\t");	    break;	  case 'r':	    printf("\r");	    break;	  case '\\':	  default:	    printf("\\");	    break;	  }        break;      default:	putchar(*formatstr);	break;      }    formatstr++;    }}/* *	Function: parse_header() * 	Purpose: parse a -H header string  * *	Format tokens are: *		\n \t \r \\ As obvious :-) */static void parse_header( char *header ){   while (*header) {      switch (*header) {      case '\\':        header++;        switch(*header)	  {	  case 'n':	    printf("\n");	    break;	  case 't':	    printf("\t");	    break;	  case 'r':	    printf("\r");	    break;	  case '\\':	  default:	    printf("\\");	    break;	  }        break;      default:	putchar(*header);	break;      }    header++;    }}static void print_entry(radlast rad_last){  if (extended)    if (brief) parse_formatstr("%l/%p/%a/%k/%c/%d/%T/%I/%O/%M/%s/%S/%A/%#\n",                          rad_last);    else parse_formatstr( 		    "\nUsername = %l\n"	    	    "Port-Number = %p\n"		    "NAS-IP = %a\n"		    "Service-Type = %k\n"		    "User-IP = %c\n"		    "Date = %d\n"		    "Session-Time = %T\n"		    "Input-Traffic = %I\n"		    "Output-Traffic = %O\n"		    "Total-Traffic = %M\n"		    "Rx-Speed = %s\n"		    "Tx-Speed = %S\n"		    "NAS-CLI = %A\n"		    "User-CLI = %#\n",rad_last );  else /* !extended */	if (brief)	    parse_formatstr("%l/%p/%a/%k/%c/%d/%T\n",rad_last);	else	    parse_formatstr(                     "\nUsername = %l\n"                    "Port-Number = %p\n"                    "NAS-IP = %a\n"                    "Service-Type = %k\n"                    "User-IP = %c\n"                    "Date = %d\n"                    "Session-Time = %T\n",rad_last);}static void radlast_usage(void){    printf("\nUsage: %s <option>\n\nValid options are:\n", progname);    printf("\t-a <acct_dir>\tthe radius accounting files directory\n");    printf("\t-F <format>\tcustom output format\n");    printf("\t-H <format>\tcustom header\n");    printf("\t-c\t\tshow records in cronological order\n");    printf("\t-u <username>\tget username database entry\n");    printf("\t-f <filename>\tuse this radlast logfile instead\n");    printf("\t-h\t\tthis help screen\n");    printf("\t-m <month>\treport statistics for <month>\n");    printf("\t-y <year>\treport statistics for <year>\n");    printf("\t-b\t\tsingle row output\n");    printf("\t-x\t\textended info (include traffic and CLIs)\n\n");    exit(-1);}static void fatal_func(const char *msg) {    fprintf(stderr, "FATAL ERROR: %s\n",msg);    return;}int main(int argc, char **argv){    radlast rad_last;    int fd;    static char filename[PATH_MAX];    int flag;    int month;    int year;    time_t crt_time;    struct tm *time_info;    int file_arg = 0;    int month_arg = 0;    int year_arg = 0;    int user_arg = 0;    const char *radacct_dir;    int cronologic = 0;    char *format=NULL;    char *header=NULL;    extern char *optarg;        crt_time = time(NULL);    time_info = localtime(&crt_time);    month = time_info->tm_mon + 1;				        year = 1900+time_info->tm_year;    memset(&rad_last, 0, sizeof(radlast));    memset(filename, 0, sizeof(filename));    memset(username, 0, sizeof(username));        progname = argv[0];    radacct_dir = RADACCT_DIR;        while ((flag = getopt(argc, argv, "a:F:H:cu:f:by:m:xh")) != EOF) {	char *cp;	switch (flag) {	    case 'a':		radacct_dir = optarg;		break;	    case 'F':		format = optarg;		break;	    case 'H':		header = optarg;		break;	    case 'c':		cronologic++;		break;	    case 'u':		strncpy(username, optarg, USERNAME_MAX);		user_arg++;		break;	    case 'f':		if (month_arg || year_arg) {		    fatal_func("you cannot specify a filename and a month number");		    radlast_usage();		}		strncpy(filename, optarg, PATH_MAX);		file_arg++;		break;            case 'b':		brief++;		break;	    case 'y':		if (file_arg) {                    fatal_func("you can not specify a year and a filename");		    radlast_usage();		}		year = strtol(optarg, &cp, 10);		if (*cp) {		    fatal_func("year should be a number\n");		    radlast_usage();		}		if (year < 1970) {		    fatal_func("year should be greater than 1970\n");		    radlast_usage();		}		year_arg++;		break;	    case 'm':		if (file_arg) {                    fatal_func("you can not specify a month number and a filename");		    radlast_usage();		}		month = strtol(optarg, &cp, 10);		if (*cp) {		    /* not a number ... */		    fatal_func("month should be a number\n");		    radlast_usage();		}		if ((month < 1) || (month > 12)) {		    fatal_func("month should be between 1 and 12\n");		    /* not a valid month */		    radlast_usage();		}		month_arg++;		break;	    case 'x':		extended++;		break;	    case 'h':	    default:		radlast_usage();	}    }    if (!file_arg)	snprintf(filename, sizeof(filename),"%s/%d/%s-%02d", 	        radacct_dir, year, RADIUS_LAST, month);        if ((fd = open(filename, O_RDONLY)) >= 0) {	off_t seekpos = 0;		if (!cronologic)	    seekpos = lseek(fd, -sizeof(radlast), SEEK_END);	if ( format != NULL && header != NULL ) parse_header(header); 	while ((seekpos >= 0) &&	       read(fd, &rad_last, sizeof(radlast)) == sizeof(radlast)) {	    if (user_arg && strncmp(username, rad_last.login, USERNAME_MAX)) {		memset(&rad_last, 0, sizeof(rad_last));		if (!cronologic)		    seekpos = lseek(fd, -2*sizeof(radlast), SEEK_CUR);		continue;	    }	    if ( format != NULL ) parse_formatstr(format,rad_last);	    else print_entry(rad_last);	    memset(&rad_last, 0, sizeof(rad_last));	    if (!cronologic)		seekpos = lseek(fd, -2*sizeof(radlast), SEEK_CUR);	}    } else {	fprintf(stderr, "Cannot open the radlast log file: %s\n",filename);	exit(-1);    }    exit(0);}void rad_exit(int code){ 	exit(code);}

⌨️ 快捷键说明

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