/* * filters.c Routines to parse Ascend's filter attributes. * * Version: $Id$ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * * Copyright 2003,2006 The FreeRADIUS server project */ #include #define FR_NAME_NUMBER struct fr_name_number FR_NAME_NUMBER { const char *name; int nr; }; /* * Two types of filters are supported, GENERIC and IP. The identifiers * are: */ #define RAD_FILTER_GENERIC 0 #define RAD_FILTER_IP 1 #define RAD_FILTER_IPX 2 /* * Generic filters mask and match up to RAD_MAX_FILTER_LEN bytes * starting at some offset. The length is: */ #define RAD_MAX_FILTER_LEN 6 /* * ASCEND extensions for ABINARY filters */ #define IPX_NODE_ADDR_LEN 6 /* * ascend_ip_filter_t * * The binary format of an IP filter. ALL fields are stored in * network byte order. * * srcip: The source IP address. * * dstip: The destination IP address. * * srcmask: The number of leading one bits in the source address * mask. Specifies the bits of interest. * * dstmask: The number of leading one bits in the destination * address mask. Specifies the bits of interest. * * proto: The IP protocol number * * established: A boolean value. TRUE when we care about the * established state of a TCP connection. FALSE when * we dont care. * * srcport: TCP or UDP source port number. * * dstport: TCP or UDP destination port number. * * srcPortCmp: One of the values of the RadFilterComparison * enumeration, specifying how to compare the * srcport value. * * dstPortCmp: One of the values of the RadFilterComparison * enumeration, specifying how to compare the * dstport value. * * fill: Round things out to a int16_t boundary. */ typedef struct ascend_ip_filter_t { uint32_t srcip; uint32_t dstip; uint8_t srcmask; uint8_t dstmask; uint8_t proto; uint8_t established; uint16_t srcport; uint16_t dstport; uint8_t srcPortComp; uint8_t dstPortComp; unsigned char fill[4]; /* used to be fill[2] */ } ascend_ip_filter_t; /* * ascend_ipx_net_t * * net: IPX Net address * * node: IPX Node address * * socket: IPX socket address */ typedef struct ascend_ipx_net_t { uint32_t net; uint8_t node[IPX_NODE_ADDR_LEN]; uint16_t socket; } ascend_ipx_net_t; /* * ascend_ipx_filter_t * * The binary format of an IPX filter. ALL fields are stored in * network byte order. * * src: Source net, node, and socket. * * dst: Destination net, node, and socket. * * srcSocComp: Source socket compare value * * dstSocComp: Destination socket compare value */ typedef struct ascend_ipx_filter_t { ascend_ipx_net_t src; ascend_ipx_net_t dst; uint8_t srcSocComp; uint8_t dstSocComp; } ascend_ipx_filter_t; /* * ascend_generic_filter_t * * The binary format of a GENERIC filter. ALL fields are stored in * network byte order. * * offset: Number of bytes into packet to start comparison. * * len: Number of bytes to mask and compare. May not * exceed RAD_MAX_FILTER_LEN. * * more: Boolean. If non-zero the next filter entry is * also to be applied to a packet. * * mask: A bit mask specifying the bits to compare. * * value: A value to compare against the masked bits at * offset in a users packet. * * compNeq: Defines type of comarison (Equal or Notequal) * default is Equal. * * fill: Round things out to a dword boundary */ typedef struct ascend_generic_filter_t { uint16_t offset; uint16_t len; uint16_t more; uint8_t mask[ RAD_MAX_FILTER_LEN ]; uint8_t value[ RAD_MAX_FILTER_LEN ]; uint8_t compNeq; uint8_t fill[3]; /* used to be fill[1] */ } ascend_generic_filter_t; /* * ascend_filter_t * * A binary filter element. Contains one of ascend_ip_filter_t, * ascend_ipx_filter_t, or ascend_generic_filter_t. * * All fields are stored in network byte order. * * type: Either RAD_FILTER_GENERIC or RAD_FILTER_IP. * * forward: TRUE if we should forward packets that match this * filter, FALSE if we should drop packets that match * this filter. * * direction: TRUE if this is an input filter, FALSE if this is * an output filter. * * fill: Round things out to a dword boundary. * * u: A union of * ip: An ip filter entry * generic: A generic filter entry */ typedef struct ascend_filter_t { uint8_t type; uint8_t forward; uint8_t direction; uint8_t fill; union { ascend_ip_filter_t ip; ascend_ipx_filter_t ipx; ascend_generic_filter_t generic; uint8_t data[28]; /* ensure it's 32 bytes */ } u; } ascend_filter_t; /* * This is a wild C hack... */ typedef struct _cpp_hack { char data[(sizeof(ascend_filter_t) == 32) ? 1 : -1 ]; } _cpp_hack; static const FR_NAME_NUMBER filterType[] = { { "generic", RAD_FILTER_GENERIC}, { "ip", RAD_FILTER_IP}, { "ipx", RAD_FILTER_IPX}, { NULL, 0}, }; typedef enum { FILTER_GENERIC_TYPE, FILTER_IP_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 const FR_NAME_NUMBER 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 , -1}, }; /* * FilterProtoName: * * Ascii name of protocols used for filtering. * * ??? What the heck is wrong with getprotobyname? */ static const FR_NAME_NUMBER filterProtoName[] = { { "tcp", 6 }, { "udp", 17 }, { "ospf", 89 }, { "icmp", 1 }, { "0", 0 }, { NULL , -1 }, }; /* * RadFilterComparison: * * An enumerated values for the IP filter port comparisons. */ typedef enum { RAD_NO_COMPARE = 0, RAD_COMPARE_LESS, RAD_COMPARE_EQUAL, RAD_COMPARE_GREATER, RAD_COMPARE_NOT_EQUAL } RadFilterComparison; static const FR_NAME_NUMBER filterCompare[] = { { "<", RAD_COMPARE_LESS }, { "=", RAD_COMPARE_EQUAL }, { ">", RAD_COMPARE_GREATER }, { "!=", RAD_COMPARE_NOT_EQUAL }, { NULL, 0 }, }; #define IP_SRC_ADDR_FLAG (1 << 0) #define IP_DEST_ADDR_FLAG (1 << 1) #define IP_SRC_PORT_FLAG (1 << 2) #define IP_DEST_PORT_FLAG (1 << 3) #define IP_PROTO_FLAG (1 << 4) #define IP_EST_FLAG (1 << 5) #define DONE_FLAGS (IP_SRC_ADDR_FLAG | IP_DEST_ADDR_FLAG | \ IP_SRC_PORT_FLAG | IP_DEST_PORT_FLAG | \ IP_PROTO_FLAG | IP_EST_FLAG)