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

📄 ipaddrset.c

📁 Linux snort-2.4.4源代码
💻 C
字号:
/* $Id$ *//* * Copyright(C) 2002 Sourcefire, Inc. *  * Author(s):  Andrew R. Baker <andrewb@snort.org> *             Martin Roesch   <roesch@sourcefire.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. *  * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * *//* includes */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <errno.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#ifndef WIN32#include <netdb.h>#include <ctype.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#endif#ifdef HAVE_STRINGS_H#include <strings.h>#endif#include "util.h"#include "mstring.h"#include "parser.h"#include "debug.h"#include "IpAddrSet.h"IpAddrSet *IpAddrSetCreate(){    IpAddrSet *tmp;    tmp = (IpAddrSet *) SnortAlloc(sizeof(IpAddrSet));    return tmp;}void IpAddrSetDestroy(IpAddrSet *ipAddrSet){    IpAddrSet *next;    while(ipAddrSet)    {        next = ipAddrSet->next;        free(ipAddrSet);        ipAddrSet = next;    }}static char buffer[1024];void IpAddrSetPrint(char *prefix, IpAddrSet *ipAddrSet){    struct in_addr in;    size_t offset = 0;    while(ipAddrSet)    {        offset = 0;        if(ipAddrSet->addr_flags & EXCEPT_IP)            offset += snprintf(buffer, 1024 - offset, "NOT ");        in.s_addr = ipAddrSet->ip_addr;        offset += snprintf(buffer + offset, 1024 - offset, "%s/",                 inet_ntoa(in));        in.s_addr = ipAddrSet->netmask;        offset += snprintf(buffer + offset, 1024 - offset, "%s", inet_ntoa(in));        buffer[offset] = '\0';        if (prefix)            LogMessage("%s%s\n", prefix, buffer);        else            LogMessage("%s%s\n", buffer);        ipAddrSet = ipAddrSet->next;    }}IpAddrSet *IpAddrSetCopy(IpAddrSet *ipAddrSet){    IpAddrSet *newIpAddrSet = NULL;    IpAddrSet *current = NULL;    IpAddrSet *prev = NULL;    while(ipAddrSet)    {        if(!(current = (IpAddrSet *)malloc(sizeof(IpAddrSet))))        {            /* ENOMEM */            goto failed;        }                current->ip_addr = ipAddrSet->ip_addr;        current->netmask = ipAddrSet->netmask;        current->addr_flags = ipAddrSet->addr_flags;        current->next = NULL;        if(!prev)            newIpAddrSet = current;        else            prev->next = current;        ipAddrSet = ipAddrSet->next;        prev = current;    }    return newIpAddrSet;failed:    if(newIpAddrSet)        IpAddrSetDestroy(newIpAddrSet);    return NULL; /* XXX ENOMEM */}/* XXX: legacy support function *//* * Function: ParseIP(char *, IpAddrSet *) * * Purpose: Convert a supplied IP address to it's network order 32-bit long *          value.  Also convert the CIDR block notation into a real *          netmask. * * Arguments: char *addr  => address string to convert *            IpAddrSet * => *             * * Returns: 0 for normal addresses, 1 for an "any" address */int ParseIP(char *paddr, IpAddrSet *address_data){    char **toks;        /* token dbl buffer */    int num_toks;       /* number of tokens found by mSplit() */    int cidr = 1;       /* is network expressed in CIDR format */    int nmask = -1;     /* netmask temporary storage */    char *addr;         /* string to parse, eventually a                         * variable-contents */    struct hostent *host_info;  /* various struct pointers for stuff */    struct sockaddr_in sin; /* addr struct */    char broadcast_addr_set = 0;    addr = paddr;    if(*addr == '!')    {        address_data->addr_flags |= EXCEPT_IP;        addr++;  /* inc past the '!' */    }    /* check for wildcards */    if(!strcasecmp(addr, "any"))    {        address_data->ip_addr = 0;        address_data->netmask = 0;        return 1;    }    /* break out the CIDR notation from the IP address */    toks = mSplit(addr, "/", 2, &num_toks, 0);    /* "/" was not used as a delimeter, try ":" */    if(num_toks == 1)    {        mSplitFree(&toks, num_toks);        toks = mSplit(addr, ":", 2, &num_toks, 0);    }    /*     * if we have a mask spec and it is more than two characters long, assume     * it is netmask format     */    if((num_toks > 1) && strlen(toks[1]) > 2)    {        cidr = 0;    }    switch(num_toks)    {        case 1:            address_data->netmask = netmasks[32];            break;        case 2:            if(cidr)            {                /* convert the CIDR notation into a real live netmask */                nmask = atoi(toks[1]);                /* it's pain to differ whether toks[1] is correct if netmask */                /* is /0, so we deploy some sort of evil hack with isdigit */                if(!isdigit((int) toks[1][0]))                    nmask = -1;                /* if second char is != '\0', it must be a digit                 * by Daniel B. Cid, dcid@sourcefire.com                 */                 if((toks[1][1] != '\0')&&(!isdigit((int) toks[1][1]) ))                    nmask = -1;                                if((nmask > -1) && (nmask < 33))                {                    address_data->netmask = netmasks[nmask];                }                else                {                    FatalError("ERROR %s(%d): Invalid CIDR block for IP addr "                            "%s\n", file_name, file_line, addr);                                           }            }            else            {                /* convert the netmask into its 32-bit value */                /* broadcast address fix from                  * Steve Beaty <beaty@emess.mscd.edu>                  */                /*                 * if the address is the (v4) broadcast address, inet_addr *                 * returns -1 which usually signifies an error, but in the *                 * broadcast address case, is correct.  we'd use inet_aton() *                 * here, but it's less portable.                 */                if(!strncmp(toks[1], "255.255.255.255", 15))                {                    address_data->netmask = INADDR_BROADCAST;                }                else if((address_data->netmask = inet_addr(toks[1])) == -1)                {                    FatalError("ERROR %s(%d): Unable to parse rule netmask "                            "(%s)\n", file_name, file_line, toks[1]);                }                /* Set nmask so we don't try to do a host lookup below.                 * The value of 0 is irrelevant. */                nmask = 0;            }            break;        default:            FatalError("ERROR %s(%d) => Unrecognized IP address/netmask %s\n",                    file_name, file_line, addr);            break;    }    sin.sin_addr.s_addr = inet_addr(toks[0]);#ifndef WORDS_BIGENDIAN    /*     * since PC's store things the "wrong" way, shuffle the bytes into the     * right order.  Non-CIDR netmasks are already correct.     */    if(cidr)    {        address_data->netmask = htonl(address_data->netmask);    }#endif    /* broadcast address fix from Steve Beaty <beaty@emess.mscd.edu> */    /* Changed location */    if(!strncmp(toks[0], "255.255.255.255", 15))    {        address_data->ip_addr = INADDR_BROADCAST;        broadcast_addr_set = 1;    }    else if (nmask == -1)    {        /* Try to do a host lookup if the address didn't         * convert to a valid IP and there were not any         * mask bits specified (CIDR or dot notation). */        if(sin.sin_addr.s_addr == INADDR_NONE)        {            /* get the hostname and fill in the host_info struct */            if((host_info = gethostbyname(toks[0])))            {                /* protecting against malicious DNS servers */                if(host_info->h_length <= sizeof(sin.sin_addr))                {                    bcopy(host_info->h_addr, (char *) &sin.sin_addr, host_info->h_length);                }                else                {                    bcopy(host_info->h_addr, (char *) &sin.sin_addr, sizeof(sin.sin_addr));                }            }            /* Using h_errno */            else if(h_errno == HOST_NOT_FOUND)            /*else if((sin.sin_addr.s_addr = inet_addr(toks[0])) == INADDR_NONE)*/            {                FatalError("ERROR %s(%d): Couldn't resolve hostname %s\n",                    file_name, file_line, toks[0]);            }        }        else        {            /* It was a valid IP address with no netmask specified. */            /* Noop */        }    }    else    {        if(sin.sin_addr.s_addr == INADDR_NONE)        {            /* It was not a valid IP address but had a valid netmask. */            FatalError("ERROR %s(%d): Rule IP addr (%s) didn't translate\n",                file_name, file_line, toks[0]);        }    }    /* Only set this if we haven't set it above as 255.255.255.255 */    if (!broadcast_addr_set)    {        address_data->ip_addr = ((u_long) (sin.sin_addr.s_addr) &            (address_data->netmask));    }    mSplitFree(&toks, num_toks);    return 0;}                                                                                            IpAddrSet *IpAddrSetParse(char *addr){    IpAddrSet *ias = NULL;    IpAddrSet *tmp_ias = NULL;    char **toks;    int num_toks;    int i;    char *tmp;    char *enbracket;    char *index;    int flags = 0;    index = addr;        while(isspace((int)*index)) index++;        if(*index == '!')    {        flags = EXCEPT_IP;    }    if(*index == '$')    {        if((tmp = VarGet(index+1)) == NULL)        {            FatalError("%s(%d) => Undefined variable %s\n", file_name, file_line,                    index);        }    }    else    {        tmp = index;    }    if(*tmp == '[')    {        DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Found IP list!\n"););        enbracket = strrchr(tmp, (int)']'); /* null out the en-bracket */        if(enbracket)             *enbracket = '\x0';        else            FatalError("%s(%d) => Unterminated IP List\n", file_name, file_line);        toks = mSplit(tmp+1, ",", 128, &num_toks, 0);        DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"mSplit got %d tokens...\n",                     num_toks););        for(i=0; i< num_toks; i++)        {            DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"adding %s to IP "                        "address list\n", toks[i]););            tmp = toks[i];            while (isspace((int)*tmp)||*tmp=='[') tmp++;            enbracket = strrchr(tmp, (int)']'); /* null out the en-bracket */            if(enbracket)                 *enbracket = '\x0';            if (!strlen(tmp))                continue;                            if(!ias)            {                ias = (IpAddrSet *) SnortAlloc(sizeof(IpAddrSet));                tmp_ias = ias;            }            else            {                tmp_ias->next = (IpAddrSet *) SnortAlloc(sizeof(IpAddrSet));                tmp_ias = tmp_ias->next;            }                        ParseIP(tmp, tmp_ias);        }        mSplitFree(&toks, num_toks);    }    else    {        DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,                    "regular IP address, processing...\n"););        ias = (IpAddrSet *) SnortAlloc(sizeof(IpAddrSet));        ParseIP(tmp, ias);    }    return ias;}int IpAddrSetContains(IpAddrSet *ias, struct in_addr test_addr){    IpAddrSet *index;    u_int32_t raw_addr;    int exception_flag = 0;    raw_addr = test_addr.s_addr;        for(index = ias; index != NULL; index = index->next)    {        if(index->addr_flags & EXCEPT_IP) exception_flag = 1;        if(((index->ip_addr == (raw_addr & index->netmask)) ^ exception_flag))        {            return 1;        }    }    return 0;}

⌨️ 快捷键说明

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