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

📄 snort.c

📁 该软件是一个有名的基于网络的入侵检测系统
💻 C
📖 第 1 页 / 共 4 页
字号:
            }

            grinder = DecodePppPkt;
            break;

        case DLT_NULL: /* loopback and stuff.. you wouldn't perform intrusion
                        * detection on it, but it's ok for testing.
                        */
            if (!pv.readmode_flag)
                printf("   => Decoding LoopBack on interface %s\n", pv.interface);
            else
                printf("Entering readback mode....\n");

            if (pv.show2hdr_flag == 1)
            {
                printf("Second layer header parsing for this datalink "
                       "isn't implemented yet\n");
                pv.show2hdr_flag = 0;
            }

            grinder = DecodeNullPkt;

            break;

#ifdef DLT_RAW /* Not supported in some arch or older pcap versions */
        case DLT_RAW:
            if (!pv.readmode_flag)
                printf("   => Decoding raw data on interface %s\n", pv.interface);
            else
                printf("Entering readback mode....\n");

            if (pv.show2hdr_flag == 1)
            {
                printf("There's no second layer header available for this datalink\n");
                pv.show2hdr_flag = 0;
            }

            grinder = DecodeRawPkt;

            break;
#endif
            /* you need the I4L modified version of libpcap
            to get this stuff working */
#ifdef DLT_I4L_RAWIP
        case DLT_I4L_RAWIP:  
            printf("   => Decoding I4L-rawip on interface %s\n", pv.interface);
            grinder = DecodeI4LRawIPPkt;
            break;
#endif

#ifdef DLT_I4L_IP
        case DLT_I4L_IP:
            printf("   => Decoding I4L-ip on interface %s\n", pv.interface);
            grinder = DecodeEthPkt;
            break;
#endif

#ifdef DLT_I4L_CISCOHDLC
        case DLT_I4L_CISCOHDLC:
            printf("   => Decoding I4L-cisco-h on interface %s\n", pv.interface);
            grinder = DecodeI4LCiscoIPPkt;
            break;
#endif


        default:  /* oops, don't know how to handle this one */
            PrintFmtError("\n%s cannot handle data link type %d", 
                          progname, datalink);
            CleanExit(SIGQUIT);
    }

    return 0;
}


/****************************************************************************
 *
 * Function: OpenPcap(char *)
 *
 * Purpose:  Open the libpcap interface
 *
 * Arguments: intf => name of the interface to open 
 *
 * Returns: 0 => success, exits on problems
 *
 ****************************************************************************/
int OpenPcap(char *intf)
{
    bpf_u_int32 localnet, netmask;    /* net addr holders */
    struct bpf_program fcode;         /* Finite state machine holder */
    char errorbuf[PCAP_ERRBUF_SIZE];  /* buffer to put error strings in */
    bpf_u_int32 defaultnet = 0xFFFFFF00;

    printf("\nInitializing Network Interface...\n");

    if (pv.interface == NULL)
    {
#ifdef DEBUG
        printf("pv.interface is NULL, looking up interface....   ");
#endif
        /* look up the device and get the handle */
        pv.interface = pcap_lookupdev(errorbuf);
#ifdef DEBUG
        printf("found interface %s\n", pv.interface);
#endif 
        /* uh oh, we couldn't find the interface name */
        if (pv.interface == NULL)
        {
            FatalError("ERROR: OpenPcap() interface lookup: \n\t%s\n", errorbuf);
        }
    }

    /* if we're not reading packets from a file */
    if (!pv.readmode_flag)
    {
        if (pv.pkt_snaplen)  /* if it's set let's try it... */
        {
            if (pv.pkt_snaplen < MIN_SNAPLEN)   /* if it's < MIN set it to MIN */
            {
                snaplen = MIN_SNAPLEN;
            }
            else
            {
                snaplen = pv.pkt_snaplen;
            }
        }
        else
        {
            snaplen = SNAPLEN; /* otherwise let's put the compiled value in */
        }

#ifdef DEBUG
        printf("snaplength info: set=%d/compiled=%d/wanted=%d\n", snaplen,
               SNAPLEN, pv.pkt_snaplen);
#endif

        /* get the device file descriptor */
        pd = pcap_open_live(pv.interface, snaplen,
                            pv.promisc_flag ? PROMISC : 0, READ_TIMEOUT, errorbuf);
    }
    else /* reading packets from a file */
    {
        /* open the file */
        pd = pcap_open_offline(intf, errorbuf);

        /* the file didn't open correctly */
        if (pd == NULL)
        {
            FatalError("ERROR => unable to open file %s for readback: %s\n", 
                       intf, errorbuf);
        }

        /* set the snaplen for the file (so we don't get a lot of extra
           crap in the end of packets */
        snaplen = pcap_snapshot(pd);

        printf("snaplen = %d\n", snaplen);
    }

    /* something is wrong with the opened packet socket */
    if (pd == NULL)
    {
        FatalError("ERROR: OpenPcap() device %s open: \n\t%s\n", 
                   pv.interface, errorbuf);
    }

    /* get local net and netmask */
    if (pcap_lookupnet(pv.interface, &localnet, &netmask, errorbuf) < 0)
    {
        ErrorMessage("WARNING: OpenPcap() device %s network lookup: \n\t%s\n", 
                   pv.interface, errorbuf);
    
        /* set the default netmask to 255.255.255.0 (for stealthed interfaces) */
        netmask = htonl(defaultnet);
    }

    

    /* compile BPF filter spec info fcode FSM */
    if (pcap_compile(pd, &fcode, pv.pcap_cmd, 1, netmask) < 0)
    {
        ErrorMessage("ERROR: OpenPcap() FSM compilation failed: \n\t%s\n", 
                     pcap_geterr(pd));
        FatalError("PCAP command: %s\n", pv.pcap_cmd);
    }

    /* set the pcap filter */
    if (pcap_setfilter(pd, &fcode) < 0)
    {
        FatalError("ERROR: OpenPcap() setfilter: \n\t%s\n", pcap_geterr(pd));
    }

    /* get data link type */
    datalink = pcap_datalink(pd);

    if (datalink < 0)
    {
        FatalError("ERROR: OpenPcap() datalink grab: \n\t%s\n", pcap_geterr(pd));
    }

    return 0;
}

/****************************************************************************
 *
 * Function: CleanExit()
 *
 * Purpose:  Clean up misc file handles and such and exit
 *
 * Arguments: Signal
 *
 * Returns: void function
 *
 ****************************************************************************/

extern PluginSignalFuncNode *PluginCleanExitList;
extern PluginSignalFuncNode *PluginRestartList;

void CleanExit(int sig)
{
    struct pcap_stat ps;
    float drop;
    float recv;
    PluginSignalFuncNode *idx;

    /* make sure everything that needs to go to the screen gets there */
    fflush(stdout);

    if (sig != SIGHUP)
        printf("\nExiting...\n");
    else
        printf("\nRestaring...\n");

    if (pv.logbin_flag)
    {
        pcap_dump_close(dumpd);
    }

    unlink(pv.pid_filename);
    pv.pid_filename[0] = 0;

    if (pv.alert_mode == ALERT_FAST || pv.alert_mode == ALERT_FULL)
    {
        if (alert != NULL)
            fclose(alert);
    }

    /* carry signals down to plugins */
    if(sig != SIGHUP) 
    {
        idx = PluginCleanExitList;
    } 
    else 
    {
        idx = PluginRestartList;
    }

    while(idx != NULL) 
    {
         idx->func(sig, idx->arg);
         idx = idx->next;
    }

    if (pv.readmode_flag)
    {
        puts("\n\n===============================================================================");

        recv = pc.tcp+pc.udp+pc.icmp+pc.arp+pc.ipx+pc.ipv6+pc.other;

        printf("Snort processed %d packets.\n", (int) recv);

        puts("Breakdown by protocol:");
        printf("    TCP: %-10ld (%.3f%%)\n", pc.tcp, CalcPct((float)pc.tcp, recv));
        printf("    UDP: %-10ld (%.3f%%)\n", pc.udp, CalcPct((float)pc.udp, recv));
        printf("   ICMP: %-10ld (%.3f%%)\n", pc.icmp, CalcPct((float)pc.icmp, recv));
        printf("  FRAGS: %-10ld (%.3f%%)\n", pc.frags, CalcPct((float)pc.frags, recv));
        printf("    ARP: %-10ld (%.3f%%)\n", pc.arp, CalcPct((float)pc.arp, recv));
        printf("   IPv6: %-10ld (%.3f%%)\n", pc.ipv6, CalcPct((float)pc.ipv6, recv));
        printf("    IPX: %-10ld (%.3f%%)\n", pc.ipx, CalcPct((float)pc.ipx, recv));
        printf("  OTHER: %-10ld (%.3f%%)\n", pc.other, CalcPct((float)pc.other, recv));
        puts("\n\n===============================================================================");

        exit_or_exec(0, sig);
        exit(0);
    }

    if (pd == NULL)
        exit(1);

    /* collect the packet stats */
    if (pcap_stats(pd, &ps))
    {
        pcap_perror(pd, "pcap_stats");
    }
    else
    {
        recv = ps.ps_recv;
        drop = ps.ps_drop;

        puts("\n\n===============================================================================");
        printf("Snort received %d packets", ps.ps_recv);

        if (ps.ps_recv)
        {
#ifndef LINUX
            printf(" and dropped %d(%.3f%%) packets\n\n", ps.ps_drop, 
                   CalcPct(drop, recv));
#else
            printf(".\nPacket loss statistics are unavailable under Linux.  Sorry!\n\n");
#endif
        }
        else
        {
            puts(".\n");
        }
        puts("Breakdown by protocol:");
        printf("    TCP: %-10ld (%.3f%%)\n", pc.tcp, CalcPct((float)pc.tcp, recv));
        printf("    UDP: %-10ld (%.3f%%)\n", pc.udp, CalcPct((float)pc.udp, recv));
        printf("   ICMP: %-10ld (%.3f%%)\n", pc.icmp, CalcPct((float)pc.icmp, recv));
        printf("  FRAGS: %-10ld (%.3f%%)\n", pc.frags, CalcPct((float)pc.frags, recv));
        printf("    ARP: %-10ld (%.3f%%)\n", pc.arp, CalcPct((float)pc.arp, recv));
        printf("   IPv6: %-10ld (%.3f%%)\n", pc.ipv6, CalcPct((float)pc.ipv6, recv));
        printf("    IPX: %-10ld (%.3f%%)\n", pc.ipx, CalcPct((float)pc.ipx, recv));
        printf("  OTHER: %-10ld (%.3f%%)\n", pc.other, CalcPct((float)pc.other, recv));

        puts("===============================================================================");
    }


    pcap_close(pd);

    exit_or_exec(0, sig);
    exit(0);
}



/*
 *
 * exit_or_exec()
 * Arguments: status, signal received.
 *
 * This function performs exec on SIGHUP signal and exit otherwise
 *
 */
void exit_or_exec(int stat, int sig)
{

    if ( sig != SIGHUP )
        exit(stat);
    else
    {
        syslog(LOG_DAEMON|LOG_NOTICE,"Received SIGHUP. Restarting");

#ifdef PARANOID
        execv(progname,progargs);
#else
        execvp(progname,progargs);
#endif

        syslog(LOG_DAEMON|LOG_NOTICE,"Restarting %s failed",progname);
        exit(1);
    }
}

/****************************************************************************
 *
 * Function: CalcPct(float, float)
 *
 * Purpose:  Calculate the percentage of a value compared to a total
 *
 * Arguments: cnt => the numerator in the equation
 *            total => the denominator in the calculation
 *
 * Returns: pct -> the percentage of cnt to value
 *
 ****************************************************************************/
float CalcPct(float cnt, float total)
{
    float pct;

    if (cnt > 0.0)
        pct = cnt/total;
    else
        return 0.0;

    pct *= 100.0;

    return pct;
}


/****************************************************************************
 *
 * Function: DisplayBanner()
 *
 * Purpose:  Show valuable proggie info
 *
 * Arguments: None.
 *
 * Returns: 0 all the time
 *
 ****************************************************************************/
int DisplayBanner()
{
    printf("\n-*> Snort! <*-\nVersion %s\nBy Martin Roesch (roesch@clark.net, www.snort.org)\n", VERSION);
    return 0;
}



/****************************************************************************
 *  
 * Function: ts_print(register const struct, char *)
 * 
 * Purpose: Generate a time stamp and stuff it in a buffer.  This one has
 *          millisecond precision.  Oh yeah, I ripped this code off from
 *          TCPdump, props to those guys.
 * 
 * Arguments: timeval => clock struct coming out of libpcap
 *            timebuf => buffer to stuff timestamp into
 *      
 * Returns: void function
 * 
 ****************************************************************************/
void ts_print(register const struct timeval *tvp, char *timebuf)
{
    register int s;  
    struct timeval tv;
    struct timezone tz;
    struct tm *lt;   /* place to stick the adjusted clock data */

    /* if null was passed, we use current time */
    if (!tvp)
    {
        /* manual page (for linux) says tz is never used, so.. */
        bzero((char *)&tz,sizeof(tz));
        gettimeofday(&tv,&tz);
        tvp=&tv;
    }
    lt = localtime((time_t *)&tvp->tv_sec);

    s = (tvp->tv_sec + thiszone) % 86400;

    (void)sprintf(timebuf, "%02d/%02d-%02d:%02d:%02d.%06u ", lt->tm_mon+1, 
                  lt->tm_mday, s / 3600, (s % 3600) / 60, s % 60, 
                  (u_int)tvp->tv_usec);
}



/****************************************************************************
 *  
 * Function: gmt2local(time_t)
 * 
 * Purpose: Figures out how to adjust the current clock reading based on the
 *          timezone you're in.  Ripped off from TCPdump.
 * 
 * Arguments: time_t => offset from GMT
 *      
 * Returns: offset seconds from GMT
 * 
 ****************************************************************************/
int gmt2local(time_t t)
{
    register int dt, dir;
    register struct tm *gmt, *loc;
    struct tm sgmt;

    if (t == 0)
        t = time(NULL);

    gmt = &sgmt;
    *gmt = *gmtime(&t);
    loc = localtime(&t);

    dt = (loc->tm_hour - gmt->tm_hour) * 60 * 60 + 
         (loc->tm_min - gmt->tm_min) * 60;

    /* If the year or julian day is different, we span 00:00 GMT
      and must add or subtract a day. Check the year first to
      avoid problems when the julian day wraps. */

    dir = loc->tm_year - gmt->tm_year;

    if (dir == 0)
        dir = loc->tm_yday - gmt->tm_yday;

    dt += dir * 24 * 60 * 60;

    return(dt);
}




/****************************************************************************
 *
 * Function: copy_argv(u_char **)
 *
 * Purpose: Copies a 2D array (like argv) into a flat string.  Stolen from
 *          TCPDump.
 *
 * Arguments: argv => 2D array to flatten
 *
 * Returns: Pointer to the flat string
 *
 ****************************************************************************/
char *copy_argv(char **argv)
{
    char **p;
    u_int len = 0;
    char *buf;
    char *src, *dst;
    void ftlerr(char *, ...);

    p = argv;

⌨️ 快捷键说明

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