/** * \brief Initialize the ERF receiver thread, generate a single * ErfDagThreadVar structure for each thread, this will * contain a DAG file descriptor which is read when the * thread executes. * * \param tv Thread variable to ThreadVars * \param initdata Initial data to the interface passed from the user, * this is processed by the user. * * We assume that we have only a single name for the DAG * interface. * * \param data data pointer gets populated with * */ TmEcode ReceiveErfDagThreadInit(ThreadVars *tv, void *initdata, void **data) { SCEnter(); int stream_count = 0; if (initdata == NULL) { SCLogError(SC_ERR_INVALID_ARGUMENT, "Error: No DAG interface provided."); SCReturnInt(TM_ECODE_FAILED); } ErfDagThreadVars *ewtn = SCMalloc(sizeof(ErfDagThreadVars)); if (unlikely(ewtn == NULL)) { SCLogError(SC_ERR_MEM_ALLOC, "Failed to allocate memory for ERF DAG thread vars."); exit(EXIT_FAILURE); } memset(ewtn, 0, sizeof(*ewtn)); /* dag_parse_name will return a DAG device name and stream number * to open for this thread. */ if (dag_parse_name(initdata, ewtn->dagname, DAGNAME_BUFSIZE, &ewtn->dagstream) < 0) { SCLogError(SC_ERR_INVALID_ARGUMENT, "Failed to parse DAG interface: %s", (char*)initdata); SCFree(ewtn); exit(EXIT_FAILURE); } SCLogInfo("Opening DAG: %s on stream: %d for processing", ewtn->dagname, ewtn->dagstream); if ((ewtn->dagfd = dag_open(ewtn->dagname)) < 0) { SCLogError(SC_ERR_ERF_DAG_OPEN_FAILED, "Failed to open DAG: %s", ewtn->dagname); SCFree(ewtn); SCReturnInt(TM_ECODE_FAILED); } /* Check to make sure the card has enough available streams to * support reading from the one specified. */ if ((stream_count = dag_rx_get_stream_count(ewtn->dagfd)) < 0) { SCLogError(SC_ERR_ERF_DAG_OPEN_FAILED, "Failed to open stream: %d, DAG: %s, could not query stream count", ewtn->dagstream, ewtn->dagname); SCFree(ewtn); SCReturnInt(TM_ECODE_FAILED); } /* Check to make sure we have enough rx streams to open the stream * the user is asking for. */ if (ewtn->dagstream > stream_count*2) { SCLogError(SC_ERR_ERF_DAG_OPEN_FAILED, "Failed to open stream: %d, DAG: %s, insufficient streams: %d", ewtn->dagstream, ewtn->dagname, stream_count); SCFree(ewtn); SCReturnInt(TM_ECODE_FAILED); } /* If we are transmitting into a soft DAG card then set the stream * to act in reverse mode. */ if (0 != (ewtn->dagstream & 0x01)) { /* Setting reverse mode for using with soft dag from daemon side */ if(dag_set_mode(ewtn->dagfd, ewtn->dagstream, DAG_REVERSE_MODE)) { SCLogError(SC_ERR_ERF_DAG_STREAM_OPEN_FAILED, "Failed to set mode to DAG_REVERSE_MODE on stream: %d, DAG: %s", ewtn->dagstream, ewtn->dagname); SCFree(ewtn); SCReturnInt(TM_ECODE_FAILED); } } if (dag_attach_stream(ewtn->dagfd, ewtn->dagstream, 0, 0) < 0) { SCLogError(SC_ERR_ERF_DAG_STREAM_OPEN_FAILED, "Failed to open DAG stream: %d, DAG: %s", ewtn->dagstream, ewtn->dagname); SCFree(ewtn); SCReturnInt(TM_ECODE_FAILED); } if (dag_start_stream(ewtn->dagfd, ewtn->dagstream) < 0) { SCLogError(SC_ERR_ERF_DAG_STREAM_START_FAILED, "Failed to start DAG stream: %d, DAG: %s", ewtn->dagstream, ewtn->dagname); SCFree(ewtn); SCReturnInt(TM_ECODE_FAILED); } SCLogInfo("Attached and started stream: %d on DAG: %s", ewtn->dagstream, ewtn->dagname); /* * Initialise DAG Polling parameters. */ timerclear(&ewtn->maxwait); ewtn->maxwait.tv_usec = 20 * 1000; /* 20ms timeout */ timerclear(&ewtn->poll); ewtn->poll.tv_usec = 1 * 1000; /* 1ms poll interval */ /* 32kB minimum data to return -- we still restrict the number of * pkts that are processed to a maximum of dag_max_read_packets. */ if (dag_set_stream_poll(ewtn->dagfd, ewtn->dagstream, 32*1024, &(ewtn->maxwait), &(ewtn->poll)) < 0) { SCLogError(SC_ERR_ERF_DAG_STREAM_SET_FAILED, "Failed to set poll parameters for stream: %d, DAG: %s", ewtn->dagstream, ewtn->dagname); SCFree(ewtn); SCReturnInt(TM_ECODE_FAILED); } ewtn->packets = SCPerfTVRegisterCounter("capture.dag_packets", tv, SC_PERF_TYPE_UINT64, "NULL"); ewtn->drops = SCPerfTVRegisterCounter("capture.dag_drops", tv, SC_PERF_TYPE_UINT64, "NULL"); ewtn->tv = tv; *data = (void *)ewtn; SCLogInfo("Starting processing packets from stream: %d on DAG: %s", ewtn->dagstream, ewtn->dagname); SCReturnInt(TM_ECODE_OK); }
void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv) { /* register counters */ dtv->counter_pkts = SCPerfTVRegisterCounter("decoder.pkts", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_bytes = SCPerfTVRegisterCounter("decoder.bytes", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_invalid = SCPerfTVRegisterCounter("decoder.invalid", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_ipv4 = SCPerfTVRegisterCounter("decoder.ipv4", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_ipv6 = SCPerfTVRegisterCounter("decoder.ipv6", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_eth = SCPerfTVRegisterCounter("decoder.ethernet", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_raw = SCPerfTVRegisterCounter("decoder.raw", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_sll = SCPerfTVRegisterCounter("decoder.sll", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_tcp = SCPerfTVRegisterCounter("decoder.tcp", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_udp = SCPerfTVRegisterCounter("decoder.udp", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_sctp = SCPerfTVRegisterCounter("decoder.sctp", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_icmpv4 = SCPerfTVRegisterCounter("decoder.icmpv4", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_icmpv6 = SCPerfTVRegisterCounter("decoder.icmpv6", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_ppp = SCPerfTVRegisterCounter("decoder.ppp", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_pppoe = SCPerfTVRegisterCounter("decoder.pppoe", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_gre = SCPerfTVRegisterCounter("decoder.gre", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_vlan = SCPerfTVRegisterCounter("decoder.vlan", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_vlan_qinq = SCPerfTVRegisterCounter("decoder.vlan_qinq", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_teredo = SCPerfTVRegisterCounter("decoder.teredo", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_ipv4inipv6 = SCPerfTVRegisterCounter("decoder.ipv4_in_ipv6", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_ipv6inipv6 = SCPerfTVRegisterCounter("decoder.ipv6_in_ipv6", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_avg_pkt_size = SCPerfTVRegisterAvgCounter("decoder.avg_pkt_size", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_max_pkt_size = SCPerfTVRegisterMaxCounter("decoder.max_pkt_size", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_defrag_ipv4_fragments = SCPerfTVRegisterCounter("defrag.ipv4.fragments", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_defrag_ipv4_reassembled = SCPerfTVRegisterCounter("defrag.ipv4.reassembled", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_defrag_ipv4_timeouts = SCPerfTVRegisterCounter("defrag.ipv4.timeouts", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_defrag_ipv6_fragments = SCPerfTVRegisterCounter("defrag.ipv6.fragments", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_defrag_ipv6_reassembled = SCPerfTVRegisterCounter("defrag.ipv6.reassembled", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_defrag_ipv6_timeouts = SCPerfTVRegisterCounter("defrag.ipv6.timeouts", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_defrag_max_hit = SCPerfTVRegisterCounter("defrag.max_frag_hits", tv, SC_PERF_TYPE_UINT64, "NULL"); return; }
/* Making it conditional to Linux even if GetIfaceOffloading return 0 * for non Linux. */ #ifdef HAVE_LINUX_ETHTOOL_H if (GetIfaceOffloading(pcapconfig->iface) == 1) { SCLogWarning(SC_ERR_PCAP_CREATE, "Using Pcap capture with GRO or LRO activated can lead to " "capture problems."); } #endif /* HAVE_LINUX_ETHTOOL_H */ ptv->datalink = pcap_datalink(ptv->pcap_handle); pcapconfig->DerefFunc(pcapconfig); ptv->capture_kernel_packets = SCPerfTVRegisterCounter("capture.kernel_packets", ptv->tv, SC_PERF_TYPE_UINT64, "NULL"); ptv->capture_kernel_drops = SCPerfTVRegisterCounter("capture.kernel_drops", ptv->tv, SC_PERF_TYPE_UINT64, "NULL"); ptv->capture_kernel_ifdrops = SCPerfTVRegisterCounter("capture.kernel_ifdrops", ptv->tv, SC_PERF_TYPE_UINT64, "NULL"); *data = (void *)ptv; SCReturnInt(TM_ECODE_OK); } #else /* implied LIBPCAP_VERSION_MAJOR == 0 */ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) { SCEnter(); PcapIfaceConfig *pcapconfig = initdata; if (initdata == NULL) { SCLogError(SC_ERR_INVALID_ARGUMENT, "initdata == NULL"); SCReturnInt(TM_ECODE_FAILED); } PcapThreadVars *ptv = SCMalloc(sizeof(PcapThreadVars)); if (unlikely(ptv == NULL)) { pcapconfig->DerefFunc(pcapconfig); SCReturnInt(TM_ECODE_FAILED); } memset(ptv, 0, sizeof(PcapThreadVars)); ptv->tv = tv; ptv->livedev = LiveGetDevice(pcapconfig->iface); if (ptv->livedev == NULL) { SCLogError(SC_ERR_INVALID_VALUE, "Unable to find Live device"); SCReturnInt(TM_ECODE_FAILED); } SCLogInfo("using interface %s", pcapconfig->iface); if (strlen(pcapconfig->iface) > PCAP_IFACE_NAME_LENGTH) { SCFree(ptv); /* Dereference config */ pcapconfig->DerefFunc(pcapconfig); SCReturnInt(TM_ECODE_FAILED); } strlcpy(ptv->iface, pcapconfig->iface, PCAP_IFACE_NAME_LENGTH); if (pcapconfig->snaplen == 0) { /* We try to set snaplen from MTU value */ ptv->pcap_snaplen = GetIfaceMaxPacketSize(pcapconfig->iface); /* be conservative with old pcap lib to mimic old tcpdump behavior when MTU was not available. */ if (ptv->pcap_snaplen <= 0) ptv->pcap_snaplen = LIBPCAP_SNAPLEN; } else { ptv->pcap_snaplen = pcapconfig->snaplen; } char errbuf[PCAP_ERRBUF_SIZE] = ""; ptv->pcap_handle = pcap_open_live(ptv->iface, ptv->pcap_snaplen, LIBPCAP_PROMISC, LIBPCAP_COPYWAIT, errbuf); if (ptv->pcap_handle == NULL) { SCLogError(SC_ERR_PCAP_OPEN_LIVE, "Problem creating pcap handler for live mode, error %s", errbuf); SCFree(ptv); /* Dereference config */ pcapconfig->DerefFunc(pcapconfig); SCReturnInt(TM_ECODE_FAILED); } /* set bpf filter if we have one */ if (pcapconfig->bpf_filter) { SCMutexLock(&pcap_bpf_compile_lock); ptv->bpf_filter = pcapconfig->bpf_filter; SCLogInfo("using bpf-filter \"%s\"", ptv->bpf_filter); if(pcap_compile(ptv->pcap_handle,&ptv->filter, ptv->bpf_filter,1,0) < 0) { SCLogError(SC_ERR_BPF,"bpf compilation error %s",pcap_geterr(ptv->pcap_handle)); SCMutexUnlock(&pcap_bpf_compile_lock); SCFree(ptv); /* Dereference config */ pcapconfig->DerefFunc(pcapconfig); return TM_ECODE_FAILED; } if(pcap_setfilter(ptv->pcap_handle,&ptv->filter) < 0) { SCLogError(SC_ERR_BPF,"could not set bpf filter %s",pcap_geterr(ptv->pcap_handle)); SCMutexUnlock(&pcap_bpf_compile_lock); SCFree(ptv); /* Dereference config */ pcapconfig->DerefFunc(pcapconfig); return TM_ECODE_FAILED; } SCMutexUnlock(&pcap_bpf_compile_lock); } ptv->datalink = pcap_datalink(ptv->pcap_handle); ptv->capture_kernel_packets = SCPerfTVRegisterCounter("capture.kernel_packets", ptv->tv, SC_PERF_TYPE_UINT64, "NULL"); ptv->capture_kernel_drops = SCPerfTVRegisterCounter("capture.kernel_drops", ptv->tv, SC_PERF_TYPE_UINT64, "NULL"); ptv->capture_kernel_ifdrops = SCPerfTVRegisterCounter("capture.kernel_ifdrops", ptv->tv, SC_PERF_TYPE_UINT64, "NULL"); *data = (void *)ptv; /* Dereference config */ pcapconfig->DerefFunc(pcapconfig); SCReturnInt(TM_ECODE_OK); }
void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv) { /* register counters */ dtv->counter_pkts = SCPerfTVRegisterCounter("decoder.pkts", tv, SC_PERF_TYPE_UINT64, "NULL"); #if 0 dtv->counter_pkts_per_sec = SCPerfTVRegisterIntervalCounter("decoder.pkts_per_sec", tv, SC_PERF_TYPE_DOUBLE, "NULL", "1s"); #endif dtv->counter_bytes = SCPerfTVRegisterCounter("decoder.bytes", tv, SC_PERF_TYPE_UINT64, "NULL"); #if 0 dtv->counter_bytes_per_sec = SCPerfTVRegisterIntervalCounter("decoder.bytes_per_sec", tv, SC_PERF_TYPE_DOUBLE, "NULL", "1s"); dtv->counter_mbit_per_sec = SCPerfTVRegisterIntervalCounter("decoder.mbit_per_sec", tv, SC_PERF_TYPE_DOUBLE, "NULL", "1s"); #endif dtv->counter_ipv4 = SCPerfTVRegisterCounter("decoder.ipv4", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_ipv6 = SCPerfTVRegisterCounter("decoder.ipv6", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_eth = SCPerfTVRegisterCounter("decoder.ethernet", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_raw = SCPerfTVRegisterCounter("decoder.raw", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_sll = SCPerfTVRegisterCounter("decoder.sll", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_tcp = SCPerfTVRegisterCounter("decoder.tcp", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_udp = SCPerfTVRegisterCounter("decoder.udp", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_sctp = SCPerfTVRegisterCounter("decoder.sctp", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_icmpv4 = SCPerfTVRegisterCounter("decoder.icmpv4", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_icmpv6 = SCPerfTVRegisterCounter("decoder.icmpv6", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_ppp = SCPerfTVRegisterCounter("decoder.ppp", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_pppoe = SCPerfTVRegisterCounter("decoder.pppoe", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_gre = SCPerfTVRegisterCounter("decoder.gre", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_vlan = SCPerfTVRegisterCounter("decoder.vlan", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_teredo = SCPerfTVRegisterCounter("decoder.teredo", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_ipv4inipv6 = SCPerfTVRegisterCounter("decoder.ipv4_in_ipv6", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_ipv6inipv6 = SCPerfTVRegisterCounter("decoder.ipv6_in_ipv6", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_avg_pkt_size = SCPerfTVRegisterAvgCounter("decoder.avg_pkt_size", tv, SC_PERF_TYPE_DOUBLE, "NULL"); dtv->counter_max_pkt_size = SCPerfTVRegisterMaxCounter("decoder.max_pkt_size", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_defrag_ipv4_fragments = SCPerfTVRegisterCounter("defrag.ipv4.fragments", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_defrag_ipv4_reassembled = SCPerfTVRegisterCounter("defrag.ipv4.reassembled", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_defrag_ipv4_timeouts = SCPerfTVRegisterCounter("defrag.ipv4.timeouts", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_defrag_ipv6_fragments = SCPerfTVRegisterCounter("defrag.ipv6.fragments", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_defrag_ipv6_reassembled = SCPerfTVRegisterCounter("defrag.ipv6.reassembled", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_defrag_ipv6_timeouts = SCPerfTVRegisterCounter("defrag.ipv6.timeouts", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_defrag_max_hit = SCPerfTVRegisterCounter("defrag.max_frag_hits", tv, SC_PERF_TYPE_UINT64, "NULL"); tv->sc_perf_pca = SCPerfGetAllCountersArray(&tv->sc_perf_pctx); SCPerfAddToClubbedTMTable(tv->name, &tv->sc_perf_pctx); return; }
TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) { SCEnter(); PcapIfaceConfig *pcapconfig = initdata; if (initdata == NULL) { SCLogError(SC_ERR_INVALID_ARGUMENT, "initdata == NULL"); SCReturnInt(TM_ECODE_FAILED); } PcapThreadVars *ptv = SCMalloc(sizeof(PcapThreadVars)); if (unlikely(ptv == NULL)) { pcapconfig->DerefFunc(pcapconfig); SCReturnInt(TM_ECODE_FAILED); } memset(ptv, 0, sizeof(PcapThreadVars)); ptv->tv = tv; ptv->livedev = LiveGetDevice(pcapconfig->iface); if (ptv->livedev == NULL) { SCLogError(SC_ERR_INVALID_VALUE, "Unable to find Live device"); SCFree(ptv); SCReturnInt(TM_ECODE_FAILED); } SCLogInfo("using interface %s", (char *)pcapconfig->iface); ptv->checksum_mode = pcapconfig->checksum_mode; if (ptv->checksum_mode == CHECKSUM_VALIDATION_AUTO) { SCLogInfo("Running in 'auto' checksum mode. Detection of interface state will require " xstr(CHECKSUM_SAMPLE_COUNT) " packets."); } /* XXX create a general pcap setup function */ char errbuf[PCAP_ERRBUF_SIZE]; ptv->pcap_handle = pcap_create((char *)pcapconfig->iface, errbuf); if (ptv->pcap_handle == NULL) { if (strlen(errbuf)) { SCLogError(SC_ERR_PCAP_CREATE, "Couldn't create a new pcap handler for %s, error %s", (char *)pcapconfig->iface, errbuf); } else { SCLogError(SC_ERR_PCAP_CREATE, "Couldn't create a new pcap handler for %s", (char *)pcapconfig->iface); } SCFree(ptv); pcapconfig->DerefFunc(pcapconfig); SCReturnInt(TM_ECODE_FAILED); } if (pcapconfig->snaplen == 0) { /* We set snaplen if we can get the MTU */ ptv->pcap_snaplen = GetIfaceMaxPacketSize(pcapconfig->iface); } else { ptv->pcap_snaplen = pcapconfig->snaplen; } if (ptv->pcap_snaplen > 0) { /* set Snaplen. Must be called before pcap_activate */ int pcap_set_snaplen_r = pcap_set_snaplen(ptv->pcap_handle, ptv->pcap_snaplen); if (pcap_set_snaplen_r != 0) { SCLogError(SC_ERR_PCAP_SET_SNAPLEN, "Couldn't set snaplen, error: %s", pcap_geterr(ptv->pcap_handle)); SCFree(ptv); pcapconfig->DerefFunc(pcapconfig); SCReturnInt(TM_ECODE_FAILED); } SCLogInfo("Set snaplen to %d for '%s'", ptv->pcap_snaplen, pcapconfig->iface); } /* set Promisc, and Timeout. Must be called before pcap_activate */ int pcap_set_promisc_r = pcap_set_promisc(ptv->pcap_handle, pcapconfig->promisc); //printf("ReceivePcapThreadInit: pcap_set_promisc(%p) returned %" PRId32 "\n", ptv->pcap_handle, pcap_set_promisc_r); if (pcap_set_promisc_r != 0) { SCLogError(SC_ERR_PCAP_SET_PROMISC, "Couldn't set promisc mode, error %s", pcap_geterr(ptv->pcap_handle)); SCFree(ptv); pcapconfig->DerefFunc(pcapconfig); SCReturnInt(TM_ECODE_FAILED); } int pcap_set_timeout_r = pcap_set_timeout(ptv->pcap_handle,LIBPCAP_COPYWAIT); //printf("ReceivePcapThreadInit: pcap_set_timeout(%p) returned %" PRId32 "\n", ptv->pcap_handle, pcap_set_timeout_r); if (pcap_set_timeout_r != 0) { SCLogError(SC_ERR_PCAP_SET_TIMEOUT, "Problems setting timeout, error %s", pcap_geterr(ptv->pcap_handle)); SCFree(ptv); pcapconfig->DerefFunc(pcapconfig); SCReturnInt(TM_ECODE_FAILED); } #ifdef HAVE_PCAP_SET_BUFF ptv->pcap_buffer_size = pcapconfig->buffer_size; if (ptv->pcap_buffer_size >= 0 && ptv->pcap_buffer_size <= INT_MAX) { if (ptv->pcap_buffer_size > 0) SCLogInfo("Going to use pcap buffer size of %" PRId32 "", ptv->pcap_buffer_size); int pcap_set_buffer_size_r = pcap_set_buffer_size(ptv->pcap_handle,ptv->pcap_buffer_size); //printf("ReceivePcapThreadInit: pcap_set_timeout(%p) returned %" PRId32 "\n", ptv->pcap_handle, pcap_set_buffer_size_r); if (pcap_set_buffer_size_r != 0) { SCLogError(SC_ERR_PCAP_SET_BUFF_SIZE, "Problems setting pcap buffer size, error %s", pcap_geterr(ptv->pcap_handle)); SCFree(ptv); pcapconfig->DerefFunc(pcapconfig); SCReturnInt(TM_ECODE_FAILED); } } #endif /* HAVE_PCAP_SET_BUFF */ /* activate the handle */ int pcap_activate_r = pcap_activate(ptv->pcap_handle); //printf("ReceivePcapThreadInit: pcap_activate(%p) returned %" PRId32 "\n", ptv->pcap_handle, pcap_activate_r); if (pcap_activate_r != 0) { SCLogError(SC_ERR_PCAP_ACTIVATE_HANDLE, "Couldn't activate the pcap handler, error %s", pcap_geterr(ptv->pcap_handle)); SCFree(ptv); pcapconfig->DerefFunc(pcapconfig); SCReturnInt(TM_ECODE_FAILED); } else { ptv->pcap_state = PCAP_STATE_UP; } /* set bpf filter if we have one */ if (pcapconfig->bpf_filter) { SCMutexLock(&pcap_bpf_compile_lock); ptv->bpf_filter = pcapconfig->bpf_filter; if (pcap_compile(ptv->pcap_handle,&ptv->filter,ptv->bpf_filter,1,0) < 0) { SCLogError(SC_ERR_BPF, "bpf compilation error %s", pcap_geterr(ptv->pcap_handle)); SCMutexUnlock(&pcap_bpf_compile_lock); SCFree(ptv); pcapconfig->DerefFunc(pcapconfig); return TM_ECODE_FAILED; } if (pcap_setfilter(ptv->pcap_handle,&ptv->filter) < 0) { SCLogError(SC_ERR_BPF, "could not set bpf filter %s", pcap_geterr(ptv->pcap_handle)); SCMutexUnlock(&pcap_bpf_compile_lock); SCFree(ptv); pcapconfig->DerefFunc(pcapconfig); return TM_ECODE_FAILED; } SCMutexUnlock(&pcap_bpf_compile_lock); } /* Making it conditional to Linux even if GetIfaceOffloading return 0 * for non Linux. */ #ifdef HAVE_LINUX_ETHTOOL_H if (GetIfaceOffloading(pcapconfig->iface) == 1) { SCLogWarning(SC_ERR_PCAP_CREATE, "Using Pcap capture with GRO or LRO activated can lead to " "capture problems."); } #endif /* HAVE_LINUX_ETHTOOL_H */ ptv->datalink = pcap_datalink(ptv->pcap_handle); pcapconfig->DerefFunc(pcapconfig); ptv->capture_kernel_packets = SCPerfTVRegisterCounter("capture.kernel_packets", ptv->tv, SC_PERF_TYPE_UINT64, "NULL"); ptv->capture_kernel_drops = SCPerfTVRegisterCounter("capture.kernel_drops", ptv->tv, SC_PERF_TYPE_UINT64, "NULL"); ptv->capture_kernel_ifdrops = SCPerfTVRegisterCounter("capture.kernel_ifdrops", ptv->tv, SC_PERF_TYPE_UINT64, "NULL"); *data = (void *)ptv; SCReturnInt(TM_ECODE_OK); }