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

📄 snort.c

📁 该源码是用C语言编写的,实现网络入侵检测系统的功能
💻 C
📖 第 1 页 / 共 5 页
字号:
/* $Id: snort.c,v 1.52 2001/01/26 16:40:44 roesch Exp $ */
/*
** Copyright (C) 1998,1999,2000,2001 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"

/*  G L O B A L S  ************************************************************/
extern OutputFuncNode *AlertList;
extern OutputFuncNode *LogList;
/*extern char *malloc_options;*/

/*
 *
 * 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[])
{
#ifdef USE_PTHREADS
    int i;

#endif
#ifndef WIN32
	#if defined(LINUX) || defined(FREEBSD) || defined(OPENBSD) || defined(SOLARIS)
		sigset_t set;

		sigemptyset(&set);
		sigprocmask(SIG_SETMASK, &set, NULL);
	#else
		sigsetmask(0);
	#endif
#endif
/*    malloc_options = "AX";*/

    /* make this prog behave nicely when signals come along */
    signal(SIGKILL, CleanExit);
    signal(SIGTERM, CleanExit);
    signal(SIGINT, CleanExit);
    signal(SIGQUIT, CleanExit);
    signal(SIGHUP, CleanExit);
    signal(SIGUSR1, DropStats);

    /* 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;

#ifdef WIN32
	if (!init_winsock())
		FatalError("[!] ERROR: Could not Initialize Winsock!\n");
#endif

    /*
     * setup some lookup data structs
     */
    InitNetmasks();
    InitProtoNames();

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

    /* set the alert filename to NULL */
    pv.alert_filename = NULL;

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

    /*
     * provide (limited) status messages by default
     */
    pv.quiet_flag = 0;

    ifr_count = 0;

#ifdef USE_PTHREADS
    pt_lock = PTHREAD_MUTEX_INITIALIZER;
#endif

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

    if(pv.use_utc == 1)
    {
        thiszone = 0;
    }
    else
    {
        /* set the timezone (ripped from tcpdump) */
        thiszone = gmt2local(0);
    }

    /*
     * make sure we've got the privs to continue
     */
    if(!pv.readmode_flag && geteuid() != SNIFFUSER)
    {
        DisplayBanner();
        ShowUsage(progname);
        printf("\n\nDude, you need root priveleges to run Snort in this mode!\n\n");
        exit(1);
    }
    if(!pv.quiet_flag)
    {
        printf("\n        --== Initializing Snort ==--\n");
    }
    /* 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 || pv.daemon_flag)
    {
        /* perform some sanity checks on the output directory, etc */
        /* first perform some sanity checks on the output directory, etc ... */
        SanityChecks();

        /* ... then create a PID file if not reading from a file */
        if (!pv.readmode_flag && pv.daemon_flag)
#ifdef WIN32
	    CreatePidFile("WIN32");
#else
            CreatePidFile(pv.interfaces[0]);
#endif
    }
    if(pv.use_rules && pv.rules_order_flag)
    {
        if(!pv.quiet_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
         */
        DisplayBanner();
        ShowUsage(progname);
        PrintError("\n\nUh, you need to tell me to do something....\n\n");
        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 no interfaces were specified we would need one anyway
     */
    if(!ifr_count)
        ifr_count++;

    /*
     * if we're not reading packets from a file, open the network interface
     * for reading
     */
    if(!pv.readmode_flag)
    {
#ifdef DEBUG
#ifdef WIN32
		printf("Opening interface: %s\n", print_interface(pv.interfaces[0]));
#else
        printf("Opening interface: %s\n", pv.interfaces[0]);
#endif
#endif
        /* open up our libpcap packet capture interface */
        InitializeInterfaces();
    }
    else
    {
#ifdef DEBUG
        printf("Opening file: %s\n", pv.readfile);
#endif

        /* open the packet file for readback */
        OpenPcap(pv.readfile, 0);
    }

    /*
     * creating a PID file before setting its proper
     * path (in SanityChecks()) is not a good idea
     */
    if((!(pv.use_rules || pv.log_flag) || pv.daemon_flag) && !pv.readmode_flag)
    {
#ifdef WIN32
		CreatePidFile("WIN32");
#else
        CreatePidFile(pv.interfaces[0]);
#endif
    }

#ifndef WIN32
    /* Don't need root privelege anymore, so lets drop ownership
     * and chroot if requested....
     */

    if(chrootdir != NULL)
    {
        if(chdir(chrootdir) < 0)
            FatalError("Can not chdir to \"%s\"\n", chrootdir);
        if(chroot(chrootdir) < 0)
            FatalError("Can not chroot to %s\n", chrootdir);
        if(chdir("/") < 0)
            FatalError("Can not chdir to \"/\"\n");

        chrootdir = NULL;        /* we don't need chrootdir anymore so all
                                 * other routines should use fullpath. */
    }
    /* set safe userID/groupID if needed */
    SetUidGid();
#endif
#ifdef DEBUG
    printf("Setting Packet Processor\n");
#endif

    /* set the packet processor (ethernet, slip, t/r, etc ) */
    SetPktProcessors();

    /* if we're using the rules system, it gets initialized here */
    if(pv.use_rules)
    {
        /* initialize all the plugin modules */
        InitPreprocessors();
        InitPlugIns();
        InitOutputPlugins();

#ifdef DEBUG
        DumpPreprocessors();
        DumpPlugIns();
        DumpOutputPlugins();
#endif

        /* setup the default rule action anchor points */
        CreateDefaultRules();

        if(pv.rules_order_flag)
        {
            OrderRuleLists("pass alert log");
        }
        ParseRulesFile(pv.config_file, 0);

        if(!pv.quiet_flag)
        {
            printRuleOrder();
        }
    }
    if(!pv.quiet_flag)
    {
        printf("\n        --== Initialization Complete ==--\n");
    }
    /* 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
         * appropriate 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(pv.alert_filename);
                    AddFuncToOutputList(FastAlert, NT_OUTPUT_ALERT, NULL);
                    break;

                case ALERT_FULL:
                    alert = OpenAlertFile(pv.alert_filename);
                    AddFuncToOutputList(FullAlert, NT_OUTPUT_ALERT, NULL);
                    break;

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

                    break;

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

                    break;
            }
        }
    }
    /* set the default alert function (alert full) */
    if(AlertList == NULL && pv.use_rules == 1)
    {
        alert = OpenAlertFile(pv.alert_filename);
        AddFuncToOutputList(FullAlert, NT_OUTPUT_ALERT, NULL);
    }
    /* set the alert function pointer list to call all the output plugins */
    AlertFunc = CallAlertPlugins;

    if(pv.log_cmd_override)
    {
        /* logging to a tcpdump file, initialize the output file and pointer */
        if(pv.logbin_flag)
        {
#ifdef DEBUG
            printf("Initializing output file\n");
#endif
            InitBinLogFile(pv.binLogFile);

            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 DEBUG
    printf("Entering pcap loop\n");
#endif

#ifdef USE_PTHREADS
    /*
     * With pthreads each interface gets a thread of its own.
     * 
     */
    for(i = 0; i < ifr_count; i++)
    {
        pthread_create(&pt[i], NULL, InterfaceThread, NULL);
    }

    while(1)
    {
        sleep(10);
    }

#else
    /* Without pthreads one interface goes in main thread */
    InterfaceThread(NULL);
#endif

    return 0;
}




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

#ifdef USE_PTHREADS
    pthread_mutex_lock(&pt_lock);
#endif
    /* 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)
        {
            PrintArpHeader(stdout, &p);

⌨️ 快捷键说明

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