From: Ashlee Young Date: Tue, 29 Dec 2015 03:41:26 +0000 (+0000) Subject: Added Suricata Ubuntu dependencies X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=commitdiff_plain;h=refs%2Fchanges%2F35%2F5335%2F1;p=onosfw.git Added Suricata Ubuntu dependencies Change-Id: I22e33f4042b12d16e9c6dc39c167be78a24b6b6e Signed-off-by: Ashlee Young --- diff --git a/build.sh b/build.sh index 26b18204..dfa505b4 100755 --- a/build.sh +++ b/build.sh @@ -18,9 +18,9 @@ # limitations under the License. ##### Settings ##### -VERSION=1.0.10 +VERSION=1.0.11 AUTHOR="Ashlee Young" -MODIFIED="December 21, 2015" +MODIFIED="December 26, 2015" GERRITURL="git clone ssh://im2bz2pee@gerrit.opnfv.org:29418/onosfw" ONOSURL="https://github.com/opennetworkinglab/onos" SURICATAURL="https://github.com/inliniac/suricata" @@ -461,7 +461,11 @@ suricataDepends() # Checks whether RPMBUILD is installed elif [ "$OS" = "suse" ]; then sudo zypper --non-interactive install libnet-devel elif [ "$OS" = "ubuntu" ]; then - sudo apt-get -y install libnet-devel + sudo apt-get -y install libpcre3 libpcre3-dbg libpcre3-dev \ + build-essential autoconf automake libtool libpcap-dev libnet1-dev \ + libyaml-0-2 libyaml-dev pkg-config zlib1g zlib1g-dev libcap-ng-dev libcap-ng0 \ + make libmagic-dev libnetfilter-queue-dev libnetfilter-queue1 libnfnetlink-dev \ + libnfnetlink0 fi } ##### End Check for Suricata Dependencies ##### diff --git a/framework/build/README b/framework/build/README deleted file mode 100644 index f9626d79..00000000 --- a/framework/build/README +++ /dev/null @@ -1 +0,0 @@ -This is where to place any files to patch upstream projects. The patches are whole files and must be added with their full relative path. For example, if you're making applying a patch to onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc, then you'll need that entire directory path here. Use copy and paste of the location after running "pwd". You can then use "mkdir -p" to create the full path. diff --git a/framework/src/suricata/ChangeLog b/framework/src/suricata/ChangeLog index a7e64598..b121928a 100644 --- a/framework/src/suricata/ChangeLog +++ b/framework/src/suricata/ChangeLog @@ -1,3 +1,23 @@ +3.0RC3 -- 2015-12-21 + +Bug #1632: Fail to download large file with browser +Bug #1634: Fix non thread safeness of Prelude analyzer +Bug #1640: drop log crashes +Bug #1645: Race condition in unix manager +Bug #1647: FlowGetKey flow-hash.c:240 segmentation fault (master) +Bug #1650: DER parsing issue (master) + +3.0RC2 -- 2015-12-08 + +Bug #1551: --enable-profiling-locks broken +Bug #1602: eve-log prefix field feature broken +Bug #1614: app_proto key missing from EVE file events +Bug #1615: disable modbus by default +Bug #1616: TCP reassembly bug +Bug #1617: DNS over TCP parsing issue +Bug #1618: SMTP parsing issue +Feature #1635: unified2 output: disable by default + 3.0RC1 -- 2015-11-25 Bug #1150: TLS store disabled by TLS EVE logging diff --git a/framework/src/suricata/src/alert-prelude.c b/framework/src/suricata/src/alert-prelude.c index a053e38b..1a7b2681 100644 --- a/framework/src/suricata/src/alert-prelude.c +++ b/framework/src/suricata/src/alert-prelude.c @@ -115,6 +115,7 @@ typedef struct AlertPreludeCtx_ { typedef struct AlertPreludeThread_ { /** Pointer to the global context */ AlertPreludeCtx *ctx; + idmef_analyzer_t *analyzer; } AlertPreludeThread; @@ -131,24 +132,56 @@ static int SetupAnalyzer(idmef_analyzer_t *analyzer) SCEnter(); ret = idmef_analyzer_new_model(analyzer, &string); - if (unlikely(ret < 0)) + if (unlikely(ret < 0)) { + SCLogDebug("%s: error creating analyzer model: %s.", + prelude_strsource(ret), prelude_strerror(ret)); SCReturnInt(ret); - prelude_string_set_constant(string, ANALYZER_MODEL); + } + ret = prelude_string_set_constant(string, ANALYZER_MODEL); + if (unlikely(ret < 0)) { + SCLogDebug("%s: error setting analyzer model: %s.", + prelude_strsource(ret), prelude_strerror(ret)); + SCReturnInt(ret); + } ret = idmef_analyzer_new_class(analyzer, &string); - if (unlikely(ret < 0)) + if (unlikely(ret < 0)) { + SCLogDebug("%s: error creating analyzer class: %s.", + prelude_strsource(ret), prelude_strerror(ret)); SCReturnInt(ret); - prelude_string_set_constant(string, ANALYZER_CLASS); + } + ret = prelude_string_set_constant(string, ANALYZER_CLASS); + if (unlikely(ret < 0)) { + SCLogDebug("%s: error setting analyzer class: %s.", + prelude_strsource(ret), prelude_strerror(ret)); + SCReturnInt(ret); + } ret = idmef_analyzer_new_manufacturer(analyzer, &string); - if (unlikely(ret < 0)) + if (unlikely(ret < 0)) { + SCLogDebug("%s: error creating analyzer manufacturer: %s.", + prelude_strsource(ret), prelude_strerror(ret)); SCReturnInt(ret); - prelude_string_set_constant(string, ANALYZER_MANUFACTURER); + } + ret = prelude_string_set_constant(string, ANALYZER_MANUFACTURER); + if (unlikely(ret < 0)) { + SCLogDebug("%s: error setting analyzer manufacturer: %s.", + prelude_strsource(ret), prelude_strerror(ret)); + SCReturnInt(ret); + } ret = idmef_analyzer_new_version(analyzer, &string); - if (unlikely(ret < 0)) + if (unlikely(ret < 0)) { + SCLogDebug("%s: error creating analyzer version: %s.", + prelude_strsource(ret), prelude_strerror(ret)); SCReturnInt(ret); - prelude_string_set_constant(string, VERSION); + } + ret = prelude_string_set_constant(string, VERSION); + if (unlikely(ret < 0)) { + SCLogDebug("%s: error setting analyzer version: %s.", + prelude_strsource(ret), prelude_strerror(ret)); + SCReturnInt(ret); + } SCReturnInt(0); } @@ -606,9 +639,9 @@ static TmEcode AlertPreludeThreadInit(ThreadVars *t, void *initdata, void **data SCEnter(); - if(unlikely(initdata == NULL)) - { - SCLogDebug("Error getting context for Prelude. \"initdata\" argument NULL"); + if (unlikely(initdata == NULL)) { + SCLogError(SC_ERR_INITIALIZATION, + "Error getting context for Prelude. \"initdata\" argument NULL"); SCReturnInt(TM_ECODE_FAILED); } @@ -617,9 +650,28 @@ static TmEcode AlertPreludeThreadInit(ThreadVars *t, void *initdata, void **data SCReturnInt(TM_ECODE_FAILED); memset(aun, 0, sizeof(AlertPreludeThread)); - /** Use the Ouput Context */ + /* Use the Ouput Context */ aun->ctx = ((OutputCtx *)initdata)->data; + /* Create a per-thread idmef analyzer */ + if (unlikely(idmef_analyzer_new(&aun->analyzer) < 0)) { + SCLogError(SC_ERR_INITIALIZATION, + "Error creating idmef analyzer for Prelude."); + + SCFree(aun); + SCReturnInt(TM_ECODE_FAILED); + } + + /* Setup the per-thread idmef analyzer */ + if (unlikely(SetupAnalyzer(aun->analyzer) < 0)) { + SCLogError(SC_ERR_INITIALIZATION, + "Error configuring idmef analyzer for Prelude."); + + idmef_analyzer_destroy(aun->analyzer); + SCFree(aun); + SCReturnInt(TM_ECODE_FAILED); + } + *data = (void *)aun; SCReturnInt(TM_ECODE_OK); } @@ -641,6 +693,7 @@ static TmEcode AlertPreludeThreadDeinit(ThreadVars *t, void *data) } /* clear memory */ + idmef_analyzer_destroy(aun->analyzer); memset(aun, 0, sizeof(AlertPreludeThread)); SCFree(aun); @@ -703,7 +756,12 @@ static OutputCtx *AlertPreludeInitCtx(ConfNode *conf) SCReturnPtr(NULL, "AlertPreludeCtx"); } - SetupAnalyzer(prelude_client_get_analyzer(client)); + ret = SetupAnalyzer(prelude_client_get_analyzer(client)); + if (ret < 0) { + SCLogDebug("Unable to setup prelude client analyzer."); + prelude_client_destroy(client, PRELUDE_CLIENT_EXIT_STATUS_SUCCESS); + SCReturnPtr(NULL, "AlertPreludeCtx"); + } ret = prelude_client_start(client); if (unlikely(ret < 0)) { @@ -855,7 +913,7 @@ static int AlertPreludeLogger(ThreadVars *tv, void *thread_data, const Packet *p goto err; idmef_alert_set_create_time(alert, time); - idmef_alert_set_analyzer(alert, idmef_analyzer_ref(prelude_client_get_analyzer(apn->ctx->client)), IDMEF_LIST_PREPEND); + idmef_alert_set_analyzer(alert, idmef_analyzer_ref(apn->analyzer), IDMEF_LIST_PREPEND); /* finally, send event */ prelude_client_send_idmef(apn->ctx->client, idmef); diff --git a/framework/src/suricata/src/app-layer-dns-tcp.c b/framework/src/suricata/src/app-layer-dns-tcp.c index f1cb597d..9e85ca29 100644 --- a/framework/src/suricata/src/app-layer-dns-tcp.c +++ b/framework/src/suricata/src/app-layer-dns-tcp.c @@ -521,7 +521,9 @@ next_record: DNSTcpHeader *dns_tcp_header = (DNSTcpHeader *)input; SCLogDebug("DNS %p", dns_tcp_header); - if (ntohs(dns_tcp_header->len) == (input_len-2)) { + if (ntohs(dns_tcp_header->len) == 0) { + goto bad_data; + } else if (ntohs(dns_tcp_header->len) == (input_len-2)) { /* we have all data, so process w/o buffering */ if (DNSReponseParseData(f, dns_state, input+2, input_len-2) < 0) goto bad_data; diff --git a/framework/src/suricata/src/app-layer-htp-body.c b/framework/src/suricata/src/app-layer-htp-body.c index 6454fe1c..a9a1ba17 100644 --- a/framework/src/suricata/src/app-layer-htp-body.c +++ b/framework/src/suricata/src/app-layer-htp-body.c @@ -222,7 +222,16 @@ void HtpBodyPrune(HtpState *state, HtpBody *body, int direction) window = state->cfg->request_inspect_window; } - if (body->body_inspected < (min_size > window) ? min_size : window) { + uint64_t max_window = ((min_size > window) ? min_size : window); + uint64_t in_flight = body->content_len_so_far - body->body_inspected; + + /* Special case. If body_inspected is not being updated, we make sure that + * we prune the body. We allow for some extra size/room as we may be called + * multiple times on uninspected body chunk additions if a large block of + * data was ack'd at once. Want to avoid pruning before inspection. */ + if (in_flight > (max_window * 3)) { + body->body_inspected = body->content_len_so_far - max_window; + } else if (body->body_inspected < max_window) { SCReturn; } diff --git a/framework/src/suricata/src/app-layer-htp-file.c b/framework/src/suricata/src/app-layer-htp-file.c index d8659f33..27371a75 100644 --- a/framework/src/suricata/src/app-layer-htp-file.c +++ b/framework/src/suricata/src/app-layer-htp-file.c @@ -77,7 +77,7 @@ * \retval -2 not handling files on this flow */ int HTPFileOpen(HtpState *s, uint8_t *filename, uint16_t filename_len, - uint8_t *data, uint32_t data_len, uint16_t txid, uint8_t direction) + uint8_t *data, uint32_t data_len, uint64_t txid, uint8_t direction) { int retval = 0; uint8_t flags = 0; diff --git a/framework/src/suricata/src/app-layer-htp-file.h b/framework/src/suricata/src/app-layer-htp-file.h index d70794ea..70799c32 100644 --- a/framework/src/suricata/src/app-layer-htp-file.h +++ b/framework/src/suricata/src/app-layer-htp-file.h @@ -25,7 +25,7 @@ #ifndef __APP_LAYER_HTP_FILE_H__ #define __APP_LAYER_HTP_FILE_H__ -int HTPFileOpen(HtpState *, uint8_t *, uint16_t, uint8_t *, uint32_t, uint16_t, uint8_t); +int HTPFileOpen(HtpState *, uint8_t *, uint16_t, uint8_t *, uint32_t, uint64_t, uint8_t); int HTPFileStoreChunk(HtpState *, uint8_t *, uint32_t, uint8_t); int HTPFileClose(HtpState *, uint8_t *, uint32_t, uint8_t, uint8_t); diff --git a/framework/src/suricata/src/app-layer-htp.c b/framework/src/suricata/src/app-layer-htp.c index e8da88eb..5fd09492 100644 --- a/framework/src/suricata/src/app-layer-htp.c +++ b/framework/src/suricata/src/app-layer-htp.c @@ -1812,6 +1812,9 @@ int HTPCallbackRequestBodyData(htp_tx_data_t *d) } } + /* see if we can get rid of htp body chunks */ + HtpBodyPrune(hstate, &tx_ud->request_body, STREAM_TOSERVER); + SCLogDebug("tx_ud->request_body.content_len_so_far %"PRIu64, tx_ud->request_body.content_len_so_far); SCLogDebug("hstate->cfg->request_body_limit %u", hstate->cfg->request_body_limit); @@ -1863,9 +1866,6 @@ int HTPCallbackRequestBodyData(htp_tx_data_t *d) } end: - /* see if we can get rid of htp body chunks */ - HtpBodyPrune(hstate, &tx_ud->request_body, STREAM_TOSERVER); - /* set the new chunk flag */ hstate->flags |= HTP_FLAG_NEW_BODY_SET; @@ -1911,6 +1911,9 @@ int HTPCallbackResponseBodyData(htp_tx_data_t *d) tx_ud->operation = HTP_BODY_RESPONSE; } + /* see if we can get rid of htp body chunks */ + HtpBodyPrune(hstate, &tx_ud->response_body, STREAM_TOCLIENT); + SCLogDebug("tx_ud->response_body.content_len_so_far %"PRIu64, tx_ud->response_body.content_len_so_far); SCLogDebug("hstate->cfg->response_body_limit %u", hstate->cfg->response_body_limit); @@ -1932,9 +1935,6 @@ int HTPCallbackResponseBodyData(htp_tx_data_t *d) HtpResponseBodyHandle(hstate, tx_ud, d->tx, (uint8_t *)d->data, (uint32_t)d->len); } - /* see if we can get rid of htp body chunks */ - HtpBodyPrune(hstate, &tx_ud->response_body, STREAM_TOCLIENT); - /* set the new chunk flag */ hstate->flags |= HTP_FLAG_NEW_BODY_SET; diff --git a/framework/src/suricata/src/app-layer-modbus.c b/framework/src/suricata/src/app-layer-modbus.c index fa965135..2d2cdc3d 100644 --- a/framework/src/suricata/src/app-layer-modbus.c +++ b/framework/src/suricata/src/app-layer-modbus.c @@ -1427,21 +1427,13 @@ void RegisterModbusParsers(void) STREAM_TOSERVER, ModbusProbingParser); } else { - /* if we have no config, we enable the default port 502 */ + /* If there is no app-layer section for Modbus, silently + * leave it disabled. */ if (!AppLayerProtoDetectPPParseConfPorts("tcp", IPPROTO_TCP, proto_name, ALPROTO_MODBUS, 0, sizeof(ModbusHeader), ModbusProbingParser)) { - SCLogWarning(SC_ERR_MODBUS_CONFIG, "no Modbus TCP config found, " - "enabling Modbus detection on " - "port 502."); - - AppLayerProtoDetectPPRegister(IPPROTO_TCP, - "502", - ALPROTO_MODBUS, - 0, sizeof(ModbusHeader), - STREAM_TOSERVER, - ModbusProbingParser); + return; } } diff --git a/framework/src/suricata/src/app-layer-smtp.c b/framework/src/suricata/src/app-layer-smtp.c index cd0a732e..61ac4ec6 100644 --- a/framework/src/suricata/src/app-layer-smtp.c +++ b/framework/src/suricata/src/app-layer-smtp.c @@ -887,12 +887,14 @@ static int SMTPProcessReply(SMTPState *state, Flow *f, state->parser_state |= SMTP_PARSER_STATE_FIRST_REPLY_SEEN; if (reply_code == SMTP_REPLY_220) SCReturnInt(0); - else + else { SMTPSetEvent(state, SMTP_DECODER_EVENT_INVALID_REPLY); + SCReturnInt(0); + } } else { /* decoder event - unable to match reply with request */ SCLogDebug("unable to match reply with request"); - SCReturnInt(-1); + SCReturnInt(0); } } diff --git a/framework/src/suricata/src/app-layer-tls-handshake.c b/framework/src/suricata/src/app-layer-tls-handshake.c index ca2e7f49..530a7c1f 100644 --- a/framework/src/suricata/src/app-layer-tls-handshake.c +++ b/framework/src/suricata/src/app-layer-tls-handshake.c @@ -174,7 +174,7 @@ int DecodeTLSHandshakeServerCertificate(SSLState *ssl_state, uint8_t *input, uin int j = 0; if (hash == NULL) { - SCLogWarning(SC_ERR_MEM_ALLOC, "Can not allocate fingerprint string"); + // TODO maybe an event here? } else { for (j = 0; j < hash_len; j++, p += 3) { snprintf(p, 4, j == hash_len - 1 ? "%02x" : "%02x:", hash[j]); @@ -182,7 +182,7 @@ int DecodeTLSHandshakeServerCertificate(SSLState *ssl_state, uint8_t *input, uin SCFree(hash); ssl_state->server_connp.cert0_fingerprint = SCStrdup(out); if (ssl_state->server_connp.cert0_fingerprint == NULL) { - SCLogWarning(SC_ERR_MEM_ALLOC, "Can not allocate fingerprint string"); + // TODO do we need an event here? } } diff --git a/framework/src/suricata/src/decode-icmpv4.c b/framework/src/suricata/src/decode-icmpv4.c index 5af012ce..45b213f6 100644 --- a/framework/src/suricata/src/decode-icmpv4.c +++ b/framework/src/suricata/src/decode-icmpv4.c @@ -47,13 +47,13 @@ /** * Note, this is the IP header, plus a bit of the original packet, not the whole thing! */ -void DecodePartialIPV4( Packet* p, uint8_t* partial_packet, uint16_t len ) +int DecodePartialIPV4( Packet* p, uint8_t* partial_packet, uint16_t len ) { /** Check the sizes, the header must fit at least */ if (len < IPV4_HEADER_LEN) { SCLogDebug("DecodePartialIPV4: ICMPV4_IPV4_TRUNC_PKT"); ENGINE_SET_INVALID_EVENT(p, ICMPV4_IPV4_TRUNC_PKT); - return; + return -1; } IPV4Hdr *icmp4_ip4h = (IPV4Hdr*)partial_packet; @@ -64,7 +64,7 @@ void DecodePartialIPV4( Packet* p, uint8_t* partial_packet, uint16_t len ) SCLogDebug("DecodePartialIPV4: ICMPv4 contains Unknown IPV4 version " "ICMPV4_IPV4_UNKNOWN_VER"); ENGINE_SET_INVALID_EVENT(p, ICMPV4_IPV4_UNKNOWN_VER); - return; + return -1; } /** We need to fill icmpv4vars */ @@ -125,12 +125,14 @@ void DecodePartialIPV4( Packet* p, uint8_t* partial_packet, uint16_t len ) break; case IPPROTO_ICMP: - p->icmpv4vars.emb_icmpv4h = (ICMPV4Hdr*)(partial_packet + IPV4_HEADER_LEN); - p->icmpv4vars.emb_sport = 0; - p->icmpv4vars.emb_dport = 0; - p->icmpv4vars.emb_ip4_proto = IPPROTO_ICMP; + if (len >= IPV4_HEADER_LEN + ICMPV4_HEADER_LEN ) { + p->icmpv4vars.emb_icmpv4h = (ICMPV4Hdr*)(partial_packet + IPV4_HEADER_LEN); + p->icmpv4vars.emb_sport = 0; + p->icmpv4vars.emb_dport = 0; + p->icmpv4vars.emb_ip4_proto = IPPROTO_ICMP; - SCLogDebug("DecodePartialIPV4: ICMPV4->IPV4->ICMP header"); + SCLogDebug("DecodePartialIPV4: ICMPV4->IPV4->ICMP header"); + } break; } @@ -144,8 +146,7 @@ void DecodePartialIPV4( Packet* p, uint8_t* partial_packet, uint16_t len ) IPV4_GET_RAW_IPPROTO(icmp4_ip4h), IPV4_GET_RAW_IPID(icmp4_ip4h)); #endif - return; - + return 0; } /** DecodeICMPV4 @@ -188,11 +189,13 @@ int DecodeICMPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, } else { /* parse IP header plus 64 bytes */ if (len > ICMPV4_HEADER_PKT_OFFSET) { - DecodePartialIPV4( p, (uint8_t *)(pkt + ICMPV4_HEADER_PKT_OFFSET), len - ICMPV4_HEADER_PKT_OFFSET ); - - /* ICMP ICMP_DEST_UNREACH influence TCP/UDP flows */ - if (ICMPV4_DEST_UNREACH_IS_VALID(p)) { - FlowHandlePacket(tv, dtv, p); + if (DecodePartialIPV4(p, (uint8_t *)(pkt + ICMPV4_HEADER_PKT_OFFSET), + len - ICMPV4_HEADER_PKT_OFFSET ) == 0) + { + /* ICMP ICMP_DEST_UNREACH influence TCP/UDP flows */ + if (ICMPV4_DEST_UNREACH_IS_VALID(p)) { + FlowHandlePacket(tv, dtv, p); + } } } } diff --git a/framework/src/suricata/src/decode-icmpv4.h b/framework/src/suricata/src/decode-icmpv4.h index f8cb97f4..2f5862d3 100644 --- a/framework/src/suricata/src/decode-icmpv4.h +++ b/framework/src/suricata/src/decode-icmpv4.h @@ -179,8 +179,6 @@ typedef struct ICMPV4Vars_ { uint16_t id; uint16_t seq; - uint32_t mtu; - uint32_t error_ptr; /** Pointers to the embedded packet headers */ IPV4Hdr *emb_ipv4h; @@ -203,8 +201,6 @@ typedef struct ICMPV4Vars_ (p)->level4_comp_csum = -1; \ (p)->icmpv4vars.id = 0; \ (p)->icmpv4vars.seq = 0; \ - (p)->icmpv4vars.mtu = 0; \ - (p)->icmpv4vars.error_ptr = 0; \ (p)->icmpv4vars.emb_ipv4h = NULL; \ (p)->icmpv4vars.emb_tcph = NULL; \ (p)->icmpv4vars.emb_udph = NULL; \ @@ -236,13 +232,6 @@ typedef struct ICMPV4Vars_ /* If message is Error */ -/** macro for icmpv4 "unused" access */ -#define ICMPV4_GET_UNUSED(p) (p)->icmpv4h->icmpv4b.icmpv4e.unused -/** macro for icmpv4 "error_ptr" access */ -#define ICMPV4_GET_ERROR_PTR(p) (p)->icmpv4h->icmpv4b.icmpv4e.error_ptr -/** macro for icmpv4 "mtu" access */ -#define ICMPV4_GET_MTU(p) (p)->icmpv4h->icmpv4b.icmpv4e.mtu - /** macro for icmpv4 embedded "protocol" access */ #define ICMPV4_GET_EMB_PROTO(p) (p)->icmpv4vars.emb_ip4_proto /** macro for icmpv4 embedded "ipv4h" header access */ @@ -259,7 +248,9 @@ typedef struct ICMPV4Vars_ * * \warning use only _after_ the decoder has processed the packet */ -#define ICMPV4_DEST_UNREACH_IS_VALID(p) (((p)->icmpv4h != NULL) && \ +#define ICMPV4_DEST_UNREACH_IS_VALID(p) ( \ + (!((p)->flags & PKT_IS_INVALID)) && \ + ((p)->icmpv4h != NULL) && \ (ICMPV4_GET_TYPE((p)) == ICMP_DEST_UNREACH) && \ (ICMPV4_GET_EMB_IPV4((p)) != NULL) && \ ((ICMPV4_GET_EMB_TCP((p)) != NULL) || \ @@ -280,9 +271,6 @@ typedef struct ICMPV4Vars_ ICMPV4_GET_TYPE((p)) == ICMP_TIME_EXCEEDED || \ ICMPV4_GET_TYPE((p)) == ICMP_PARAMETERPROB) -typedef struct ICMPV4Cache_ { -} ICMPV4Cache; - void DecodeICMPV4RegisterTests(void); /** ------ Inline functions ------ */ diff --git a/framework/src/suricata/src/detect.c b/framework/src/suricata/src/detect.c index 401d2b00..74a1b8a9 100644 --- a/framework/src/suricata/src/detect.c +++ b/framework/src/suricata/src/detect.c @@ -1827,6 +1827,7 @@ end: DetectEngineCleanHCBDBuffers(det_ctx); DetectEngineCleanHSBDBuffers(det_ctx); DetectEngineCleanHHDBuffers(det_ctx); + DetectEngineCleanSMTPBuffers(det_ctx); /* store the found sgh (or NULL) in the flow to save us from looking it * up again for the next packet. Also return any stream chunk we processed diff --git a/framework/src/suricata/src/log-droplog.c b/framework/src/suricata/src/log-droplog.c index 6eafd9d5..67cbd1b1 100644 --- a/framework/src/suricata/src/log-droplog.c +++ b/framework/src/suricata/src/log-droplog.c @@ -224,30 +224,34 @@ static int LogDropLogNetFilter (ThreadVars *tv, const Packet *p, void *data) switch (proto) { case IPPROTO_TCP: - fprintf(dlt->file_ctx->fp, " SPT=%"PRIu16" DPT=%"PRIu16" " - "SEQ=%"PRIu32" ACK=%"PRIu32" WINDOW=%"PRIu32"", - GET_TCP_SRC_PORT(p), GET_TCP_DST_PORT(p), TCP_GET_SEQ(p), - TCP_GET_ACK(p), TCP_GET_WINDOW(p)); - fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_SYN(p) ? " SYN" : ""); - fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_ACK(p) ? " ACK" : ""); - fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_PUSH(p) ? " PSH" : ""); - fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_RST(p) ? " RST" : ""); - fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_URG(p) ? " URG" : ""); - fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_FIN(p) ? " FIN" : ""); - fprintf(dlt->file_ctx->fp, " RES=0x%02"PRIu8" URGP=%"PRIu16"", - TCP_GET_RAW_X2(p->tcph), TCP_GET_URG_POINTER(p)); + if (PKT_IS_TCP(p)) { + fprintf(dlt->file_ctx->fp, " SPT=%"PRIu16" DPT=%"PRIu16" " + "SEQ=%"PRIu32" ACK=%"PRIu32" WINDOW=%"PRIu32"", + GET_TCP_SRC_PORT(p), GET_TCP_DST_PORT(p), TCP_GET_SEQ(p), + TCP_GET_ACK(p), TCP_GET_WINDOW(p)); + fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_SYN(p) ? " SYN" : ""); + fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_ACK(p) ? " ACK" : ""); + fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_PUSH(p) ? " PSH" : ""); + fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_RST(p) ? " RST" : ""); + fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_URG(p) ? " URG" : ""); + fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_FIN(p) ? " FIN" : ""); + fprintf(dlt->file_ctx->fp, " RES=0x%02"PRIu8" URGP=%"PRIu16"", + TCP_GET_RAW_X2(p->tcph), TCP_GET_URG_POINTER(p)); + } break; case IPPROTO_UDP: - fprintf(dlt->file_ctx->fp, " SPT=%"PRIu16" DPT=%"PRIu16"" - " LEN=%"PRIu16"", UDP_GET_SRC_PORT(p), - UDP_GET_DST_PORT(p), UDP_GET_LEN(p)); + if (PKT_IS_UDP(p)) { + fprintf(dlt->file_ctx->fp, " SPT=%"PRIu16" DPT=%"PRIu16"" + " LEN=%"PRIu16"", UDP_GET_SRC_PORT(p), + UDP_GET_DST_PORT(p), UDP_GET_LEN(p)); + } break; case IPPROTO_ICMP: if (PKT_IS_ICMPV4(p)) { fprintf(dlt->file_ctx->fp, " TYPE=%"PRIu8" CODE=%"PRIu8"" " ID=%"PRIu16" SEQ=%"PRIu16"", ICMPV4_GET_TYPE(p), ICMPV4_GET_CODE(p), ICMPV4_GET_ID(p), ICMPV4_GET_SEQ(p)); - } else if(PKT_IS_ICMPV6(p)) { + } else if (PKT_IS_ICMPV6(p)) { fprintf(dlt->file_ctx->fp, " TYPE=%"PRIu8" CODE=%"PRIu8"" " ID=%"PRIu16" SEQ=%"PRIu16"", ICMPV6_GET_TYPE(p), ICMPV6_GET_CODE(p), ICMPV6_GET_ID(p), ICMPV6_GET_SEQ(p)); diff --git a/framework/src/suricata/src/log-stats.c b/framework/src/suricata/src/log-stats.c index 5fcb1c9f..385dec2b 100644 --- a/framework/src/suricata/src/log-stats.c +++ b/framework/src/suricata/src/log-stats.c @@ -51,6 +51,7 @@ #define LOG_STATS_TOTALS (1<<0) #define LOG_STATS_THREADS (1<<1) +#define LOG_STATS_NULLS (1<<2) TmEcode LogStatsLogThreadInit(ThreadVars *, void *, void **); TmEcode LogStatsLogThreadDeinit(ThreadVars *, void *); @@ -108,6 +109,9 @@ int LogStatsLogger(ThreadVars *tv, void *thread_data, const StatsTable *st) if (st->stats[u].name == NULL) continue; + if (!(aft->statslog_ctx->flags & LOG_STATS_NULLS) && st->stats[u].value == 0) + continue; + char line[1024]; size_t len = snprintf(line, sizeof(line), "%-25s | %-25s | %-" PRIu64 "\n", st->stats[u].name, st->stats[u].tm_name, st->stats[u].value); @@ -238,6 +242,7 @@ OutputCtx *LogStatsLogInitCtx(ConfNode *conf) if (conf != NULL) { const char *totals = ConfNodeLookupChildValue(conf, "totals"); const char *threads = ConfNodeLookupChildValue(conf, "threads"); + const char *nulls = ConfNodeLookupChildValue(conf, "null-values"); SCLogDebug("totals %s threads %s", totals, threads); if (totals != NULL && ConfValIsFalse(totals)) { @@ -246,6 +251,9 @@ OutputCtx *LogStatsLogInitCtx(ConfNode *conf) if (threads != NULL && ConfValIsTrue(threads)) { statslog_ctx->flags |= LOG_STATS_THREADS; } + if (nulls != NULL && ConfValIsTrue(nulls)) { + statslog_ctx->flags |= LOG_STATS_NULLS; + } SCLogDebug("statslog_ctx->flags %08x", statslog_ctx->flags); } diff --git a/framework/src/suricata/src/output-json-drop.c b/framework/src/suricata/src/output-json-drop.c index c9b01df8..68c14d9b 100644 --- a/framework/src/suricata/src/output-json-drop.c +++ b/framework/src/suricata/src/output-json-drop.c @@ -114,20 +114,24 @@ static int DropLogJSON (JsonDropLogThread *aft, const Packet *p) } switch (proto) { case IPPROTO_TCP: - json_object_set_new(djs, "tcpseq", json_integer(TCP_GET_SEQ(p))); - json_object_set_new(djs, "tcpack", json_integer(TCP_GET_ACK(p))); - json_object_set_new(djs, "tcpwin", json_integer(TCP_GET_WINDOW(p))); - json_object_set_new(djs, "syn", TCP_ISSET_FLAG_SYN(p) ? json_true() : json_false()); - json_object_set_new(djs, "ack", TCP_ISSET_FLAG_ACK(p) ? json_true() : json_false()); - json_object_set_new(djs, "psh", TCP_ISSET_FLAG_PUSH(p) ? json_true() : json_false()); - json_object_set_new(djs, "rst", TCP_ISSET_FLAG_RST(p) ? json_true() : json_false()); - json_object_set_new(djs, "urg", TCP_ISSET_FLAG_URG(p) ? json_true() : json_false()); - json_object_set_new(djs, "fin", TCP_ISSET_FLAG_FIN(p) ? json_true() : json_false()); - json_object_set_new(djs, "tcpres", json_integer(TCP_GET_RAW_X2(p->tcph))); - json_object_set_new(djs, "tcpurgp", json_integer(TCP_GET_URG_POINTER(p))); + if (PKT_IS_TCP(p)) { + json_object_set_new(djs, "tcpseq", json_integer(TCP_GET_SEQ(p))); + json_object_set_new(djs, "tcpack", json_integer(TCP_GET_ACK(p))); + json_object_set_new(djs, "tcpwin", json_integer(TCP_GET_WINDOW(p))); + json_object_set_new(djs, "syn", TCP_ISSET_FLAG_SYN(p) ? json_true() : json_false()); + json_object_set_new(djs, "ack", TCP_ISSET_FLAG_ACK(p) ? json_true() : json_false()); + json_object_set_new(djs, "psh", TCP_ISSET_FLAG_PUSH(p) ? json_true() : json_false()); + json_object_set_new(djs, "rst", TCP_ISSET_FLAG_RST(p) ? json_true() : json_false()); + json_object_set_new(djs, "urg", TCP_ISSET_FLAG_URG(p) ? json_true() : json_false()); + json_object_set_new(djs, "fin", TCP_ISSET_FLAG_FIN(p) ? json_true() : json_false()); + json_object_set_new(djs, "tcpres", json_integer(TCP_GET_RAW_X2(p->tcph))); + json_object_set_new(djs, "tcpurgp", json_integer(TCP_GET_URG_POINTER(p))); + } break; case IPPROTO_UDP: - json_object_set_new(djs, "udplen", json_integer(UDP_GET_LEN(p))); + if (PKT_IS_UDP(p)) { + json_object_set_new(djs, "udplen", json_integer(UDP_GET_LEN(p))); + } break; case IPPROTO_ICMP: if (PKT_IS_ICMPV4(p)) { diff --git a/framework/src/suricata/src/output-json-file.c b/framework/src/suricata/src/output-json-file.c index 9506a746..32f3a943 100644 --- a/framework/src/suricata/src/output-json-file.c +++ b/framework/src/suricata/src/output-json-file.c @@ -108,6 +108,8 @@ static void FileWriteJsonRecord(JsonFileLogThread *aft, const Packet *p, const F break; } + json_object_set_new(js, "app_proto", + json_string(AppProtoToString(p->flow->alproto))); json_t *fjs = json_object(); if (unlikely(fjs == NULL)) { diff --git a/framework/src/suricata/src/output-json-flow.c b/framework/src/suricata/src/output-json-flow.c index 7ff0d3d2..f89c32df 100644 --- a/framework/src/suricata/src/output-json-flow.c +++ b/framework/src/suricata/src/output-json-flow.c @@ -188,7 +188,7 @@ static void JsonFlowLogJSON(JsonFlowLogThread *aft, json_t *js, Flow *f) return; } - json_object_set_new(hjs, "app_proto", json_string(AppProtoToString(f->alproto))); + json_object_set_new(js, "app_proto", json_string(AppProtoToString(f->alproto))); json_object_set_new(hjs, "pkts_toserver", json_integer(f->todstpktcnt)); diff --git a/framework/src/suricata/src/output-json-netflow.c b/framework/src/suricata/src/output-json-netflow.c index 153beb3d..1b1fa8c0 100644 --- a/framework/src/suricata/src/output-json-netflow.c +++ b/framework/src/suricata/src/output-json-netflow.c @@ -194,7 +194,7 @@ static void JsonNetFlowLogJSONToServer(JsonNetFlowLogThread *aft, json_t *js, Fl return; } - json_object_set_new(hjs, "app_proto", + json_object_set_new(js, "app_proto", json_string(AppProtoToString(f->alproto_ts ? f->alproto_ts : f->alproto))); json_object_set_new(hjs, "pkts", @@ -243,7 +243,7 @@ static void JsonNetFlowLogJSONToClient(JsonNetFlowLogThread *aft, json_t *js, Fl return; } - json_object_set_new(hjs, "app_proto", + json_object_set_new(js, "app_proto", json_string(AppProtoToString(f->alproto_tc ? f->alproto_tc : f->alproto))); json_object_set_new(hjs, "pkts", diff --git a/framework/src/suricata/src/runmode-af-packet.c b/framework/src/suricata/src/runmode-af-packet.c index fc17a4bd..cd98b229 100644 --- a/framework/src/suricata/src/runmode-af-packet.c +++ b/framework/src/suricata/src/runmode-af-packet.c @@ -92,6 +92,10 @@ void AFPDerefConfig(void *conf) } } +/* if cluster id is not set, assign it automagically, uniq value per + * interface. */ +static int cluster_id_auto = 1; + /** * \brief extract information from config file * @@ -192,7 +196,7 @@ void *ParseAFPConfig(const char *iface) if (rss_queues > 0) { if (rss_queues < aconf->threads) { aconf->threads = rss_queues; - SCLogInfo("More core than RSS queues, using %d threads for interface %s", + SCLogInfo("More cores than RSS queues, using %d threads for interface %s", aconf->threads, iface); } } @@ -252,14 +256,15 @@ void *ParseAFPConfig(const char *iface) (void) SC_ATOMIC_ADD(aconf->ref, aconf->threads); if (ConfGetChildValueWithDefault(if_root, if_default, "cluster-id", &tmpclusterid) != 1) { - SCLogError(SC_ERR_INVALID_ARGUMENT,"Could not get cluster-id from config"); + aconf->cluster_id = (uint16_t)(cluster_id_auto++); } else { aconf->cluster_id = (uint16_t)atoi(tmpclusterid); SCLogDebug("Going to use cluster-id %" PRId32, aconf->cluster_id); } if (ConfGetChildValueWithDefault(if_root, if_default, "cluster-type", &tmpctype) != 1) { - SCLogError(SC_ERR_GET_CLUSTER_TYPE_FAILED,"Could not get cluster-type from config"); + /* default to our safest choice: flow hashing + defrag enabled */ + aconf->cluster_type = PACKET_FANOUT_HASH | PACKET_FANOUT_FLAG_DEFRAG; } else if (strcmp(tmpctype, "cluster_round_robin") == 0) { SCLogInfo("Using round-robin cluster mode for AF_PACKET (iface %s)", aconf->iface); @@ -367,6 +372,22 @@ void *ParseAFPConfig(const char *iface) "Using AF_PACKET with GRO or LRO activated can lead to capture problems"); } + char *active_runmode = RunmodeGetActive(); + if (active_runmode && !strcmp("workers", active_runmode)) { + aconf->flags |= AFP_ZERO_COPY; + SCLogInfo("%s: enabling zero copy mode", iface); + } else { + /* If we are using copy mode we need a lock */ + aconf->flags |= AFP_SOCK_PROTECT; + } + + /* If we are in RING mode, then we can use ZERO copy + * by using the data release mechanism */ + if (aconf->flags & AFP_RING_MODE) { + aconf->flags |= AFP_ZERO_COPY; + SCLogInfo("%s: enabling zero copy mode by using data release call", iface); + } + return aconf; } @@ -492,7 +513,7 @@ int RunModeIdsAFPAutoFp(void) exit(EXIT_FAILURE); } - SCLogInfo("RunModeIdsAFPAutoFp initialised"); + SCLogDebug("RunModeIdsAFPAutoFp initialised"); #endif /* HAVE_AF_PACKET */ SCReturnInt(0); @@ -534,7 +555,7 @@ int RunModeIdsAFPSingle(void) exit(EXIT_FAILURE); } - SCLogInfo("RunModeIdsAFPSingle initialised"); + SCLogDebug("RunModeIdsAFPSingle initialised"); #endif /* HAVE_AF_PACKET */ SCReturnInt(0); @@ -579,7 +600,7 @@ int RunModeIdsAFPWorkers(void) exit(EXIT_FAILURE); } - SCLogInfo("RunModeIdsAFPWorkers initialised"); + SCLogDebug("RunModeIdsAFPWorkers initialised"); #endif /* HAVE_AF_PACKET */ SCReturnInt(0); diff --git a/framework/src/suricata/src/runmode-unix-socket.c b/framework/src/suricata/src/runmode-unix-socket.c index 06a71869..46aa3100 100644 --- a/framework/src/suricata/src/runmode-unix-socket.c +++ b/framework/src/suricata/src/runmode-unix-socket.c @@ -346,13 +346,15 @@ TmEcode UnixSocketPcapFilesCheck(void *data) unix_manager_file_task_running = 1; this->running = 1; if (ConfSet("pcap-file.file", cfile->filename) != 1) { - SCLogInfo("Can not set working file to '%s'", cfile->filename); + SCLogError(SC_ERR_INVALID_ARGUMENTS, + "Can not set working file to '%s'", cfile->filename); PcapFilesFree(cfile); return TM_ECODE_FAILED; } if (cfile->output_dir) { if (ConfSet("default-log-dir", cfile->output_dir) != 1) { - SCLogInfo("Can not set output dir to '%s'", cfile->output_dir); + SCLogError(SC_ERR_INVALID_ARGUMENTS, + "Can not set output dir to '%s'", cfile->output_dir); PcapFilesFree(cfile); return TM_ECODE_FAILED; } @@ -361,7 +363,8 @@ TmEcode UnixSocketPcapFilesCheck(void *data) char tstr[16] = ""; snprintf(tstr, sizeof(tstr), "%d", cfile->tenant_id); if (ConfSet("pcap-file.tenant-id", tstr) != 1) { - SCLogInfo("Can not set working tenant-id to '%s'", tstr); + SCLogError(SC_ERR_INVALID_ARGUMENTS, + "Can not set working tenant-id to '%s'", tstr); PcapFilesFree(cfile); return TM_ECODE_FAILED; } diff --git a/framework/src/suricata/src/source-af-packet.c b/framework/src/suricata/src/source-af-packet.c index 3f1f44e1..f9eb8658 100644 --- a/framework/src/suricata/src/source-af-packet.c +++ b/framework/src/suricata/src/source-af-packet.c @@ -1073,7 +1073,7 @@ static int AFPSynchronizeStart(AFPThreadVars *ptv) } /* no packets */ } else if (r == 0 && AFPPeersListStarted()) { - SCLogInfo("Starting to read on %s", ptv->tv->name); + SCLogDebug("Starting to read on %s", ptv->tv->name); return 1; } else if (r < 0) { /* only exit on error */ SCLogWarning(SC_ERR_AFP_READ, "poll failed with retval %d", r); @@ -1154,7 +1154,7 @@ TmEcode ReceiveAFPLoop(ThreadVars *tv, void *data, void *slot) AFPPeersListReachedInc(); } if (ptv->afp_state == AFP_STATE_UP) { - SCLogInfo("Thread %s using socket %d", tv->name, ptv->socket); + SCLogDebug("Thread %s using socket %d", tv->name, ptv->socket); AFPSynchronizeStart(ptv); } @@ -1570,8 +1570,7 @@ static int AFPCreateSocket(AFPThreadVars *ptv, char *devname, int verbose) ptv->frame_offset = 0; } - SCLogInfo("Using interface '%s' via socket %d", (char *)devname, ptv->socket); - + SCLogDebug("Using interface '%s' via socket %d", (char *)devname, ptv->socket); ptv->datalink = AFPGetDevLinktype(ptv->socket, ptv->iface); switch (ptv->datalink) { @@ -1702,9 +1701,9 @@ TmEcode ReceiveAFPThreadInit(ThreadVars *tv, void *initdata, void **data) ptv->cluster_id = 1; /* We only set cluster info if the number of reader threads is greater than 1 */ if (afpconfig->threads > 1) { - ptv->cluster_id = afpconfig->cluster_id; - ptv->cluster_type = afpconfig->cluster_type; - ptv->threads = afpconfig->threads; + ptv->cluster_id = afpconfig->cluster_id; + ptv->cluster_type = afpconfig->cluster_type; + ptv->threads = afpconfig->threads; } #endif ptv->flags = afpconfig->flags; @@ -1720,23 +1719,6 @@ TmEcode ReceiveAFPThreadInit(ThreadVars *tv, void *initdata, void **data) ptv->tv); #endif - char *active_runmode = RunmodeGetActive(); - - if (active_runmode && !strcmp("workers", active_runmode)) { - ptv->flags |= AFP_ZERO_COPY; - SCLogInfo("Enabling zero copy mode"); - } else { - /* If we are using copy mode we need a lock */ - ptv->flags |= AFP_SOCK_PROTECT; - } - - /* If we are in RING mode, then we can use ZERO copy - * by using the data release mechanism */ - if (ptv->flags & AFP_RING_MODE) { - ptv->flags |= AFP_ZERO_COPY; - SCLogInfo("Enabling zero copy mode by using data release call"); - } - ptv->copy_mode = afpconfig->copy_mode; if (ptv->copy_mode != AFP_COPY_MODE_NONE) { strlcpy(ptv->out_iface, afpconfig->out_iface, AFP_IFACE_NAME_LENGTH); @@ -1860,19 +1842,22 @@ TmEcode DecodeAFP(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, Packet } /* call the decoder */ - switch(p->datalink) { - case LINKTYPE_LINUX_SLL: - DecodeSll(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); - break; + switch (p->datalink) { case LINKTYPE_ETHERNET: DecodeEthernet(tv, dtv, p,GET_PKT_DATA(p), GET_PKT_LEN(p), pq); break; + case LINKTYPE_LINUX_SLL: + DecodeSll(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); + break; case LINKTYPE_PPP: DecodePPP(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); break; case LINKTYPE_RAW: DecodeRaw(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); break; + case LINKTYPE_NULL: + DecodeNull(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); + break; default: SCLogError(SC_ERR_DATALINK_UNIMPLEMENTED, "Error: datalink type %" PRId32 " not yet supported in module DecodeAFP", p->datalink); break; diff --git a/framework/src/suricata/src/source-pcap.c b/framework/src/suricata/src/source-pcap.c index 0656f958..1f0c59bd 100644 --- a/framework/src/suricata/src/source-pcap.c +++ b/framework/src/suricata/src/source-pcap.c @@ -554,6 +554,7 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) 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); } diff --git a/framework/src/suricata/src/stream-tcp-reassemble.c b/framework/src/suricata/src/stream-tcp-reassemble.c index a947fab3..94deab43 100644 --- a/framework/src/suricata/src/stream-tcp-reassemble.c +++ b/framework/src/suricata/src/stream-tcp-reassemble.c @@ -2696,8 +2696,7 @@ static inline int DoReassemble(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, if (SEQ_LT(stream->last_ack, (seg->seq + seg->payload_len))) { if (SEQ_LT(stream->last_ack, (rd->ra_base_seq + 1))) { - payload_len = (stream->last_ack - seg->seq); - SCLogDebug("payload_len %u", payload_len); + return 1; } else { payload_len = (stream->last_ack - seg->seq) - payload_offset; SCLogDebug("payload_len %u", payload_len); @@ -2752,12 +2751,18 @@ static inline int DoReassemble(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, /* copy the data into the buffer */ uint16_t copy_size = sizeof(rd->data) - rd->data_len; + if (copy_size + payload_offset > seg->payload_len) { + copy_size = seg->payload_len - payload_offset; + } if (copy_size > payload_len) { copy_size = payload_len; } if (SCLogDebugEnabled()) { BUG_ON(copy_size > sizeof(rd->data)); + BUG_ON(copy_size+payload_offset > seg->payload_len); + BUG_ON(copy_size+payload_offset > seg->pool_size); } + SCLogDebug("copy_size is %"PRIu16"", copy_size); memcpy(rd->data + rd->data_len, seg->payload + payload_offset, copy_size); rd->data_len += copy_size; @@ -3141,7 +3146,7 @@ static int DoRawReassemble(TcpSession *ssn, TcpStream *stream, TcpSegment *seg, if (SEQ_LT(stream->last_ack, (seg->seq + seg->payload_len))) { if (SEQ_LT(stream->last_ack, rd->ra_base_seq)) { - payload_len = (stream->last_ack - seg->seq); + return 1; } else { payload_len = (stream->last_ack - seg->seq) - payload_offset; } @@ -3189,6 +3194,9 @@ static int DoRawReassemble(TcpSession *ssn, TcpStream *stream, TcpSegment *seg, /* copy the data into the smsg */ uint32_t copy_size = rd->smsg->data_size - rd->smsg_offset; + if (copy_size + payload_offset > seg->payload_len) { + copy_size = seg->payload_len - payload_offset; + } if (copy_size > payload_len) { copy_size = payload_len; } diff --git a/framework/src/suricata/src/suricata.c b/framework/src/suricata/src/suricata.c index b368f21d..a6ed5736 100644 --- a/framework/src/suricata/src/suricata.c +++ b/framework/src/suricata/src/suricata.c @@ -1108,6 +1108,7 @@ static TmEcode ParseCommandLine(int argc, char** argv, SCInstance *suri) int build_info = 0; int conf_test = 0; int engine_analysis = 0; + int set_log_directory = 0; int ret = TM_ECODE_OK; #ifdef UNITTESTS @@ -1580,6 +1581,8 @@ static TmEcode ParseCommandLine(int argc, char** argv, SCInstance *suri) "exist. Shutting down the engine.", optarg, optarg); return TM_ECODE_FAILED; } + set_log_directory = 1; + break; case 'q': #ifdef NFQ @@ -1714,6 +1717,11 @@ static TmEcode ParseCommandLine(int argc, char** argv, SCInstance *suri) return TM_ECODE_FAILED; } + if ((suri->run_mode == RUNMODE_UNIX_SOCKET) && set_log_directory) { + SCLogError(SC_ERR_INITIALIZATION, "can't use -l and unix socket runmode at the same time"); + return TM_ECODE_FAILED; + } + if (list_app_layer_protocols) suri->run_mode = RUNMODE_LIST_APP_LAYERS; if (list_cuda_cards) diff --git a/framework/src/suricata/src/unix-manager.c b/framework/src/suricata/src/unix-manager.c index 9357f4c5..ca92677b 100644 --- a/framework/src/suricata/src/unix-manager.c +++ b/framework/src/suricata/src/unix-manager.c @@ -851,25 +851,6 @@ static TmEcode UnixManagerThreadInit(ThreadVars *t, void *initdata, void **data) if (utd == NULL) return TM_ECODE_FAILED; - *data = utd; - return TM_ECODE_OK; -} - -static TmEcode UnixManagerThreadDeinit(ThreadVars *t, void *data) -{ - SCFree(data); - return TM_ECODE_OK; -} - -static TmEcode UnixManager(ThreadVars *th_v, void *thread_data) -{ - int ret; - - /* set the thread name */ - SCLogDebug("%s started...", th_v->name); - - StatsSetupPrivate(th_v); - if (UnixNew(&command) == 0) { int failure_fatal = 0; SCLogError(SC_ERR_INITIALIZATION, @@ -884,10 +865,6 @@ static TmEcode UnixManager(ThreadVars *th_v, void *thread_data) } } - /* Set the threads capability */ - th_v->cap_flags = 0; - SCDropCaps(th_v); - /* Init Unix socket */ UnixManagerRegisterCommand("shutdown", UnixManagerShutdownCommand, NULL, 0); UnixManagerRegisterCommand("command-list", UnixManagerListCommand, &command, 0); @@ -905,6 +882,28 @@ static TmEcode UnixManager(ThreadVars *th_v, void *thread_data) UnixManagerRegisterCommand("reload-tenant", UnixSocketReloadTenant, &command, UNIX_CMD_TAKE_ARGS); UnixManagerRegisterCommand("unregister-tenant", UnixSocketUnregisterTenant, &command, UNIX_CMD_TAKE_ARGS); + *data = utd; + return TM_ECODE_OK; +} + +static TmEcode UnixManagerThreadDeinit(ThreadVars *t, void *data) +{ + SCFree(data); + return TM_ECODE_OK; +} + +static TmEcode UnixManager(ThreadVars *th_v, void *thread_data) +{ + int ret; + + /* set the thread name */ + SCLogDebug("%s started...", th_v->name); + + StatsSetupPrivate(th_v); + + /* Set the threads capability */ + th_v->cap_flags = 0; + SCDropCaps(th_v); TmThreadsSetFlag(th_v, THV_INIT_DONE); while (1) { diff --git a/framework/src/suricata/src/util-decode-der.c b/framework/src/suricata/src/util-decode-der.c index 1687668b..05c4671a 100644 --- a/framework/src/suricata/src/util-decode-der.c +++ b/framework/src/suricata/src/util-decode-der.c @@ -482,7 +482,8 @@ static Asn1Generic * DecodeAsn1DerIA5String(const unsigned char *buffer, uint32_ SCFree(a); return NULL; } - strlcpy(a->str, (const char*)d_ptr, length+1); + memcpy(a->str, (const char*)d_ptr, length); + a->str[length] = 0; d_ptr += length; @@ -583,8 +584,8 @@ static Asn1Generic * DecodeAsn1DerPrintableString(const unsigned char *buffer, u SCFree(a); return NULL; } - strlcpy(a->str, (const char*)d_ptr, length+1); - a->str[length] = '\0'; + memcpy(a->str, (const char*)d_ptr, length); + a->str[length] = 0; d_ptr += length; diff --git a/framework/src/suricata/src/util-device.c b/framework/src/suricata/src/util-device.c index c08e30f0..fb2c04f6 100644 --- a/framework/src/suricata/src/util-device.c +++ b/framework/src/suricata/src/util-device.c @@ -42,7 +42,7 @@ static int live_devices_stats = 1; * \retval 0 on success. * \retval -1 on failure. */ -int LiveRegisterDevice(char *dev) +int LiveRegisterDevice(const char *dev) { LiveDevice *pd = SCMalloc(sizeof(LiveDevice)); if (unlikely(pd == NULL)) { @@ -113,7 +113,7 @@ char *LiveGetDeviceName(int number) * \retval ptr pointer to the string containing the device * \retval NULL on error */ -LiveDevice *LiveGetDevice(char *name) +LiveDevice *LiveGetDevice(const char *name) { int i = 0; LiveDevice *pd; @@ -136,12 +136,12 @@ LiveDevice *LiveGetDevice(char *name) -int LiveBuildDeviceList(char * runmode) +int LiveBuildDeviceList(const char *runmode) { return LiveBuildDeviceListCustom(runmode, "interface"); } -int LiveBuildDeviceListCustom(char * runmode, char * itemname) +int LiveBuildDeviceListCustom(const char *runmode, const char *itemname) { ConfNode *base = ConfGetNode(runmode); ConfNode *child; diff --git a/framework/src/suricata/src/util-device.h b/framework/src/suricata/src/util-device.h index fd6a8213..1fabdbe5 100644 --- a/framework/src/suricata/src/util-device.h +++ b/framework/src/suricata/src/util-device.h @@ -32,14 +32,14 @@ typedef struct LiveDevice_ { } LiveDevice; -int LiveRegisterDevice(char *dev); +int LiveRegisterDevice(const char *dev); int LiveGetDeviceCount(void); char *LiveGetDeviceName(int number); -LiveDevice *LiveGetDevice(char *dev); -int LiveBuildDeviceList(char * base); +LiveDevice *LiveGetDevice(const char *dev); +int LiveBuildDeviceList(const char *base); void LiveDeviceHasNoStats(void); int LiveDeviceListClean(void); -int LiveBuildDeviceListCustom(char * base, char * itemname); +int LiveBuildDeviceListCustom(const char *base, const char *itemname); #ifdef BUILD_UNIX_SOCKET TmEcode LiveDeviceIfaceStat(json_t *cmd, json_t *server_msg, void *data); diff --git a/framework/src/suricata/src/util-file.c b/framework/src/suricata/src/util-file.c index bfb68e1e..66d4080e 100644 --- a/framework/src/suricata/src/util-file.c +++ b/framework/src/suricata/src/util-file.c @@ -873,7 +873,7 @@ void FileDisableStoringForTransaction(Flow *f, uint8_t direction, uint64_t tx_id * \param fc file store * \param file_id the file's id */ -void FileStoreFileById(FileContainer *fc, uint16_t file_id) +void FileStoreFileById(FileContainer *fc, uint32_t file_id) { File *ptr = NULL; @@ -888,7 +888,7 @@ void FileStoreFileById(FileContainer *fc, uint16_t file_id) } } -void FileStoreAllFilesForTx(FileContainer *fc, uint16_t tx_id) +void FileStoreAllFilesForTx(FileContainer *fc, uint64_t tx_id) { File *ptr = NULL; diff --git a/framework/src/suricata/src/util-file.h b/framework/src/suricata/src/util-file.h index 9cfc3a85..8f322a99 100644 --- a/framework/src/suricata/src/util-file.h +++ b/framework/src/suricata/src/util-file.h @@ -62,7 +62,7 @@ typedef struct FileData_ { typedef struct File_ { uint16_t flags; uint64_t txid; /**< tx this file is part of */ - unsigned int file_id; + uint32_t file_id; uint8_t *name; uint16_t name_len; int16_t state; @@ -169,7 +169,7 @@ void FileDisableFilesize(Flow *f, uint8_t direction); */ void FileDisableStoringForTransaction(Flow *f, uint8_t direction, uint64_t tx_id); -void FlowFileDisableStoringForTransaction(struct Flow_ *f, uint16_t tx_id); +void FlowFileDisableStoringForTransaction(struct Flow_ *f, uint64_t tx_id); void FilePrune(FileContainer *ffc); @@ -184,8 +184,8 @@ int FileForceMd5(void); void FileForceTrackingEnable(void); void FileStoreAllFiles(FileContainer *); -void FileStoreAllFilesForTx(FileContainer *, uint16_t); -void FileStoreFileById(FileContainer *fc, uint16_t); +void FileStoreAllFilesForTx(FileContainer *, uint64_t); +void FileStoreFileById(FileContainer *fc, uint32_t); void FileTruncateAllOpenFiles(FileContainer *); diff --git a/framework/src/suricata/src/util-ioctl.c b/framework/src/suricata/src/util-ioctl.c index f08dea71..99a84a7e 100644 --- a/framework/src/suricata/src/util-ioctl.c +++ b/framework/src/suricata/src/util-ioctl.c @@ -90,8 +90,8 @@ int GetIfaceMTU(const char *pcap_dev) if (ioctl(fd, SIOCGIFMTU, (char *)&ifr) < 0) { SCLogWarning(SC_ERR_SYSCALL, - "Failure when trying to get MTU via ioctl: %d", - errno); + "Failure when trying to get MTU via ioctl for '%s': %s (%d)", + pcap_dev, strerror(errno), errno); close(fd); return -1; } @@ -157,6 +157,7 @@ int GetIfaceOffloading(const char *pcap_dev) int fd; struct ethtool_value ethv; int ret = 0; + char *lro = "unset", *gro = "unset"; fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd == -1) { @@ -169,16 +170,14 @@ int GetIfaceOffloading(const char *pcap_dev) ifr.ifr_data = (void *) ðv; if (ioctl(fd, SIOCETHTOOL, (char *)&ifr) < 0) { SCLogWarning(SC_ERR_SYSCALL, - "Failure when trying to get feature via ioctl: %s (%d)", - strerror(errno), errno); + "Failure when trying to get feature via ioctl for '%s': %s (%d)", + pcap_dev, strerror(errno), errno); close(fd); return -1; } else { if (ethv.data) { - SCLogInfo("Generic Receive Offload is set on %s", pcap_dev); + gro = "SET"; ret = 1; - } else { - SCLogInfo("Generic Receive Offload is unset on %s", pcap_dev); } } @@ -188,21 +187,19 @@ int GetIfaceOffloading(const char *pcap_dev) ifr.ifr_data = (void *) ðv; if (ioctl(fd, SIOCETHTOOL, (char *)&ifr) < 0) { SCLogWarning(SC_ERR_SYSCALL, - "Failure when trying to get feature via ioctl: %s (%d)", - strerror(errno), errno); + "Failure when trying to get feature via ioctl for '%s': %s (%d)", + pcap_dev, strerror(errno), errno); close(fd); return -1; } else { if (ethv.data & ETH_FLAG_LRO) { - SCLogInfo("Large Receive Offload is set on %s", pcap_dev); + lro = "SET"; ret = 1; - } else { - SCLogInfo("Large Receive Offload is unset on %s", pcap_dev); } } close(fd); - + SCLogInfo("NIC offloading on %s: GRO: %s, LRO: %s", pcap_dev, gro, lro); return ret; #else /* ioctl is not defined, let's pretend returning 0 is ok */ @@ -221,8 +218,8 @@ int GetIfaceRSSQueuesNum(const char *pcap_dev) fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd == -1) { SCLogWarning(SC_ERR_SYSCALL, - "Failure when opening socket for ioctl: %d", - errno); + "Failure when opening socket for ioctl: %s (%d)", + strerror(errno), errno); return -1; } @@ -232,8 +229,8 @@ int GetIfaceRSSQueuesNum(const char *pcap_dev) if (ioctl(fd, SIOCETHTOOL, (char *)&ifr) < 0) { if (errno != ENOTSUP) { SCLogWarning(SC_ERR_SYSCALL, - "Failure when trying to get number of RSS queue ioctl: %d", - errno); + "Failure when trying to get number of RSS queue ioctl for '%s': %s (%d)", + pcap_dev, strerror(errno), errno); } close(fd); return 0; diff --git a/framework/src/suricata/src/util-logopenfile.c b/framework/src/suricata/src/util-logopenfile.c index 84e5d2fe..04173d48 100644 --- a/framework/src/suricata/src/util-logopenfile.c +++ b/framework/src/suricata/src/util-logopenfile.c @@ -538,7 +538,7 @@ int LogFileFreeCtx(LogFileCtx *lf_ctx) } #ifdef HAVE_LIBHIREDIS -static int LogFileWriteRedis(LogFileCtx *file_ctx, char *string, size_t string_len) +static int LogFileWriteRedis(LogFileCtx *file_ctx, const char *string, size_t string_len) { if (file_ctx->redis == NULL) { SCConfLogReopenRedis(file_ctx); diff --git a/framework/src/suricata/suricata.yaml.in b/framework/src/suricata/suricata.yaml.in index af54b527..6614906f 100644 --- a/framework/src/suricata/suricata.yaml.in +++ b/framework/src/suricata/suricata.yaml.in @@ -181,7 +181,7 @@ outputs: # alert output for use with Barnyard2 - unified2-alert: - enabled: yes + enabled: no filename: unified2.alert # File size limit. Can be specified in kb, mb, gb. Just a number @@ -315,6 +315,7 @@ outputs: filename: stats.log totals: yes # stats for all threads merged together threads: no # per thread stats + #null-values: yes # print counters that have value 0 # a line based alerts log similar to fast.log into syslog - syslog: @@ -1171,7 +1172,7 @@ rule-files: - smtp-events.rules # available in suricata sources under rules dir - dns-events.rules # available in suricata sources under rules dir - tls-events.rules # available in suricata sources under rules dir - - modbus-events.rules # available in suricata sources under rules dir +# - modbus-events.rules # available in suricata sources under rules dir - app-layer-events.rules # available in suricata sources under rules dir classification-file: @e_sysconfdir@classification.config @@ -1350,7 +1351,7 @@ app-layer: # If the limit is reached, app-layer-event:modbus.flooded; will match. #request-flood: 500 - enabled: yes + enabled: no detection-ports: dp: 502 # According to MODBUS Messaging on TCP/IP Implementation Guide V1.0b, it @@ -1440,14 +1441,14 @@ app-layer: # Can be specified in kb, mb, gb. Just a number indicates # it's in bytes. - request-body-limit: 3072 - response-body-limit: 3072 + request-body-limit: 100kb + response-body-limit: 100kb # inspection limits request-body-minimal-inspect-size: 32kb request-body-inspect-window: 4kb - response-body-minimal-inspect-size: 32kb - response-body-inspect-window: 4kb + response-body-minimal-inspect-size: 40kb + response-body-inspect-window: 16kb # auto will use http-body-inline mode in IPS mode, yes or no set it statically http-body-inline: auto