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

📄 filters.c

📁 This program is a RADIUS RFC-compliant daemon, which is derived from original Livingston Enterprise
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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. * * Modifications to this file for yardradius are under YardRadius copyright, * as follows: *  * Copyright (C) 2004, 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. *//* FIXME: A bit revised for inclusion in yardradius, needs major revision *//* $Id: filters.c,v 1.1.2.2 2004/08/27 21:45:16 flovergine Exp $ */#include "yard.h"#if defined(ASCEND_BINARY)VALUE_PAIR*	prevRadPair = NULL;#define NO_TOKEN -1typedef struct {    const char*	name;    int 	value;} KeywordStruct;    /*     * FilterPortType:     *     * 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 },};typedef enum {    FILTER_IP_TYPE,    FILTER_GENERIC_TYPE,    FILTER_IN,    FILTER_OUT,    FILTER_FORWARD,    FILTER_DROP,    FILTER_GENERIC_OFFSET,    FILTER_GENERIC_MASK,    FILTER_GENERIC_VALUE,    FILTER_GENERIC_COMPNEQ,    FILTER_GENERIC_COMPEQ,    FILTER_MORE,    FILTER_IP_DST,    FILTER_IP_SRC,    FILTER_IP_PROTO,    FILTER_IP_DST_PORT,    FILTER_IP_SRC_PORT,    FILTER_EST,    FILTER_IPX_TYPE,    FILTER_IPX_DST_IPXNET,    FILTER_IPX_DST_IPXNODE,    FILTER_IPX_DST_IPXSOCK,    FILTER_IPX_SRC_IPXNET,    FILTER_IPX_SRC_IPXNODE,    FILTER_IPX_SRC_IPXSOCK} FilterTokens;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  },    { "ipx",	FILTER_IPX_TYPE  },    { "dstipxnet",	FILTER_IPX_DST_IPXNET  },    { "dstipxnode",	FILTER_IPX_DST_IPXNODE  },    { "dstipxsock",	FILTER_IPX_DST_IPXSOCK  },    { "srcipxnet",	FILTER_IPX_SRC_IPXNET  },    { "srcipxnode",	FILTER_IPX_SRC_IPXNODE  },    { "srcipxsock",	FILTER_IPX_SRC_IPXSOCK  },    {  NULL , NO_TOKEN },};#define FILTER_DIRECTION 	0#define FILTER_DISPOSITION	1#define IP_FILTER_COMPLETE  	0x3	/* bits shifted by FILTER_DIRECTION */					/* FILTER_DISPOSITION */#define IPX_FILTER_COMPLETE      0x3     /* bits shifted by FILTER_DIRECTION */                                        /* FILTER_DISPOSITION */#define GENERIC_FILTER_COMPLETE 0x1c3	/* bits shifted for FILTER_DIRECTION */					/* FILTER_DISPOSITION, FILTER_GENERIC_OFFSET*/					/* FILTER_GENERIC_MASK, FILTER_GENERIC_VALUE*/    /*     * FilterProtoName:     *     * Ascii name of protocols used for filtering.     *     */static KeywordStruct _filterProtoName[] = {    { "tcp",  6 },    { "udp",  17 },    { "ospf", 89 },    { "icmp", 1 },    {  NULL , NO_TOKEN },};static KeywordStruct _filterCompare[] = {    { ">", RAD_COMPARE_GREATER },    { "=", RAD_COMPARE_EQUAL },    { "<", RAD_COMPARE_LESS },    { "!=", RAD_COMPARE_NOT_EQUAL },    {  NULL , NO_TOKEN },};static char	_curString[512];static int _findKey ( char *string, KeywordStruct *list );static int _isAllDigit ( char *token );static short _a2octet ( char *tok, char *retBuf );static char _defaultNetmask ( unsigned long address );static int _ipAddressStringToValue ( char *string, unsigned long *ipAddress,					 char *netmask);static int _parseIpFilter ( RadFilter *curEntry );static int _parseGenericFilter ( RadFilter *curEntry );static int _parseIpxFilter ( RadFilter *curEntry );static int _stringToNode   ( unsigned char* dest,  unsigned char* src );    /*     * _findKey:     *     * Given a table of keywords, it will try and match string to an     * entry. If it does it returns that keyword value. if no NO_TOKEN is     * returned. A sanity check is made for upper case characters.     *     *	string:			Pointer to the token to match.     *     *	list:			Point to the list of keywords.     *     *	returns:		Keyword value on a match or NO_TOKEN.     */static int _findKey(char *string, KeywordStruct *list){    KeywordStruct *entry;    char *buf, *ptr;    buf = strdup(string);    for( ptr = buf ; buf && *ptr ; ptr++ ) {	if ( isupper( *ptr ) ) *ptr = tolower( *ptr );    }    entry = list;    while( entry->name ) {   	if( strcmp( entry->name, buf ) == 0 ) {	    break;	}	entry++;    }    free(buf);    return( entry->value );}    /*     * _isAllDigit:     *     * Routine checks a string to make sure all values are digits.     *     *	token:			Pointer to sting to check.     *     * 	returns:		TRUE if all digits, or FALSE.     *     */static int_isAllDigit(char *token){    int i;    i = strlen( (char *) token );    while( i-- ) {	if( isdigit( *token ) ) {	    token++;	} else {	    break;	}    }    if( i > 0 ) {	return( FALSE );    }     return( TRUE );}    /*     * _a2octet:     *     * Converts the ascii mask and value for generic filters into octets.     * It also does a sanity check to see if the string is greater than     * MAX_FILTER_LEN. It assumes the sting is hex with NO leading "0x"     *     *	tok:			Pointer to the string.     *     *  retBuf:			Pointer to place the octets.     *     *	returns:		Number of octects or -1 for error.     *      */static short_a2octet(char *tok,char *retBuf){    short	rc, len, val, retLen, i;    char	buf[ RAD_MAX_FILTER_LEN *2 ];    char	*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 );}    /*     * _defaultNetMask:     *     *	Given an ip address this routine calculate a default netmask.     *     *	address:		Ip address.     *     *	returns:		Number of bits for the netmask     *     */static char_defaultNetmask(unsigned long address){    char netmask;    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;}		    /*     * This functions attempts to convert an IP address in ASCII dot     * with an optional netmask part to a pair of IpAddress.  Note:     * An IpAddress is always stored in network byte order.     *     * Parameters:     *     *  string:		Pointer to a NULL terminated IP address in dot      *			notation followed by an optional /nn to indicate     *			the number leading of bits in the netmask.     *      *  ipAddress:	Pointer to an IpAddress where the converted     *			address will be stored.     *     *	netmask:	Pointer to an IpAddress where the netmask     *			will be stored.  If no netmask is passed as     *			as part of the address the default netmask will     *			be stored here.     *     * Returns:     *	<>		TRUE if valid conversion, FALSE otherwise.     *     *	*ipAddress:	If function returns TRUE, the IP address in NBO.     *	*netmask:	If function returns TRUE, the netmask in NBO.     */static int_ipAddressStringToValue(char *string, unsigned long *ipAddress, char *netmask){    u_char*	dst;    char*	cp;    int		numDots;    int		i;    long	value;    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( (char*)"1234567890./", *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 = _defaultNetmask( *ipAddress );    }    return TRUE;}    /*     * Convert a 12 digit string representation of a hex data field to a     * value.     */static int_stringToNode( unsigned char*dest, unsigned char*src ){    int         srcIx = 0;    int         ix;    int         nibble1;    int         nibble2;    int		temp;    unsigned char *src1;    src1 = (unsigned char *) strchr(src, 'x');    if (src1 == NULL)	src1 = (unsigned char *) strchr(src,'X');    if (src1 == NULL)	src1 = src;    else	src1++;    /* skip any leading 0x or 0X 's */    temp = strlen( (char*) src1 );    if( strlen( (unsigned char*) src1 ) != ( IPX_NODE_ADDR_LEN * 2 ) ) {        return( FALSE );    }    for ( ix = 0; ix < IPX_NODE_ADDR_LEN; ++ix ) {        if ( src1[ srcIx ] <= '9' ) {            nibble1 = src1[ srcIx ] & 0x0f;        } else {            nibble1 = (src1[ srcIx ] & 0x0f) + 9;        }        srcIx += 1;        if ( src1[ srcIx ] <= '9' ) {            nibble2 = src1[ srcIx ] & 0x0f;        } else {            nibble2 = (src1[ srcIx ] & 0x0f) + 9;        }        srcIx += 1;        ((unsigned char *) dest)[ ix ] = (unsigned char) (nibble1 << 4) + nibble2;    }    return( TRUE );}    /*     * _parseIpxFilter:     *     * This routine parses an IPX filter string from a RADIUS     * reply. The format of the string is:     *     *	ipx dir action [ srcipxnet nnnn srcipxnode mmmmm [srcipxsoc cmd value ]]     * 	               [ dstipxnet nnnn dstipxnode mmmmm [dstipxsoc cmd value ]]     *     * Fields in [...] are optional.     *	where:     *     *  ipx:		Keyword to designate an IPX filter. Actually this     *			has been determined by _parseFilter.     *     *	dir:		Filter direction. "IN" or "OUT"     *     *	action:		Filter action. "FORWARD" or "DROP"     *     *  srcipxnet:      Keyword for source IPX address.     *                  nnnn = IPX Node address.     *     *  srcipxnode:     Keyword for source IPX Node address.     *                  mmmmm = IPX Node Address, could be FFFFFF.     *                  A vlid ipx node number should accompany ipx net number.     *     *  srcipxsoc:      Keyword for source IPX socket address.     *     *  cmd:            One of ">" or "<" or "=" or "!=".     *     *  value:          Socket value to be compared against, in hex.      *			     *	dstipxnet:	Keyword for destination IPX address.     *			nnnn = IPX Node address.      *			     *	dstipxnode:	Keyword for destination IPX Node address.     *  		mmmmm = IPX Node Address, could be FFFFFF.     *			A vlid ipx node number should accompany ipx net number.     *			     *	dstipxsoc:	Keyword for destination IPX socket address.     *			     *	cmd:		One of ">" or "<" or "=" or "!=".     *			     *	value:		Socket value to be compared against, in hex.		     *			     *			     * expects:     *     *	curEntry:	Pointer to place the filter structure     *     *	returns:	-1 for error or 0 for OK     *	     */static int _parseIpxFilter(RadFilter*curEntry){

⌨️ 快捷键说明

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