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

📄 snort.c

📁 该软件是一个有名的基于网络的入侵检测系统
💻 C
📖 第 1 页 / 共 4 页
字号:
/* $Id: snort.c,v 1.44 2000/03/20 08:40:58 roesch Exp $ */
/*
** Copyright (C) 1998,1999,2000 Martin Roesch <roesch@clark.net>
**
** 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.
*/

/******************************************************************************
 *
 * Program: Snort
 *
 * Purpose: Check out the README file for info on what you can do
 *          with Snort.
 *
 * Author: Martin Roesch (roesch@clark.net)
 *
 * Comments: Ideas and code stolen liberally from Mike Borella's IP Grab 
 *           program. Check out his stuff at http://www.borella.net.  I
 *           also have ripped some util functions from TCPdump, plus Mike's
 *           prog is derived from it as well.  All hail TCPdump....
 *
 * HP-UX 10.x note from Chris Sylvain:
 * if you run snort and receive the error message
 *  "ERROR: OpenPcap() device lan0 open:
 *                    recv_ack: promisc_phys: Invalid argument"
 * it's because there's another program running using the DLPI service.
 * The HP-UX implementation doesn't allow more than one libpcap program
 * at a time to run, unlike Linux.
 *
 ******************************************************************************/

/*  I N C L U D E S  **********************************************************/
#include "snort.h"


extern OutputFuncNode *AlertList;
extern OutputFuncNode *LogList;

/****************************************************************************
 *
 * Function: main(int, char *)
 *
 * Purpose:  Handle program entry and exit, call main prog sections
 *
 * Arguments: See command line args in README file
 *
 * Returns: 0 => normal exit, 1 => exit on error
 *
 ****************************************************************************/
int main(int argc, char *argv[])
{
#if defined(LINUX) || defined (FREEBSD) || defined(OPENBSD) || defined(SOLARIS)
    sigset_t set;
    sigemptyset(&set);
    sigprocmask(SIG_SETMASK, &set, NULL);
#else
    sigsetmask(0);
#endif

    /* make this prog behave nicely when signals come along */
    signal(SIGKILL, CleanExit);
    signal(SIGTERM, CleanExit);
    signal(SIGINT, CleanExit);
    signal(SIGQUIT, CleanExit);
    signal(SIGHUP, CleanExit);
    /* sane permissions */
    umask(077);

    /* set a global ptr to the program name so other functions can tell
       what the program name is */
    progname = argv[0];
    progargs = argv;

    InitNetmasks();
    InitProtoNames();

    /* initialize the packet counter to loop forever */
    pv.pkt_cnt = -1;

    /* set the default alert mode */
    pv.alert_mode = ALERT_FULL;

    /* set the timezone (ripped from tcpdump) */
    thiszone = gmt2local(0);

    pv.quiet_flag = 0;

    /* chew up the command line */
    ParseCmdLine(argc, argv);

#ifdef ENABLE_RESPONSE
#ifdef DEBUG
    printf("Opening Raw Socket for Sending\n");
#endif

    if ((nd = libnet_open_raw_sock(IPPROTO_RAW)) < 0)
    {
        FatalError("ERROR: cannot open raw socket for libnet, exiting...\n");
    }
#endif

    if (!pv.readmode_flag)
    {
#ifdef DEBUG
        printf("Opening interface: %s\n", pv.interface);
#endif
        /* open up our libpcap packet capture interface */
        OpenPcap(pv.interface);
    }
    else
    {

#ifdef DEBUG
        printf("Opening file: %s\n", pv.readfile);
#endif

        OpenPcap(pv.readfile);
    }

    CreatePidFile(pv.interface);


    if(pv.chroot_dir != NULL) 
    {
       if(chdir(pv.chroot_dir) < 0)
          FatalError("Can not chdir to \"%s\"\n",pv.chroot_dir);

       if(chroot(pv.chroot_dir) < 0)
          FatalError("Can not chroot to %s\n",pv.chroot_dir);

       if(chdir("/") < 0)
          FatalError("Can not chdir to \"/\"\n");
    }

   
    /* set safe userID/groupID if needed */
    SetUidGid();

    /* if the logging flag hasn't been set yet... */
    if(!pv.log_flag)
    {
        /* ...set the default logging dir */
        strncpy(pv.log_dir,DEFAULT_LOG_DIR,strlen(DEFAULT_LOG_DIR)+1);  
    }

    if (pv.use_rules || pv.log_flag)
    {
        /* perform some sanity checks on the output directory, etc*/
        SanityChecks();
    }

    if (pv.use_rules && pv.rules_order_flag)
    {
        printf("Rule application order changed to Pass->Alert->Log\n");
    }

    /* we're not using rules, sniffing to the screen, or logging packets
       so we don't really need to run... */
    if (!pv.use_rules && !pv.verbose_flag && !pv.log_flag)
    {
        /* give them a nice little reminder that Snort needs to be told what
           to do */
        printf("\n\nUh, you need to tell me to do something....\n\n");
        DisplayBanner();
        ShowUsage(progname);
        exit(0);
    }

    /* if daemon mode requested, fork daemon first, otherwise
     * on linux interface will be reset.
     */
    if (pv.daemon_flag)
    {
#ifdef DEBUG
        printf("Entering daemon mode\n");
#endif
        GoDaemon();
    }

/*    if (!pv.readmode_flag)
    {
#ifdef DEBUG
        printf("Opening interface: %s\n", pv.interface);
#endif
        OpenPcap(pv.interface);
    }
    else
    {

#ifdef DEBUG
        printf("Opening file: %s\n", pv.readfile);
#endif

        OpenPcap(pv.readfile);
    }

    CreatePidFile(pv.interface);
*/
#ifdef DEBUG
    printf("Setting Packet Processor\n");
#endif

    /* set the packet processor (ethernet, slip or raw)*/
    SetPktProcessor();

    if (pv.use_rules)
    {
        InitPreprocessors();
        InitPlugIns();
        InitOutputPlugins();
#ifdef DEBUG
        DumpPreprocessors();
        DumpPlugIns();
        DumpOutputPlugins();
#endif
        ParseRulesFile(pv.config_file, 0);
    }

    /* Tell 'em who wrote it, and what "it" is */
    if ( !pv.quiet_flag )
        DisplayBanner();

    if (pv.alert_cmd_override)
    {
        /* if a command line alert override has been specified, setup the
           approriate function pointer */

        /* if we're using syslog alerting set the alert function pointer to
           the syslog alerting function */
        if (pv.syslog_flag)
        {
            AddFuncToOutputList(SyslogAlert, NT_OUTPUT_ALERT, NULL);
            openlog("snort", LOG_PID|LOG_NDELAY|LOG_NOWAIT, LOG_AUTH);
        }
        else if (pv.smbmsg_flag)
        {
#ifdef ENABLE_SMB_ALERTS
            AddFuncToOutputList(SmbAlert, NT_OUTPUT_ALERT, NULL);
#else
            FatalError("ERROR: SMB support not compiled into program, exiting...\n");
#endif
        }
        else
        {
            switch (pv.alert_mode)
            {
                case ALERT_FAST:
                    alert = OpenAlertFile(NULL);
                    AddFuncToOutputList(FastAlert, NT_OUTPUT_ALERT, NULL);

                    break;

                case ALERT_FULL:
                    alert = OpenAlertFile(NULL);
                    AddFuncToOutputList(FullAlert, NT_OUTPUT_ALERT, NULL);

                    break;

                case ALERT_NONE:
                    SetOutputList(NoAlert, NT_OUTPUT_ALERT, NULL);

                    break;

                case ALERT_UNSOCK:
                    AddFuncToOutputList(UnixSockAlert, NT_OUTPUT_ALERT, NULL);
                    OpenAlertSock();

                    break;
            }
        }
    }
    
    if (AlertList == NULL && pv.use_rules) {
        alert = OpenAlertFile(NULL);
        AddFuncToOutputList(FullAlert, NT_OUTPUT_ALERT, NULL);
    }

    AlertFunc = CallAlertPlugins;

    if (pv.log_cmd_override)
    {
        if (pv.logbin_flag)
        {
#ifdef DEBUG
            printf("Initializing output file\n");
#endif
            InitBinLogFile();

            AddFuncToOutputList(LogBin, NT_OUTPUT_LOG, NULL);
        }
        else /* if we're not logging in tcpdump format... */
        {
            /* set the logging function pointer */
            if (!pv.nolog_flag)
                AddFuncToOutputList(LogPkt, NT_OUTPUT_LOG, NULL);
            else
                SetOutputList(NoLog, NT_OUTPUT_LOG, NULL);
        }
    }

    if (LogList == NULL)
        AddFuncToOutputList(LogPkt, NT_OUTPUT_LOG, NULL);

    LogFunc = CallLogPlugins;

/*
#ifdef ENABLE_RESPONSE
#ifdef DEBUG
    printf("Opening Raw Socket for Sending\n");
#endif

    if ((nd = libnet_open_raw_sock(IPPROTO_RAW)) < 0)
    {
        FatalError("ERROR: cannot open raw socket for libnet, exiting...\n");
    }
#endif

    if(pv.chroot_dir != NULL) 
    {
       if(chdir(pv.chroot_dir) < 0)
          FatalError("Can not chdir to \"%s\"\n",pv.chroot_dir);

       if(chroot(pv.chroot_dir) < 0)
          FatalError("Can not chroot to %s\n",pv.chroot_dir);

       if(chdir("/") < 0)
          FatalError("Can not chdir to \"/\"\n");
    }

    SetUidGid();
*/

#ifdef DEBUG
    printf("Entering pcap loop\n");
#endif
    /* Read all packets on the device.  Continue until cnt packets read */
    if (pcap_loop(pd, pv.pkt_cnt, (pcap_handler)ProcessPacket, NULL) < 0)
    {
        if (pv.daemon_flag)
            syslog(LOG_CONS|LOG_DAEMON,"pcap_loop: %s", pcap_geterr(pd));
        else
            PrintFmtError("pcap_loop: %s", pcap_geterr(pd));

        CleanExit(SIGQUIT);
    }

    /* close the capture interface */
    pcap_close(pd);

    CleanExit(SIGQUIT);

    return 0;
}




void ProcessPacket(char *user, struct pcap_pkthdr *pkthdr, u_char *pkt)
{
    Packet p;

    /* call the packet decoder */
    (*grinder)(&p, pkthdr, pkt);

    /* print the packet to the screen */
    if (pv.verbose_flag)
    {
        if (p.iph != NULL)
        {
            PrintIPPkt(stdout, p.iph->ip_proto, &p);
        }
        else if (p.ah != NULL && pv.showarp_flag)
        {
            PrintArpHeader(stdout, &p);

            if (pv.log_flag)
            {
                LogArpPkt(&p);
            }
        }
    }

    /* check or log the packet as necessary */
    if (!pv.use_rules)
    {
        if (pv.log_flag)
        {
            if (pv.logbin_flag)
            {
                LogBin(&p, NULL, NULL);
            }
            else
            {
                if (p.iph != NULL)
                    LogPkt(&p, NULL, NULL);

                if (p.ah != NULL)
                {
                    if (!pv.nolog_flag)
                    {
                        OpenLogFile(ARP, &p);

                        PrintArpHeader(log_ptr, &p);

                        fclose(log_ptr);
                    }
                }
            }
        }
    }
    else
    {
        Preprocess(&p);
    }

    ClearDumpBuf();

}


/****************************************************************************
 *
 * Function: ShowUsage(char *)
 *
 * Purpose:  Display the program options and exit
 *
 * Arguments: progname => name of the program (argv[0])
 *
 * Returns: 0 => success
 *
 ****************************************************************************/
int ShowUsage(char *progname)
{
    printf("USAGE: %s [-options] <filter options>\n", progname);
    puts("Options:");
    puts("        -A         Set alert mode: fast, full, or none "
         " (alert file alerts only)"
         "\n                  \"unsock\" enables UNIX socket logging (experimental).");
    puts("        -a         Display ARP packets");
    puts("        -b         Log packets in tcpdump format (much faster!)");
    puts("        -c <rules> Use Rules File <rules>");
    puts("        -C         Print out payloads with character data only (no hex)");
    puts("        -d         Dump the Application Layer");
    puts("        -D         Run Snort in background (daemon) mode");
    puts("        -e         Display the second layer header info");
    puts("        -F <bpf>   Read BPF filters from file <bpf>");
    puts("        -g <gname> Run snort gid as `gname' user or uid after initialization");
    puts("        -h <hn>    Home network = <hn>");
    puts("        -i <if>    Listen on interface <if>");
    puts("        -l <ld>    Log to directory <ld>");
#ifdef ENABLE_SMB_ALERTS
    puts("        -M <wrkst> Sends SMB message to workstations in file <wrkst>");
    puts("                   (Requires smbclient to be in PATH)");
#endif
    puts("        -n <cnt>   Exit after receiving <cnt> packets");
    puts("        -N         Turn off logging (alerts still work)");
    puts("        -o         Change the rule testing order to Pass|Alert|Log");
    puts("        -O         Obfuscate the logged IP addresses");
    puts("        -p         Disable promiscuous mode sniffing");
    printf("        -P <snap>  set explicit snaplen of packet (default: %d)\n",
           SNAPLEN);
    puts("        -q         Quiet. Don't show banner and status report");
    puts("        -r <tf>    Read and process tcpdump file <tf>");
    puts("        -s         Log alert messages to syslog");
    puts("        -S <n=v>   Set rules file variable n equal to value v");
    puts("        -t <chrt>  Chroots process to <chrt> after initialisaton");
    puts("        -u <uname> Run snort uid as `uname' user (or uid) after initialization");
    puts("        -v         Be verbose");
    puts("        -V         Show version number");
    puts("        -X         Dump the raw packet data starting at the link layer");
/* Nobody really uses this, do they?
   puts("        -6         Display IPv6 packets");
   puts("        -x         Display IPX packets");
*/
    puts("        -?         Show this information");
    puts("<Filter Options> are standard BPF options, as seen in TCPDump");

    fflush(stdout);

    return 0;
}



/****************************************************************************
 *
 * Function: ParseCmdLine(int, char *)
 *
 * Purpose:  Parse command line args
 *
 * Arguments: argc => count of arguments passed to the routine
 *            argv => 2-D character array, contains list of command line args
 *
 * Returns: 0 => success, 1 => exit on error
 *
 ****************************************************************************/

extern char *optarg;          /* for getopt */
extern int optind;            /* for getopt */

int ParseCmdLine(int argc, char *argv[])
{
    int ch;                      /* storage var for getopt info */
    int read_bpf = 0;
    char bpf_file[STD_BUF];

⌨️ 快捷键说明

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