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

📄 filters.c

📁 RADIUS协议的认证计费服务
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifdef BINARY_FILTERS/* *      Copyright (c) 1994 Ascend Communications, Inc. *      All rights reserved. * *	Permission to copy all or part of this material 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 * */static char     rcsid[] = "$Id: filters.c,v 1.1.1.1 2001/08/10 20:49:28 bonze Exp $";#include	<sys/types.h>#include	<stdio.h>#include	<string.h>#include	<ctype.h>#include	<errno.h>#include	<syslog.h>#include	<netinet/in.h>#include	<stdlib.h>#include	<sys/time.h>		/* gettimeofday() */#include	<memory.h>#include	"radius.h"extern int       debug_flag;/* * Filter Port Type *  *	ASCII names of some well known TCP/UDP services. *	Used for filtering on a port type. *  */static keywordstruct filterporttype[] ={	{ "ftp-data",	20 },	{ "ftp",	21 },	{ "telnet",	23 },	{ "smtp",	25 },	{ "nameserver",	42 },	{ "domain",	53 },	{ "tftp",	69 },	{ "gopher",	70 },	{ "finger",	79 },	{ "www",	80 },	{ "kerberos",	88 },	{ "hostname",	101 },	{ "nntp",	119 },	{ "ntp",	123 },	{ "exec",	512 },	{ "login",	513 },	{ "cmd",	514 },	{ "talk",	517 },	{ NULL,		NO_TOKEN },};static keywordstruct filterkeywords[] ={	{ "ip",		FILTER_IP_TYPE },	{ "generic",	FILTER_GENERIC_TYPE },	{ "in",		FILTER_IN },	{ "out",	FILTER_OUT },	{ "forward",	FILTER_FORWARD },	{ "drop",	FILTER_DROP },	{ "dstip",	FILTER_IP_DST },	{ "srcip",	FILTER_IP_SRC },	{ "dstport",	FILTER_IP_DST_PORT },	{ "srcport",	FILTER_IP_SRC_PORT },	{ "est",	FILTER_EST },	{ "more",	FILTER_MORE },	{ "!=",		FILTER_GENERIC_COMPNEQ },	{ "==",		FILTER_GENERIC_COMPEQ },	{ NULL,		NO_TOKEN },};#define FILTER_DIRECTION 	0#define FILTER_DISPOSITION	1#define IP_FILTER_COMPLETE  	0x3	/* bits shifted by FILTER_DIRECTION, */					/* and by FILTER_DISPOSITION */#define GENERIC_FILTER_COMPLETE 0x1c3	/* bits shifted by FILTER_DIRECTION, */					/* and by FILTER_DISPOSITION, and by */					/* FILTER_GENERIC_OFFSET, and by */					/* FILTER_GENERIC_MASK, and by */					/* FILTER_GENERIC_VALUE *//* * Filter Protocol Name - ASCII names of protocols used for filtering. */static keywordstruct filterprotoname[] ={	{ "tcp",	6 },	{ "udp",	17 },	{ "ospf",	89 },	{ "icmp",	1 },	{ NULL,		NO_TOKEN },};keywordstruct filtercompare[] ={	{ ">",	RAD_COMPARE_GREATER },	{ "=",	RAD_COMPARE_EQUAL },	{ "<",	RAD_COMPARE_LESS },	{ "!=",	RAD_COMPARE_NOT_EQUAL },	{ NULL,	NO_TOKEN },};static char     curstring[AUTH_STRING2_LEN];static char     ip_address_digits[] = "1234567890./";static int      find_key PROTO((char *, keywordstruct *));static int      is_all_digit PROTO((char *));static short    a2octet PROTO((char *, char *));static char     default_netmask PROTO((UINT4));static int      ipaddr_str2val PROTO((char *, UINT4 *, char *));static int      parse_ip_filter PROTO((radfilter *));static int      parse_gen_filter PROTO((radfilter *));/************************************************************************* *  *	Function: find_key *  *	Purpose: Given a table of keywords, try to match the given string *		 to an entry.  If it matches, return that keyword value, *		 else NO_TOKEN is returned.  A sanity check is made for *		 upper-case characters. *  *	Returns: Keyword value on a match, or NO_TOKEN. *  *************************************************************************/static intfind_key (string, list)char           *string;		/* Pointer to the token to match. */keywordstruct  *list;		/* Point to the list of keywords. */{	short           len;	keywordstruct  *entry;	char           *ptr;	char            buf[80];	static char    *func = "find_key";	dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: entered", func));	len = strlen ((char *) string);	for (ptr = buf; len; len--, string++)	{		if (isupper(*string))		{			*ptr++ = tolower(*string);		}		else		{			*ptr++ = *string;		}	}	*ptr = 0;	entry = list;	while (entry->name)	{		if (strcmp (entry->name, buf) == 0)		{			break;		}		entry++;	}	return (entry->value);} /* end of find_key () *//************************************************************************* *  *	Function: is_all_digit *  *	Purpose: Checks a string to make sure all values are digits. *  *	Returns: TRUE if all digits, or FALSE. *  *************************************************************************/static intis_all_digit (token)char           *token;		/* Pointer to sting to check. */{	int             i;	static char    *func = "is_all_digit";	dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: entered", func));	i = strlen ((char *) token);	while (i--)	{		if (isdigit(*token))		{			token++;		}		else		{			break;		}	}	if (i > 0)	{		return (FALSE);	}	return (TRUE);} /* end of is_all_digit () *//************************************************************************* * *	Function: a2octet *  *	Purpose: Converts the ASCII mask and value for generic filters *		 into octets.  Also does a sanity check to see if the *		 string is greater than MAX_FILTER_LEN. *		 Assumes the sting is hexadecimal with NO leading "0x". *  *	Returns: Number of octets, or -1 for error. *  *************************************************************************/static shorta2octet (tok, retBuf)char           *tok;		/* Pointer to the string. */char           *retBuf;		/* Pointer to place the octets. */{	short           i;	short           len;	short           rc;	short           retlen;	short           val;	char           *octet;	char            buf[RAD_MAX_FILTER_LEN * 2];	static char    *func = "a2octet";	dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: entered", func));	octet = buf;	rc = -1;	retlen = 0;	if ((len = strlen ((char *) tok)) <= (RAD_MAX_FILTER_LEN * 2))	{		retlen = len / 2;		if (len % 2)		{			retlen++;		}		memset (buf, '\0', RAD_MAX_FILTER_LEN * 2);		for ( ; len ; len--)		{			if (*tok <= '9' && *tok >= '0')			{				val = '0';				*octet++ = *tok++ - val;			}			else if (isxdigit(*tok))			{				if (*tok > 'Z')				{					val = 'a';				}				else				{					val = 'A';				}				*octet++ = (*tok++ - val) + 10;			}			else			{				break;			}		}		if (!len)		{			/* merge the values */			for (i = 0; i < RAD_MAX_FILTER_LEN * 2; i += 2)			{				*retBuf++ = (buf[i] << 4) | buf[i + 1];			}		}	}	if (len)	{		rc = -1;	}	else	{		rc = retlen;	}	return (rc);} /* end of a2octet () *//************************************************************************* * *	Function: default_netmask *  *	Purpose: Given an IP address, calculate a default netmask. *  *	Returns: Number of bits for the netmask. *  *************************************************************************/static chardefault_netmask (address)UINT4           address;	/* The given IP address. */{	char            netmask;	static char    *func = "default_netmask";	dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: entered", func));	if (!address)	{		netmask = 0;	}	else if ((address & htonl(0x80000000)) == 0)	{		netmask = 8;	}	else if ((address & htonl(0xc0000000)) == htonl(0x80000000))	{		netmask = 16;	}	else if ((address & htonl(0xe0000000)) == htonl(0xc0000000))	{		netmask = 24;	}	else	{		netmask = 32;	}	return netmask;} /* end of default_netmask () *//************************************************************************* * *	Function: ipaddr_str2val * *	Purpose: Attempts to convert an IP address (in ASCII dotted quad *		 notation with an optional netmask part) to a pair of *		 IP addresses.  Note: An IP address is always stored *		 in network byte order. *  *  *	Returns: TRUE if valid conversion, FALSE otherwise. *  *************************************************************************/static intipaddr_str2val (string, ipaddress, netmask)char           *string;		/* IP address string: xxx.xxx.xxx.xxx[/nn] */UINT4          *ipaddress;	/* Resultant IP address to return to caller. */char           *netmask;	/* Resultant netmask to return to caller. */{	int             i;	int             numdots;	long            value;	u_char         *dst;	char           *cp;	static char    *func = "ipaddr_str2val";	dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: entered", func));	if (!string)	{		return (FALSE);	}	/*	 *	Allow an IP address to be blanked instead of forcing	 *	entry of 0.0.0.0 -- the user will like it.	 */	if (*string == 0)	{		*ipaddress = 0;		*netmask = 0;		return TRUE;	}	/*	 *	First just count the number of dots in the address.	 *	If there are more or less than three the address is invalid.	 */	cp = string;	numdots = 0;	while (*cp)	{		if (!strchr (ip_address_digits, *cp))		{			return (FALSE);		}		if (*cp == '.')		{			numdots++;		}		cp++;	}	if (numdots != 3)	{		return (FALSE);	}	dst = (u_char *) ipaddress;	cp = string;	for (i = 0; i < sizeof (*ipaddress); i++)	{		value = strtol (cp, (char **) &cp, 10);		if ((value < 0) || (value > 255))		{			return (FALSE);		}		*dst++ = (u_char) value;		if (*cp == '.')		{			cp += 1;		}	}	/*	 * If there is a netmask part, parse it, otherwise figure out the	 * default netmask for this class of address.	 */	if (*cp == '/')	{		value = strtol (cp + 1, (char **) &cp, 10);		if ((*cp != 0) || (value < 0) || (value > 32))		{			return (FALSE);		}		*netmask = (char) value;	}	else	{		*netmask = default_netmask (*ipaddress);	}	return (TRUE);} /* end of ipaddr_str2val () *//************************************************************************* * *	Function: parse_ip_filter *  *	Purpose: Parses an IP filter string from a RADIUS reply. *		 The format of the string is: *  *	    ip dir action [ dstip n.n.n.n/nn ] [ srcip n.n.n.n/nn ] *		[ proto [ dstport cmp value ] [ srcport cmd value ] [ est ] ] *  *	    Fields in [...] are optional.  Where: *  *		ip:	Keyword to designate an IP filter. * 

⌨️ 快捷键说明

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