コード例 #1
0
ファイル: util-ioctl.c プロジェクト: micsoftvn/suricata
static int GetIfaceOffloadingBSD(const char *ifname)
{
    int ret = 0;
    int if_caps = GetIfaceCaps(ifname);
    if (if_caps == -1) {
        return -1;
    }
    SCLogDebug("if_caps %X", if_caps);

    if (if_caps & IFCAP_RXCSUM) {
        SCLogWarning(SC_ERR_NIC_OFFLOADING,
                "Using %s with RXCSUM activated can lead to capture "
                "problems. Run: ifconfig %s -rxcsum", ifname, ifname);
        ret = 1;
    }
#ifdef IFCAP_TOE
    if (if_caps & (IFCAP_TSO|IFCAP_TOE|IFCAP_LRO)) {
        SCLogWarning(SC_ERR_NIC_OFFLOADING,
                "Using %s with TSO, TOE or LRO activated can lead to "
                "capture problems. Run: ifconfig %s -tso -toe -lro",
                ifname, ifname);
        ret = 1;
    }
#else
    if (if_caps & (IFCAP_TSO|IFCAP_LRO)) {
        SCLogWarning(SC_ERR_NIC_OFFLOADING,
                "Using %s with TSO or LRO activated can lead to "
                "capture problems. Run: ifconfig %s -tso -lro",
                ifname, ifname);
        ret = 1;
    }
#endif
    return ret;
}
コード例 #2
0
ファイル: stream.c プロジェクト: jerryma119/suricata
/** \brief Run callback for all segments
 *
 * \return -1 in case of error, the number of segment in case of success
 */
int StreamSegmentForEach(Packet *p, uint8_t flag, StreamSegmentCallback CallbackFunc, void *data)
{
    switch(p->proto) {
        case IPPROTO_TCP:
            return StreamTcpSegmentForEach(p, flag, CallbackFunc, data);
            break;
        case IPPROTO_UDP:
            SCLogWarning(SC_ERR_UNKNOWN_PROTOCOL, "UDP is currently unsupported");
            break;
        default:
            SCLogWarning(SC_ERR_UNKNOWN_PROTOCOL, "This protocol is currently unsupported");
            break;
    }
    return 0;
}
コード例 #3
0
ファイル: source-nfq.c プロジェクト: vpiserchia/suricata
/**
 * \brief NFQ function to get a packet from the kernel
 *
 * \note separate functions for Linux and Win32 for readability.
 */
static void NFQRecvPkt(NFQQueueVars *t, NFQThreadVars *tv)
{
    int rv, ret;
    int flag = NFQVerdictCacheLen(t) ? MSG_DONTWAIT : 0;

    /* XXX what happens on rv == 0? */
    rv = recv(t->fd, tv->data, tv->datalen, flag);

    if (rv < 0) {
        if (errno == EINTR || errno == EWOULDBLOCK) {
            /* no error on timeout */
            if (flag)
                NFQVerdictCacheFlush(t);

            /* inject a fake packet on timeout */
            TmThreadsCaptureInjectPacket(tv->tv, tv->slot, NULL);
        } else {
#ifdef COUNTERS
            NFQMutexLock(t);
            t->errs++;
            NFQMutexUnlock(t);
#endif /* COUNTERS */
        }
    } else if(rv == 0) {
        SCLogWarning(SC_ERR_NFQ_RECV, "recv got returncode 0");
    } else {
#ifdef DBG_PERF
        if (rv > t->dbg_maxreadsize)
            t->dbg_maxreadsize = rv;
#endif /* DBG_PERF */

        //printf("NFQRecvPkt: t %p, rv = %" PRId32 "\n", t, rv);

        NFQMutexLock(t);
        if (t->qh != NULL) {
            ret = nfq_handle_packet(t->h, tv->data, rv);
        } else {
            SCLogWarning(SC_ERR_NFQ_HANDLE_PKT, "NFQ handle has been destroyed");
            ret = -1;
        }
        NFQMutexUnlock(t);

        if (ret != 0) {
            SCLogWarning(SC_ERR_NFQ_HANDLE_PKT, "nfq_handle_packet error %"PRId32" %s",
                    ret, strerror(errno));
        }
    }
}
コード例 #4
0
ファイル: tm-modules.c プロジェクト: P1sec/suricata
/** \brief register all unittests for the tm modules */
void TmModuleRegisterTests(void)
{
#ifdef UNITTESTS
    TmModule *t;
    uint16_t i;

    for (i = 0; i < TMM_SIZE; i++) {
        t = &tmm_modules[i];

        if (t->name == NULL)
            continue;

        g_ut_modules++;


        if (t->RegisterTests == NULL) {
            if (coverage_unittests)
                SCLogWarning(SC_WARN_NO_UNITTESTS, "threading module %s has no unittest "
                        "registration function.", t->name);
        } else {
            t->RegisterTests();
            g_ut_covered++;
        }
    }
#endif /* UNITTESTS */
}
コード例 #5
0
ファイル: source-nfq.c プロジェクト: norg/suricata
static void NFQVerdictCacheFlush(NFQQueueVars *t)
{
#ifdef HAVE_NFQ_SET_VERDICT_BATCH
    int ret;
    int iter = 0;

    do {
        if (t->verdict_cache.mark_valid)
            ret = nfq_set_verdict_batch2(t->qh,
                                         t->verdict_cache.packet_id,
                                         t->verdict_cache.verdict,
                                         t->verdict_cache.mark);
        else
            ret = nfq_set_verdict_batch(t->qh,
                                        t->verdict_cache.packet_id,
                                        t->verdict_cache.verdict);
    } while ((ret < 0) && (iter++ < NFQ_VERDICT_RETRY_TIME));

    if (ret < 0) {
        SCLogWarning(SC_ERR_NFQ_SET_VERDICT, "nfq_set_verdict_batch failed: %s",
                     strerror(errno));
    } else {
        t->verdict_cache.len = 0;
        t->verdict_cache.mark_valid = 0;
    }
#endif
}
コード例 #6
0
ファイル: util-ioctl.c プロジェクト: micsoftvn/suricata
static int SetEthtoolValue(const char *dev, int cmd, uint32_t value)
{
    struct ifreq ifr;
    int fd;
    struct ethtool_value ethv;

    fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (fd == -1) {
        return -1;
    }
    (void)strlcpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));

    ethv.cmd = cmd;
    ethv.data = value;
    ifr.ifr_data = (void *) &ethv;
    if (ioctl(fd, SIOCETHTOOL, (char *)&ifr) < 0) {
        SCLogWarning(SC_ERR_SYSCALL,
                  "Failure when trying to set feature via ioctl for '%s': %s (%d)",
                  dev, strerror(errno), errno);
        close(fd);
        return -1;
    }

    close(fd);
    return 0;
}
コード例 #7
0
/** \brief connect to the indicated local stream socket, logging any errors
 *  \param path filesystem path to connect to
 *  \param log_err, non-zero if connect failure should be logged.
 *  \retval FILE* on success (fdopen'd wrapper of underlying socket)
 *  \retval NULL on error
 */
static FILE *
SCLogOpenUnixSocketFp(const char *path, int sock_type, int log_err)
{
    struct sockaddr_un saun;
    int s = -1;
    FILE * ret = NULL;

    memset(&saun, 0x00, sizeof(saun));

    s = socket(PF_UNIX, sock_type, 0);
    if (s < 0) goto err;

    saun.sun_family = AF_UNIX;
    strlcpy(saun.sun_path, path, sizeof(saun.sun_path));

    if (connect(s, (const struct sockaddr *)&saun, sizeof(saun)) < 0)
        goto err;

    ret = fdopen(s, "w");
    if (ret == NULL)
        goto err;

    return ret;

err:
    if (log_err)
        SCLogWarning(SC_ERR_SOCKET,
            "Error connecting to socket \"%s\": %s (will keep trying)",
            path, strerror(errno));

    if (s >= 0)
        close(s);

    return NULL;
}
コード例 #8
0
ファイル: util-ioctl.c プロジェクト: micsoftvn/suricata
/**
 * \brief output the link MTU
 *
 * \param Name of link
 * \retval -1 in case of error, 0 if MTU can not be found
 */
int GetIfaceMTU(const char *pcap_dev)
{
#if defined SIOCGIFMTU
    struct ifreq ifr;
    int fd;

    (void)strlcpy(ifr.ifr_name, pcap_dev, sizeof(ifr.ifr_name));
    fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (fd == -1) {
        return -1;
    }

    if (ioctl(fd, SIOCGIFMTU, (char *)&ifr) < 0) {
        SCLogWarning(SC_ERR_SYSCALL,
                "Failure when trying to get MTU via ioctl for '%s': %s (%d)",
                pcap_dev, strerror(errno), errno);
        close(fd);
        return -1;
    }
    close(fd);
    SCLogInfo("Found an MTU of %d for '%s'", ifr.ifr_mtu,
            pcap_dev);
    return ifr.ifr_mtu;
#elif defined OS_WIN32
    return GetIfaceMTUWin32(pcap_dev);
#else
    /* ioctl is not defined, let's pretend returning 0 is ok */
    return 0;
#endif
}
コード例 #9
0
/**
 * \brief Reopen a regular log file with the side-affect of truncating it.
 *
 * This is useful to clear the log file and start a new one, or to
 * re-open the file after its been moved by something external
 * (eg. logrotate).
 */
int SCConfLogReopen(LogFileCtx *log_ctx)
{
    if (!log_ctx->is_regular) {
        /* Not supported and not needed on non-regular files. */
        return 0;
    }

    if (log_ctx->filename == NULL) {
        SCLogWarning(SC_ERR_INVALID_ARGUMENT,
            "Can't re-open LogFileCtx without a filename.");
        return -1;
    }

    fclose(log_ctx->fp);

    /* Reopen the file. Append is forced in case the file was not
     * moved as part of a rotation process. */
    SCLogDebug("Reopening log file %s.", log_ctx->filename);
    log_ctx->fp = SCLogOpenFileFp(log_ctx->filename, "yes");
    if (log_ctx->fp == NULL) {
        return -1; // Already logged by Open..Fp routine.
    }

    return 0;
}
コード例 #10
0
/**
 *  \brief Initialize the "magic" context.
 */
int MagicInit(void)
{
    BUG_ON(g_magic_ctx != NULL);

    SCEnter();

    char *filename = NULL;
    FILE *fd = NULL;

    SCMutexInit(&g_magic_lock, NULL);
    SCMutexLock(&g_magic_lock);

    g_magic_ctx = magic_open(0);
    if (g_magic_ctx == NULL) {
        SCLogError(SC_ERR_MAGIC_OPEN, "magic_open failed: %s",
                magic_error(g_magic_ctx));
        goto error;
    }

    (void)ConfGet("magic-file", &filename);


    if (filename != NULL) {
        if (strlen(filename) == 0) {
            /* set filename to NULL on *nix systems so magic_load uses system
             * default path (see man libmagic) */
            SCLogConfig("using system default magic-file");
            filename = NULL;
        }
        else {
            SCLogConfig("using magic-file %s", filename);

            if ( (fd = fopen(filename, "r")) == NULL) {
                SCLogWarning(SC_ERR_FOPEN, "Error opening file: \"%s\": %s",
                        filename, strerror(errno));
                goto error;
            }
            fclose(fd);
        }
    }

    if (magic_load(g_magic_ctx, filename) != 0) {
        SCLogError(SC_ERR_MAGIC_LOAD, "magic_load failed: %s",
                magic_error(g_magic_ctx));
        goto error;
    }

    SCMutexUnlock(&g_magic_lock);
    SCReturnInt(0);

error:
    if (g_magic_ctx != NULL) {
        magic_close(g_magic_ctx);
        g_magic_ctx = NULL;
    }

    SCMutexUnlock(&g_magic_lock);
    SCReturnInt(-1);
}
コード例 #11
0
ファイル: output-json-drop.c プロジェクト: bmeeks8/suricata
static OutputInitResult JsonDropLogInitCtx(ConfNode *conf)
{
    OutputInitResult result = { NULL, false };
    if (OutputDropLoggerEnable() != 0) {
        SCLogError(SC_ERR_CONF_YAML_ERROR, "only one 'drop' logger "
            "can be enabled");
        return result;
    }

    JsonDropOutputCtx *drop_ctx = SCCalloc(1, sizeof(*drop_ctx));
    if (drop_ctx == NULL)
        return result;

    drop_ctx->file_ctx = LogFileNewCtx();
    if (drop_ctx->file_ctx == NULL) {
        JsonDropOutputCtxFree(drop_ctx);
        return result;
    }

    if (SCConfLogOpenGeneric(conf, drop_ctx->file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) {
        JsonDropOutputCtxFree(drop_ctx);
        return result;
    }

    OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
    if (unlikely(output_ctx == NULL)) {
        JsonDropOutputCtxFree(drop_ctx);
        return result;
    }

    if (conf) {
        const char *extended = ConfNodeLookupChildValue(conf, "alerts");
        if (extended != NULL) {
            if (ConfValIsTrue(extended)) {
                drop_ctx->flags = LOG_DROP_ALERTS;
            }
        }
        extended = ConfNodeLookupChildValue(conf, "flows");
        if (extended != NULL) {
            if (strcasecmp(extended, "start") == 0) {
                g_droplog_flows_start = 1;
            } else if (strcasecmp(extended, "all") == 0) {
                g_droplog_flows_start = 0;
            } else {
                SCLogWarning(SC_ERR_CONF_YAML_ERROR, "valid options for "
                        "'flow' are 'start' and 'all'");
            }
        }
    }

    output_ctx->data = drop_ctx;
    output_ctx->DeInit = JsonDropLogDeInitCtx;

    result.ctx = output_ctx;
    result.ok = true;
    return result;
}
コード例 #12
0
ファイル: source-nfq.c プロジェクト: gcordrey/suricata
void NFQRecvPkt(NFQQueueVars *t, NFQThreadVars *tv) {
    int rv, ret;

    /* XXX what happens on rv == 0? */
    rv = recv(t->fd, tv->data, tv->datalen, 0);

    if (rv < 0) {
        if (errno == EINTR || errno == EWOULDBLOCK) {
            /* no error on timeout */
        } else {
#ifdef COUNTERS
            NFQMutexLock(t);
            t->errs++;
            NFQMutexUnlock(t);
#endif /* COUNTERS */
        }
    } else if(rv == 0) {
        SCLogWarning(SC_ERR_NFQ_RECV, "recv got returncode 0");
    } else {
#ifdef DBG_PERF
        if (rv > t->dbg_maxreadsize)
            t->dbg_maxreadsize = rv;
#endif /* DBG_PERF */

        //printf("NFQRecvPkt: t %p, rv = %" PRId32 "\n", t, rv);

        NFQMutexLock(t);
        if (t->qh != NULL) {
            ret = nfq_handle_packet(t->h, tv->data, rv);
        } else {
            SCLogWarning(SC_ERR_NFQ_HANDLE_PKT, "NFQ handle has been destroyed");
            ret = -1;
        }
        NFQMutexUnlock(t);

        if (ret != 0) {
            SCLogWarning(SC_ERR_NFQ_HANDLE_PKT, "nfq_handle_packet error %" PRId32 "", ret);
        }
    }
}
コード例 #13
0
ファイル: detect-filemagic.c プロジェクト: AmesianX/suricata
static void *DetectFilemagicThreadInit(void *data)
{
    char *filename = NULL;
    FILE *fd = NULL;
    DetectFilemagicData *filemagic = (DetectFilemagicData *)data;
    BUG_ON(filemagic == NULL);

    DetectFilemagicThreadData *t = SCMalloc(sizeof(DetectFilemagicThreadData));
    if (unlikely(t == NULL)) {
        SCLogError(SC_ERR_MEM_ALLOC, "couldn't alloc ctx memory");
        return NULL;
    }
    memset(t, 0x00, sizeof(DetectFilemagicThreadData));

    t->ctx = magic_open(0);
    if (t->ctx == NULL) {
        SCLogError(SC_ERR_MAGIC_OPEN, "magic_open failed: %s", magic_error(t->ctx));
        goto error;
    }

    (void)ConfGet("magic-file", &filename);
    if (filename != NULL) {
        if (strlen(filename) == 0) {
            /* set filename to NULL on *nix systems so magic_load uses system default path (see man libmagic) */
            SCLogInfo("using system default magic-file");
            filename = NULL;
        }
        else {
            SCLogInfo("using magic-file %s", filename);

            if ( (fd = fopen(filename, "r")) == NULL) {
                SCLogWarning(SC_ERR_FOPEN, "Error opening file: \"%s\": %s", filename, strerror(errno));
                goto error;
            }
            fclose(fd);
        }
    }

    if (magic_load(t->ctx, filename) != 0) {
        SCLogError(SC_ERR_MAGIC_LOAD, "magic_load failed: %s", magic_error(t->ctx));
        goto error;
    }

    return (void *)t;

error:
    if (t->ctx)
        magic_close(t->ctx);
    SCFree(t);
    return NULL;
}
コード例 #14
0
ファイル: source-nfq.c プロジェクト: vpiserchia/suricata
/**
 *  \brief Add a single Netfilter queue
 *
 *  \param string with the queue number
 *
 *  \retval 0 on success.
 *  \retval -1 on failure.
 */
int NFQRegisterQueue(const uint16_t number)
{
    NFQThreadVars *ntv = NULL;
    NFQQueueVars *nq = NULL;
    char queue[10] = { 0 };
    static bool many_queues_warned = false;
    uint16_t num_cpus = UtilCpuGetNumProcessorsOnline();

    if (g_nfq_t == NULL || g_nfq_q == NULL) {
        SCLogError(SC_ERR_INVALID_ARGUMENT, "NFQ context is not initialized");
        return -1;
    }

    SCMutexLock(&nfq_init_lock);
    if (!many_queues_warned && (receive_queue_num >= num_cpus)) {
        SCLogWarning(SC_WARN_UNCOMMON,
                     "using more Netfilter queues than %hu available CPU core(s) "
                     "may degrade performance",
                     num_cpus);
        many_queues_warned = true;
    }
    if (receive_queue_num >= NFQ_MAX_QUEUE) {
        SCLogError(SC_ERR_INVALID_ARGUMENT,
                   "can not register more than %d Netfilter queues",
                   NFQ_MAX_QUEUE);
        SCMutexUnlock(&nfq_init_lock);
        return -1;
    }

    ntv = &g_nfq_t[receive_queue_num];
    ntv->nfq_index = receive_queue_num;

    nq = &g_nfq_q[receive_queue_num];
    nq->queue_num = number;
    receive_queue_num++;
    SCMutexUnlock(&nfq_init_lock);
    snprintf(queue, sizeof(queue) - 1, "NFQ#%hu", number);
    LiveRegisterDevice(queue);

    ntv->livedev = LiveGetDevice(queue);

    if (ntv->livedev == NULL) {
        SCLogError(SC_ERR_INVALID_VALUE, "Unable to find Live device");
        return -1;
    }

    SCLogDebug("Queue %d registered.", number);
    return 0;
}
コード例 #15
0
ファイル: alert-syslog.c プロジェクト: P1sec/suricata
/**
 * \brief Create a new LogFileCtx for "syslog" output style.
 *
 * \param conf The configuration node for this output.
 * \return A OutputCtx pointer on success, NULL on failure.
 */
OutputCtx *AlertSyslogInitCtx(ConfNode *conf)
{
    const char *facility_s = ConfNodeLookupChildValue(conf, "facility");
    if (facility_s == NULL) {
        facility_s = DEFAULT_ALERT_SYSLOG_FACILITY_STR;
    }

    LogFileCtx *logfile_ctx = LogFileNewCtx();
    if (logfile_ctx == NULL) {
        SCLogDebug("AlertSyslogInitCtx: Could not create new LogFileCtx");
        return NULL;
    }

    int facility = SCMapEnumNameToValue(facility_s, SCSyslogGetFacilityMap());
    if (facility == -1) {
        SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Invalid syslog facility: \"%s\","
                " now using \"%s\" as syslog facility", facility_s,
                DEFAULT_ALERT_SYSLOG_FACILITY_STR);
        facility = DEFAULT_ALERT_SYSLOG_FACILITY;
    }

    const char *level_s = ConfNodeLookupChildValue(conf, "level");
    if (level_s != NULL) {
        int level = SCMapEnumNameToValue(level_s, SCSyslogGetLogLevelMap());
        if (level != -1) {
            alert_syslog_level = level;
        }
    }

    const char *ident = ConfNodeLookupChildValue(conf, "identity");
    /* if null we just pass that to openlog, which will then
     * figure it out by itself. */

    openlog(ident, LOG_PID|LOG_NDELAY, facility);

    OutputCtx *output_ctx = SCMalloc(sizeof(OutputCtx));
    if (unlikely(output_ctx == NULL)) {
        SCLogDebug("AlertSyslogInitCtx: Could not create new OutputCtx");
        return NULL;
    }
    memset(output_ctx, 0x00, sizeof(OutputCtx));

    output_ctx->data = logfile_ctx;
    output_ctx->DeInit = AlertSyslogDeInitCtx;

    SCLogInfo("Syslog output initialized");

    return output_ctx;
}
コード例 #16
0
ファイル: util-ioctl.c プロジェクト: micsoftvn/suricata
int GetIfaceRSSQueuesNum(const char *pcap_dev)
{
#if defined HAVE_LINUX_ETHTOOL_H && defined ETHTOOL_GRXRINGS
    struct ifreq ifr;
    struct ethtool_rxnfc nfccmd;
    int fd;

    (void)strlcpy(ifr.ifr_name, pcap_dev, sizeof(ifr.ifr_name));
    fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (fd == -1) {
        SCLogWarning(SC_ERR_SYSCALL,
                "Failure when opening socket for ioctl: %s (%d)",
                strerror(errno), errno);
        return -1;
    }

    nfccmd.cmd = ETHTOOL_GRXRINGS;
    ifr.ifr_data = (void*) &nfccmd;

    if (ioctl(fd, SIOCETHTOOL, (char *)&ifr) < 0) {
        if (errno != ENOTSUP) {
            SCLogWarning(SC_ERR_SYSCALL,
                         "Failure when trying to get number of RSS queue ioctl for '%s': %s (%d)",
                         pcap_dev, strerror(errno), errno);
        }
        close(fd);
        return 0;
    }
    close(fd);
    SCLogInfo("Found %d RX RSS queues for '%s'", (int)nfccmd.data,
            pcap_dev);
    return (int)nfccmd.data;
#else
    return 0;
#endif
}
コード例 #17
0
ファイル: log-filestore.c プロジェクト: glongo/suricata
static void LogFilestoreFinalizeFiles(const File *ff) {
    char pid_expression[PATH_MAX] = "";
    if (FileIncludePid())
        snprintf(pid_expression, sizeof(pid_expression), ".%d", getpid());
    char final_filename[PATH_MAX] = "";
    if (snprintf(final_filename, sizeof(final_filename), "%s/file%s.%u",
            g_logfile_base_dir, pid_expression, ff->file_store_id) == sizeof(final_filename))
        return;
    char working_filename[PATH_MAX] = "";
    if (snprintf(working_filename, sizeof(working_filename), "%s%s",
            final_filename, g_working_file_suffix) == sizeof(working_filename))
           return;

    if (rename(working_filename, final_filename) != 0) {
        SCLogWarning(SC_WARN_RENAMING_FILE, "renaming file %s to %s failed",
                working_filename, final_filename);
        return;
    }
    if (FileWriteMeta()) {
        LogFilestoreLogCloseMetaFile(ff);
        char final_metafilename[PATH_MAX] = "";
        if (snprintf(final_metafilename, sizeof(final_metafilename),
                "%s.meta", final_filename) == sizeof(final_metafilename))
            return;
        char working_metafilename[PATH_MAX] = "";
        if (snprintf(working_metafilename, sizeof(working_metafilename),
                "%s%s", final_metafilename, g_working_file_suffix) == sizeof(working_metafilename))
            return;

        if (rename(working_metafilename, final_metafilename) != 0) {
            SCLogWarning(SC_WARN_RENAMING_FILE,
                    "renaming metafile %s to %s failed", working_metafilename,
                    final_metafilename);
        }
    }
}
コード例 #18
0
ファイル: source-ipfw.c プロジェクト: kaoscoach/suricata
/**
 * \brief DeInit function closes divert socket at exit.
 * \todo Unit tests are needed for this module.
 * \param tv pointer to ThreadVars
 * \param data pointer that gets cast into IPFWThreadVars for ptv
 */
TmEcode ReceiveIPFWThreadDeinit(ThreadVars *tv, void *data)
{
    IPFWThreadVars *ptv = (IPFWThreadVars *)data;
    IPFWQueueVars *nq = IPFWGetQueue(ptv->ipfw_index);

    SCEnter();

    /* Attempt to shut the socket down...close instead? */
    if (shutdown(nq->fd, SHUT_RD) < 0) {
        SCLogWarning(SC_WARN_IPFW_UNBIND,"Unable to disable ipfw socket: %s",strerror(errno));
        SCReturnInt(TM_ECODE_FAILED);
    }

    SCReturnInt(TM_ECODE_OK);
}
コード例 #19
0
/**
 * \brief Attempt to reconnect a disconnected (or never-connected) Unix domain socket.
 * \retval 1 if it is now connected; otherwise 0
 */
static int SCLogUnixSocketReconnect(LogFileCtx *log_ctx)
{
    int disconnected = 0;
    if (log_ctx->fp) {
        SCLogWarning(SC_ERR_SOCKET,
            "Write error on Unix socket \"%s\": %s; reconnecting...",
            log_ctx->filename, strerror(errno));
        fclose(log_ctx->fp);
        log_ctx->fp = NULL;
        log_ctx->reconn_timer = 0;
        disconnected = 1;
    }

    struct timeval tv;
    uint64_t now;
    gettimeofday(&tv, NULL);
    now = (uint64_t)tv.tv_sec * 1000;
    now += tv.tv_usec / 1000;           /* msec resolution */
    if (log_ctx->reconn_timer != 0 &&
            (now - log_ctx->reconn_timer) < LOGFILE_RECONN_MIN_TIME) {
        /* Don't bother to try reconnecting too often. */
        return 0;
    }
    log_ctx->reconn_timer = now;

    log_ctx->fp = SCLogOpenUnixSocketFp(log_ctx->filename, log_ctx->sock_type, 0);
    if (log_ctx->fp) {
        /* Connected at last (or reconnected) */
        SCLogNotice("Reconnected socket \"%s\"", log_ctx->filename);
    } else if (disconnected) {
        SCLogWarning(SC_ERR_SOCKET, "Reconnect failed: %s (will keep trying)",
            strerror(errno));
    }

    return log_ctx->fp ? 1 : 0;
}
コード例 #20
0
void CudaHandlerModuleStoreData(const char *module_name,
                                const char *data_name, void *data_ptr)
{
    SCMutexLock(&mutex);

    CudaHandlerModule *module = cudahl_modules;
    while (module != NULL && strcasecmp(module->name, module_name) != 0)
        module = module->next;
    if (module == NULL) {
        SCLogError(SC_ERR_CUDA_HANDLER_ERROR, "Trying to retrieve data "
                   "\"%s\" from module \"%s\" that hasn't been registered "
                   "yet.",  module_name, data_name);
        exit(EXIT_FAILURE);
    }

    CudaHandlerModuleData *data = module->module_data;
    while (data != NULL && (strcasecmp(data_name, data->name) != 0)) {
        data = data->next;
    }
    if (data != NULL) {
        SCLogWarning(SC_ERR_CUDA_HANDLER_ERROR, "Data \"%s\" already "
                     "registered for this module \"%s\".", data_name,
                     module_name);
        SCMutexUnlock(&mutex);
        goto end;
    }

    CudaHandlerModuleData *new_data = SCMalloc(sizeof(CudaHandlerModuleData));
    if (new_data == NULL)
        exit(EXIT_FAILURE);
    memset(new_data, 0, sizeof(CudaHandlerModuleData));
    new_data->name = SCStrdup(data_name);
    if (new_data->name == NULL)
        exit(EXIT_FAILURE);
    new_data->data = data_ptr;

    if (module->module_data == NULL) {
        module->module_data = new_data;
    } else {
        new_data->next = module->module_data;
        module->module_data = new_data;
    }

    SCMutexUnlock(&mutex);

 end:
    return;
}
コード例 #21
0
ファイル: output-json.c プロジェクト: gozzy/suricata
static void OutputJsonDeInitCtx(OutputCtx *output_ctx)
{
    OutputJsonCtx *json_ctx = (OutputJsonCtx *)output_ctx->data;
    LogFileCtx *logfile_ctx = json_ctx->file_ctx;
    if (logfile_ctx->dropped) {
        SCLogWarning(SC_WARN_EVENT_DROPPED,
                "%"PRIu64" events were dropped due to slow or "
                "disconnected socket", logfile_ctx->dropped);
    }
    if (json_ctx->xff_cfg != NULL) {
        SCFree(json_ctx->xff_cfg);
    }
    LogFileFreeCtx(logfile_ctx);
    SCFree(json_ctx);
    SCFree(output_ctx);
}
コード例 #22
0
ファイル: util-magic.c プロジェクト: Hyperwise/suricata
/**
 *  \brief Initialize the "magic" context.
 */
int MagicInit(void)
{
    BUG_ON(g_magic_ctx != NULL);

    SCEnter();

    char *filename = NULL;
    FILE *fd = NULL;

    SCMutexInit(&g_magic_lock, NULL);
    SCMutexLock(&g_magic_lock);

    g_magic_ctx = magic_open(0);
    if (g_magic_ctx == NULL) {
        SCLogError(SC_ERR_MAGIC_OPEN, "magic_open failed: %s", magic_error(g_magic_ctx));
        goto error;
    }

    (void)ConfGet("magic-file", &filename);
    if (filename != NULL) {
        SCLogInfo("using magic-file %s", filename);

        if ( (fd = fopen(filename, "r")) == NULL) {
            SCLogWarning(SC_ERR_FOPEN, "Error opening file: \"%s\": %s", filename, strerror(errno));
            goto error;
        }
        fclose(fd);
    }

    if (magic_load(g_magic_ctx, filename) != 0) {
        SCLogError(SC_ERR_MAGIC_LOAD, "magic_load failed: %s", magic_error(g_magic_ctx));
        goto error;
    }

    SCMutexUnlock(&g_magic_lock);
    SCReturnInt(0);

error:
    if (g_magic_ctx != NULL) {
        magic_close(g_magic_ctx);
        g_magic_ctx = NULL;
    }

    SCMutexUnlock(&g_magic_lock);
    SCReturnInt(-1);
}
コード例 #23
0
ファイル: util-log-redis.c プロジェクト: bmeeks8/suricata
/** \brief SCRedisAsyncEchoCommandCallback() Callback for an ECHO command reply
 *         This is used to check if redis is connected.
 *  \param ac redis async context
 *  \param r redis reply
 *  \param privvata opaque datq with pointer to LogFileCtx
 */
static void SCRedisAsyncEchoCommandCallback(redisAsyncContext *ac, void *r, void *privdata)
{
    redisReply *reply = r;
    SCLogRedisContext * ctx = privdata;

    if (reply) {
       if (ctx->connected == 0) {
          SCLogNotice("Connected to Redis.");
          ctx->connected = 1;
          ctx->tried = 0;
       }
    } else {
       ctx->connected = 0;
       if (ctx->tried == 0) {
          SCLogWarning(SC_ERR_SOCKET, "Failed to connect to Redis... (will keep trying)");
       }
       ctx->tried = time(NULL);
    }
    event_base_loopbreak(ctx->ev_base);
}
コード例 #24
0
ファイル: source-pcap-file.c プロジェクト: Erdeep/suricata
void ReceivePcapFileThreadExitStats(ThreadVars *tv, void *data) {
    SCEnter();
    PcapFileThreadVars *ptv = (PcapFileThreadVars *)data;

    if (pcap_g.conf_checksum_mode == CHECKSUM_VALIDATION_AUTO &&
            pcap_g.cnt < CHECKSUM_SAMPLE_COUNT &&
            SC_ATOMIC_GET(pcap_g.invalid_checksums)) {
        uint64_t chrate = pcap_g.cnt / SC_ATOMIC_GET(pcap_g.invalid_checksums);
        if (chrate < CHECKSUM_INVALID_RATIO)
            SCLogWarning(SC_ERR_INVALID_CHECKSUM,
                         "1/%" PRIu64 "th of packets have an invalid checksum,"
                         " consider setting pcap-file.checksum-checks variable to no"
                         " or use '-k none' option on command line.",
                         chrate);
        else
            SCLogInfo("1/%" PRIu64 "th of packets have an invalid checksum",
                      chrate);
    }
    SCLogNotice("Pcap-file module read %" PRIu32 " packets, %" PRIu64 " bytes", ptv->pkts, ptv->bytes);
    return;
}
コード例 #25
0
ファイル: source-nfq.c プロジェクト: gcordrey/suricata
/**
 * \brief NFQ receive module main entry function: receive a packet from NFQ
 */
TmEcode ReceiveNFQ(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) {

    NFQThreadVars *ntv = (NFQThreadVars *)data;
    NFQQueueVars *nq = NFQGetQueue(ntv->nfq_index);
    if (nq == NULL) {
        SCLogWarning(SC_ERR_INVALID_ARGUMENT,
                     "can't get queue for %" PRId16 "", ntv->nfq_index);
        return TM_ECODE_FAILED;
    }

    /* make sure we have at least one packet in the packet pool, to prevent
     * us from 1) alloc'ing packets at line rate, 2) have a race condition
     * for the nfq mutex lock with the verdict thread. */
    while (PacketPoolSize() == 0) {
        PacketPoolWait();
    }

    /* do our nfq magic */
    NFQRecvPkt(nq, ntv);

    return TM_ECODE_OK;
}
コード例 #26
0
ファイル: util-print.c プロジェクト: norg/suricata
static const char *PrintInetIPv6(const void *src, char *dst, socklen_t size)
{
    int i;
    char s_part[6];
    uint16_t x[8];
    memcpy(&x, src, 16);

    /* current IPv6 format is fixed size */
    if (size < 8 * 5) {
        SCLogWarning(SC_ERR_ARG_LEN_LONG, "Too small buffer to write IPv6 address");
        return NULL;
    }
    memset(dst, 0, size);
    for(i = 0; i < 8; i++) {
        snprintf(s_part, sizeof(s_part), "%04x:", htons(x[i]));
        strlcat(dst, s_part, size);
    }
    /* suppress last ':' */
    dst[strlen(dst) - 1] = 0;

    return dst;
}
コード例 #27
0
void CleanupPcapFileFileVars(PcapFileFileVars *pfv)
{
    if (pfv != NULL) {
        if (pfv->pcap_handle != NULL) {
            pcap_close(pfv->pcap_handle);
            pfv->pcap_handle = NULL;
        }
        if (pfv->filename != NULL) {
            if (pfv->shared != NULL && pfv->shared->should_delete) {
                SCLogDebug("Deleting pcap file %s", pfv->filename);
                if (unlink(pfv->filename) != 0) {
                    SCLogWarning(SC_ERR_PCAP_FILE_DELETE_FAILED,
                                 "Failed to delete %s", pfv->filename);
                }
            }
            SCFree(pfv->filename);
            pfv->filename = NULL;
        }
        pfv->shared = NULL;
        SCFree(pfv);
    }
}
コード例 #28
0
ファイル: util-mpm.c プロジェクト: codercold/suricata
void MpmRegisterTests(void) {
#ifdef UNITTESTS
    uint16_t i;

    for (i = 0; i < MPM_TABLE_SIZE; i++) {
        if (i == MPM_NOTSET)
            continue;

        g_ut_modules++;

        if (mpm_table[i].RegisterUnittests != NULL) {
            g_ut_covered++;
            mpm_table[i].RegisterUnittests();
        } else {
            if (coverage_unittests)
                SCLogWarning(SC_WARN_NO_UNITTESTS, "mpm module %s has no "
                        "unittest registration function.", mpm_table[i].name);
        }
    }

#endif
}
コード例 #29
0
ファイル: util-logopenfile.c プロジェクト: norg/suricata
/** \brief open the indicated file, logging any errors
 *  \param path filesystem path to open
 *  \param append_setting open file with O_APPEND: "yes" or "no"
 *  \param mode permissions to set on file
 *  \retval FILE* on success
 *  \retval NULL on error
 */
static FILE *
SCLogOpenFileFp(const char *path, const char *append_setting, uint32_t mode)
{
    FILE *ret = NULL;

    char *filename = SCLogFilenameFromPattern(path);
    if (filename == NULL) {
        return NULL;
    }

    int rc = SCLogCreateDirectoryTree(filename);
    if (rc < 0) {
        SCFree(filename);
        return NULL;
    }

    if (ConfValIsTrue(append_setting)) {
        ret = fopen(filename, "a");
    } else {
        ret = fopen(filename, "w");
    }

    if (ret == NULL) {
        SCLogError(SC_ERR_FOPEN, "Error opening file: \"%s\": %s",
                   filename, strerror(errno));
    } else {
        if (mode != 0) {
            int r = chmod(filename, mode);
            if (r < 0) {
                SCLogWarning(SC_WARN_CHMOD, "Could not chmod %s to %u: %s",
                             filename, mode, strerror(errno));
            }
        }
    }

    SCFree(filename);
    return ret;
}
コード例 #30
0
ファイル: output-json.c プロジェクト: weixu8/suricata
/**
 * \brief Create a new LogFileCtx for "fast" output style.
 * \param conf The configuration node for this output.
 * \return A LogFileCtx pointer on success, NULL on failure.
 */
OutputCtx *OutputJsonInitCtx(ConfNode *conf)
{
    OutputJsonCtx *json_ctx = SCCalloc(1, sizeof(OutputJsonCtx));;
    if (unlikely(json_ctx == NULL)) {
        SCLogDebug("AlertJsonInitCtx: Could not create new LogFileCtx");
        return NULL;
    }

    json_ctx->file_ctx = LogFileNewCtx();
    if (unlikely(json_ctx->file_ctx == NULL)) {
        SCLogDebug("AlertJsonInitCtx: Could not create new LogFileCtx");
        SCFree(json_ctx);
        return NULL;
    }

    OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
    if (unlikely(output_ctx == NULL)) {
        LogFileFreeCtx(json_ctx->file_ctx);
        SCFree(json_ctx);
        return NULL;
    }

    output_ctx->data = json_ctx;
    output_ctx->DeInit = OutputJsonDeInitCtx;

    if (conf) {
        const char *output_s = ConfNodeLookupChildValue(conf, "type");
        if (output_s != NULL) {
            if (strcmp(output_s, "file") == 0) {
                json_ctx->json_out = ALERT_FILE;
            } else if (strcmp(output_s, "syslog") == 0) {
                json_ctx->json_out = ALERT_SYSLOG;
            } else if (strcmp(output_s, "unix_dgram") == 0) {
                json_ctx->json_out = ALERT_UNIX_DGRAM;
            } else if (strcmp(output_s, "unix_stream") == 0) {
                json_ctx->json_out = ALERT_UNIX_STREAM;
            } else {
                SCLogError(SC_ERR_INVALID_ARGUMENT,
                           "Invalid JSON output option: %s", output_s);
                exit(EXIT_FAILURE);
            }
        }

        if (json_ctx->json_out == ALERT_FILE) {

            if (SCConfLogOpenGeneric(conf, json_ctx->file_ctx, DEFAULT_LOG_FILENAME) < 0) {
                LogFileFreeCtx(json_ctx->file_ctx);
                SCFree(json_ctx);
                SCFree(output_ctx);
                return NULL;
            }

            const char *format_s = ConfNodeLookupChildValue(conf, "format");
            if (format_s != NULL) {
                if (strcmp(format_s, "indent") == 0) {
                    json_ctx->format = INDENT;
                } else if (strcmp(format_s, "compact") == 0) {
                    json_ctx->format = COMPACT;
                } else {
                    SCLogError(SC_ERR_INVALID_ARGUMENT,
                               "Invalid JSON format option: %s", format_s);
                    exit(EXIT_FAILURE);
                }
            }
        } else if (json_out == ALERT_SYSLOG) {
            const char *facility_s = ConfNodeLookupChildValue(conf, "facility");
            if (facility_s == NULL) {
                facility_s = DEFAULT_ALERT_SYSLOG_FACILITY_STR;
            }

            int facility = SCMapEnumNameToValue(facility_s, SCSyslogGetFacilityMap());
            if (facility == -1) {
                SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Invalid syslog facility: \"%s\","
                        " now using \"%s\" as syslog facility", facility_s,
                        DEFAULT_ALERT_SYSLOG_FACILITY_STR);
                facility = DEFAULT_ALERT_SYSLOG_FACILITY;
            }

            const char *level_s = ConfNodeLookupChildValue(conf, "level");
            if (level_s != NULL) {
                int level = SCMapEnumNameToValue(level_s, SCSyslogGetLogLevelMap());
                if (level != -1) {
                    alert_syslog_level = level;
                }
            }

            const char *ident = ConfNodeLookupChildValue(conf, "identity");
            /* if null we just pass that to openlog, which will then
             * figure it out by itself. */

            openlog(ident, LOG_PID|LOG_NDELAY, facility);

        }

        const char *sensor_id_s = ConfNodeLookupChildValue(conf, "sensor-id");
        if (sensor_id_s != NULL) {
            if (ByteExtractStringUint64((uint64_t *)&sensor_id, 10, 0, sensor_id_s) == -1) {
                SCLogError(SC_ERR_INVALID_ARGUMENT,
                           "Failed to initialize JSON output, "
                           "invalid sensor-is: %s", sensor_id_s);
                exit(EXIT_FAILURE);
            }
        }

        format = json_ctx->format;
        json_out = json_ctx->json_out;
    }

    return output_ctx;
}