From: Russ Combs (rucombs) Date: Thu, 20 Jul 2017 16:38:38 +0000 (-0400) Subject: Merge pull request #963 in SNORT/snort3 from u2 to master X-Git-Tag: 3.0.0-239~9 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=fe1a3bf28750d63bac05db1b38cd7367549d751d;p=thirdparty%2Fsnort3.git Merge pull request #963 in SNORT/snort3 from u2 to master Squashed commit of the following: commit d6046ce8e164daf3b8a54e2e429d71b227db13b5 Author: Russ Combs Date: Wed Jul 19 20:13:36 2017 -0400 u2: support mixed IP versions commit d0b5682dab42f3cbb67a6e71e794e4fe97533acb Author: Russ Combs Date: Wed Jul 19 08:19:32 2017 -0400 u2: convert thread local buffers to heap commit 126a9f8df065e784c1c5dc3905cb5dca1666167f Author: Russ Combs Date: Tue Jul 18 10:20:25 2017 -0400 u2: add event3 to u2spewfoo commit f27161d1460caf7ee13c3bee0b1107eb8c640cfc Author: Russ Combs Date: Mon Jul 17 08:17:24 2017 -0400 u2: deprecate ip4 and ip6 specific events and add a single event for both commit c7f6d52513f0f934b9a6f6eef4c6a9abd3b19c82 Author: Russ Combs Date: Sun Jul 9 22:47:38 2017 -0400 u2: remove aliases commit e2df358ebfbb746bace58ae83b437c3d64a1e90a Author: Russ Combs Date: Sun Jul 9 22:43:11 2017 -0400 u2: remove cruft --- diff --git a/src/log/unified2.h b/src/log/unified2.h index 003f537ba..77d15153c 100644 --- a/src/log/unified2.h +++ b/src/log/unified2.h @@ -21,37 +21,77 @@ #ifndef UNIFIED2_H #define UNIFIED2_H +// Unified logging (events and packets) shared header. Fields marked +// deprecated are no longer generated but can still be dumped with +// u2spewfoo. + #include #include "protocols/protocol_ids.h" -// SNORT DEFINES -// Long time ago... -#define UNIFIED2_EVENT 1 +// OBSOLETE (no longer generated): +// #define UNIFIED2_EVENT 1 +// #define UNIFIED2_IDS_EVENT 7 +// #define UNIFIED2_IDS_EVENT_IPV6 72 +// #define UNIFIED2_IDS_EVENT_MPLS 99 +// #define UNIFIED2_IDS_EVENT_IPV6_MPLS 100 // CURRENT #define UNIFIED2_PACKET 2 #define UNIFIED2_BUFFER 3 -#define UNIFIED2_IDS_EVENT 7 -#define UNIFIED2_IDS_EVENT_IPV6 72 -#define UNIFIED2_IDS_EVENT_MPLS 99 -#define UNIFIED2_IDS_EVENT_IPV6_MPLS 100 -#define UNIFIED2_IDS_EVENT_VLAN 104 -#define UNIFIED2_IDS_EVENT_IPV6_VLAN 105 +#define UNIFIED2_IDS_EVENT_VLAN 104 // deprecated +#define UNIFIED2_IDS_EVENT_IPV6_VLAN 105 // deprecated #define UNIFIED2_EXTRA_DATA 110 -#define UNIFIED2_IDS_EVENT_APPSTAT 113 +#define UNIFIED2_IDS_EVENT_APPSTAT 113 // FIXIT-L owned by appid (should have own # space) +#define UNIFIED2_EVENT3 114 #define MAX_EVENT_APPNAME_LEN 64 /* Data structure used for serialization of Unified2 Records */ -typedef struct _Serial_Unified2_Header +struct Serial_Unified2_Header { uint32_t type; uint32_t length; -} Serial_Unified2_Header; +}; + +// UNIFIED2_EVENT3 = type 114 +struct Unified2Event +{ + uint32_t snort_id; + + uint32_t event_id; + uint32_t event_second; + uint32_t event_microsecond; + + uint32_t policy_id_context; + uint32_t policy_id_inspect; + uint32_t policy_id_detect; + + uint32_t rule_gid; + uint32_t rule_sid; + uint32_t rule_rev; + uint32_t rule_class; + uint32_t rule_priority; + + uint32_t pkt_src_ip[4]; + uint32_t pkt_dst_ip[4]; + uint32_t pkt_mpls_label; + + uint16_t pkt_src_port_itype; + uint16_t pkt_dst_port_icode; + uint16_t pkt_vlan_id; + uint16_t unused; + + uint8_t pkt_ip_ver; // 0x4 or 0x6, high nybble is src, low is dst + uint8_t pkt_ip_proto; + + uint8_t snort_status; // allow=0, can't, would, force + uint8_t snort_action; // pass=0, drop, block, reset + + char app_name[MAX_EVENT_APPNAME_LEN]; +}; // UNIFIED2_IDS_EVENT_VLAN = type 104 -// comes from SFDC to EStreamer archive in serialized form with the extended header struct Unified2IDSEvent { uint32_t sensor_id; @@ -78,7 +118,7 @@ struct Unified2IDSEvent }; // UNIFIED2_IDS_EVENT_IPV6_VLAN = type 105 -typedef struct _Unified2IDSEventIPv6 +struct Unified2IDSEventIPv6 { uint32_t sensor_id; uint32_t event_id; @@ -101,55 +141,45 @@ typedef struct _Unified2IDSEventIPv6 uint16_t vlanId; uint16_t pad2; /*could be IPS Policy local id to support local sensor alerts*/ char app_name[MAX_EVENT_APPNAME_LEN]; -} Unified2IDSEventIPv6; +}; // UNIFIED2_PACKET = type 2 -typedef struct _Serial_Unified2Packet +struct Serial_Unified2Packet { uint32_t sensor_id; uint32_t event_id; uint32_t event_second; uint32_t packet_second; - uint32_t packet_microsecond; + uint32_t packet_microsecond; uint32_t linktype; uint32_t packet_length; uint8_t packet_data[4]; -} Serial_Unified2Packet; +}; -typedef struct _Unified2ExtraDataHdr +struct Unified2ExtraDataHdr { uint32_t event_type; uint32_t event_length; -}Unified2ExtraDataHdr; +}; // UNIFIED2_EXTRA_DATA - type 110 -typedef struct _SerialUnified2ExtraData +struct SerialUnified2ExtraData { uint32_t sensor_id; uint32_t event_id; uint32_t event_second; - uint32_t type; /* EventInfo */ - uint32_t data_type; /*EventDataType */ - uint32_t blob_length; /* Length of the data + sizeof(blob_length) + sizeof(data_type)*/ -} SerialUnified2ExtraData; + uint32_t type; // EventInfo + uint32_t data_type; // EventDataType + uint32_t blob_length; // Length of the data + sizeof(blob_length) + sizeof(data_type) +}; -typedef struct _Data_Blob +struct Data_Blob { uint32_t length; const uint8_t* data; -} Data_Blob; - -// UNIFIED2_EXTRA_DATA - type 110 -typedef struct _Serial_Unified2ExtraData -{ - uint32_t sensor_id; - uint32_t event_id; - uint32_t event_second; - uint32_t type; - Data_Blob data; -} Unified2ExtraData; +}; -typedef enum _EventInfoEnum +enum EventInfoEnum { EVENT_INFO_XFF_IPV4 = 1, EVENT_INFO_XFF_IPV6, @@ -161,16 +191,16 @@ typedef enum _EventInfoEnum EVENT_INFO_SMTP_EMAIL_HDRS, EVENT_INFO_HTTP_URI, EVENT_INFO_HTTP_HOSTNAME, - EVENT_INFO_IPV6_SRC, - EVENT_INFO_IPV6_DST, + EVENT_INFO_IPV6_SRC, // deprecated + EVENT_INFO_IPV6_DST, // deprecated EVENT_INFO_JSNORM_DATA -}EventInfoEnum; +}; -typedef enum _EventDataType +enum EventDataType { EVENT_DATA_TYPE_BLOB = 1, EVENT_DATA_TYPE_MAX -}EventDataType; +}; #define EVENT_TYPE_EXTRA_DATA 4 @@ -179,55 +209,5 @@ typedef enum _EventDataType sizeof(Unified2ExtraDataHdr) + sizeof(SerialUnified2ExtraData) \ + sizeof(struct in6_addr)) -#define Serial_Unified2IDSEvent Unified2IDSEvent -#define Serial_Unified2IDSEventIPv6 Unified2IDSEventIPv6 - -//---------------LEGACY, type '7' -// These structures are not used anymore in the product -typedef struct _Serial_Unified2IDSEvent_legacy -{ - uint32_t sensor_id; - uint32_t event_id; - uint32_t event_second; - uint32_t event_microsecond; - uint32_t signature_id; - uint32_t generator_id; - uint32_t signature_revision; - uint32_t classification_id; - uint32_t priority_id; - uint32_t ip_source; - uint32_t ip_destination; - uint16_t sport_itype; - uint16_t dport_icode; - IpProtocol ip_proto; - uint8_t impact_flag; // sets packet_action - uint8_t impact; - uint8_t blocked; -} Serial_Unified2IDSEvent_legacy; - -//----------LEGACY, type '72' -typedef struct _Serial_Unified2IDSEventIPv6_legacy -{ - uint32_t sensor_id; - uint32_t event_id; - uint32_t event_second; - uint32_t event_microsecond; - uint32_t signature_id; - uint32_t generator_id; - uint32_t signature_revision; - uint32_t classification_id; - uint32_t priority_id; - struct in6_addr ip_source; - struct in6_addr ip_destination; - uint16_t sport_itype; - uint16_t dport_icode; - IpProtocol ip_proto; - uint8_t impact_flag; - uint8_t impact; - uint8_t blocked; -} Serial_Unified2IDSEventIPv6_legacy; - -////////////////////-->LEGACY - #endif diff --git a/src/loggers/unified2.cc b/src/loggers/unified2.cc index 17d5719ea..a8cc4e63d 100644 --- a/src/loggers/unified2.cc +++ b/src/loggers/unified2.cc @@ -29,6 +29,8 @@ #include "config.h" #endif +#include + #include "detection/signature.h" #include "detection/detection_util.h" #include "events/event.h" @@ -80,10 +82,9 @@ static THREAD_LOCAL U2 u2; /* Used for buffering header and payload of unified records so only one * write is necessary. */ constexpr unsigned u2_buf_sz = - sizeof(Serial_Unified2_Header) + sizeof(Unified2IDSEventIPv6) + IP_MAXPACKET; + sizeof(Serial_Unified2_Header) + sizeof(Unified2Event) + IP_MAXPACKET; -// TBD - is performance any better if these buffers are off the heap? -static THREAD_LOCAL uint8_t write_pkt_buffer[u2_buf_sz]; +static THREAD_LOCAL uint8_t* write_pkt_buffer = nullptr; #define MAX_XDATA_WRITE_BUF_LEN \ (MAX_XFF_WRITE_BUF_LENGTH - \ @@ -95,58 +96,20 @@ static THREAD_LOCAL uint8_t write_pkt_buffer[u2_buf_sz]; * spoolers get an entire record */ /* use the size of the buffer we copy record data into */ -static THREAD_LOCAL char io_buffer[u2_buf_sz]; +static THREAD_LOCAL char* io_buffer = nullptr; /* -------------------- Local Functions -----------------------*/ -/* Unified2 Output functions */ static void Unified2InitFile(Unified2Config*); static inline void Unified2RotateFile(Unified2Config*); static void _Unified2LogPacketAlert(Packet*, const char*, Unified2Config*, const Event*); static void Unified2Write(uint8_t*, uint32_t, Unified2Config*); -static void _AlertIP4_v2(Packet*, const char*, Unified2Config*, const Event*); -static void _AlertIP6_v2(Packet*, const char*, Unified2Config*, const Event*); - -static void AlertExtraData(Flow*, void* data, LogFunction* log_funcs, uint32_t max_count, uint32_t - xtradata_mask, uint32_t event_id, uint32_t event_second); +static void alert_event(Packet*, const char*, Unified2Config*, const Event*); -#define U2_PACKET_FLAG 1 -/* Obsolete flag as UI wont check the impact_flag field anymore.*/ -#define U2_FLAG_BLOCKED 0x20 -/* New flags to set the pad field (corresponds to blocked column in UI) with packet action*/ -#define U2_BLOCKED_FLAG_ALLOW 0x00 -#define U2_BLOCKED_FLAG_BLOCK 0x01 -#define U2_BLOCKED_FLAG_WOULD 0x02 -#define U2_BLOCKED_FLAG_CANT 0x03 - -static int s_blocked_flag[] = -{ - U2_BLOCKED_FLAG_ALLOW, - U2_BLOCKED_FLAG_CANT, - U2_BLOCKED_FLAG_WOULD, - U2_BLOCKED_FLAG_BLOCK, -}; - -static int GetU2Flags(const Packet*, uint8_t* pimpact) -{ - Active::ActiveStatus dispos = Active::get_status(); +static void AlertExtraData(Flow*, void* data, LogFunction* log_funcs, + uint32_t max_count, uint32_t xtradata_mask, uint32_t event_id, uint32_t event_second); - if ( dispos > Active::AST_ALLOW ) - *pimpact = U2_FLAG_BLOCKED; - - return s_blocked_flag[dispos]; -} - -/* - * Function: Unified2InitFile() - * - * Purpose: Initialize the unified2 output file - * - * Arguments: config => pointer to the plugin's reference data struct - * - * Returns: void function - */ static void Unified2InitFile(Unified2Config* config) { char filepath[STD_BUF]; @@ -185,7 +148,7 @@ static void Unified2InitFile(Unified2Config* config) /* Set buffer to size of record buffer so the system doesn't flush * part of a record if it's greater than BUFSIZ */ - if (setvbuf(u2.stream, io_buffer, _IOFBF, sizeof(io_buffer)) != 0) + if (setvbuf(u2.stream, io_buffer, _IOFBF, u2_buf_sz) != 0) { ErrorMessage("%s(%d) Could not set I/O buffer: %s. " "Using system default.\n", @@ -213,185 +176,100 @@ static inline void Unified2RotateFile(Unified2Config* config) Unified2InitFile(config); } -static void _AlertIP4_v2(Packet* p, const char*, Unified2Config* config, const Event* event) +static inline unsigned get_version(const SfIp& addr) { - Serial_Unified2_Header hdr; - Unified2IDSEvent alertdata; - uint32_t write_len = sizeof(hdr) + sizeof(alertdata); + uint16_t family = addr.get_family(); + return (family == AF_INET) ? 0x4 : (family == AF_INET6 ? 0x6 : 0x0); +} + +static inline void copy_addr(const SfIp& src, const SfIp& dst, Unified2Event& e) +{ + COPY4(e.pkt_src_ip, src.get_ip6_ptr()); + COPY4(e.pkt_dst_ip, dst.get_ip6_ptr()); + e.pkt_ip_ver = (get_version(src) << 4) | get_version(dst); +} - memset(&alertdata, 0, sizeof(alertdata)); +static void alert_event(Packet* p, const char*, Unified2Config* config, const Event* event) +{ + Unified2Event u2_event; + memset(&u2_event, 0, sizeof(u2_event)); - alertdata.event_id = htonl(event->event_id); - alertdata.event_second = htonl(event->ref_time.tv_sec); - alertdata.event_microsecond = htonl(event->ref_time.tv_usec); - alertdata.generator_id = htonl(event->sig_info->gid); - alertdata.signature_id = htonl(event->sig_info->sid); - alertdata.signature_revision = htonl(event->sig_info->rev); - alertdata.classification_id = htonl(event->sig_info->class_id); - alertdata.priority_id = htonl(event->sig_info->priority); + u2_event.snort_id = 0; // FIXIT-H define / use - if (p) + u2_event.event_id = htonl(event->event_id); + u2_event.event_second = htonl(event->ref_time.tv_sec); + u2_event.event_microsecond = htonl(event->ref_time.tv_usec); + + u2_event.policy_id_context = 0; // FIXIT-H define / use context ids + u2_event.policy_id_detect = 0; // FIXIT-H define / use detect ids + + u2_event.rule_gid = htonl(event->sig_info->gid); + u2_event.rule_sid = htonl(event->sig_info->sid); + u2_event.rule_rev = htonl(event->sig_info->rev); + u2_event.rule_class = htonl(event->sig_info->class_id); + u2_event.rule_priority = htonl(event->sig_info->priority); + + if ( p ) { - alertdata.blocked = GetU2Flags(p, &alertdata.impact_flag); + u2_event.policy_id_inspect = htons(p->user_policy_id); // FIXIT-H inspect id + + if ( p->ptrs.ip_api.is_ip() ) + copy_addr(*p->ptrs.ip_api.get_src(), *p->ptrs.ip_api.get_dst(), u2_event); - if (p->has_ip()) - { - const ip::IP4Hdr* const iph = p->ptrs.ip_api.get_ip4h(); - alertdata.ip_source = iph->get_src(); - alertdata.ip_destination = iph->get_dst(); - } else if (p->flow) { if (p->is_from_client()) - { - alertdata.ip_source = *(p->flow->client_ip.get_ip4_ptr()); - alertdata.ip_destination = *(p->flow->server_ip.get_ip4_ptr()); - } + copy_addr(p->flow->client_ip, p->flow->server_ip, u2_event); else - { - alertdata.ip_source = *(p->flow->server_ip.get_ip4_ptr()); - alertdata.ip_destination = *(p->flow->client_ip.get_ip4_ptr()); - } + copy_addr(p->flow->server_ip, p->flow->client_ip, u2_event); } - alertdata.ip_proto = p->get_ip_proto_next(); - if ( p->type() == PktType::ICMP) { // If PktType == ICMP, icmph is set - alertdata.sport_itype = htons(p->ptrs.icmph->type); - alertdata.dport_icode = htons(p->ptrs.icmph->code); - } - - alertdata.sport_itype = htons(p->ptrs.sp); - alertdata.dport_icode = htons(p->ptrs.dp); - - if ((p->proto_bits & PROTO_BIT__MPLS) && (config->mpls_event_types)) - { - alertdata.mpls_label = htonl(p->ptrs.mplsHdr.label); + u2_event.pkt_src_port_itype = htons(p->ptrs.icmph->type); + u2_event.pkt_dst_port_icode = htons(p->ptrs.icmph->code); } - if (config->vlan_event_types) + else { - if (p->proto_bits & PROTO_BIT__VLAN) - { - alertdata.vlanId = htons(layer::get_vlan_layer(p)->vid()); - } - - alertdata.pad2 = htons(p->user_policy_id); + u2_event.pkt_src_port_itype = htons(p->ptrs.sp); + u2_event.pkt_dst_port_icode = htons(p->ptrs.dp); } - if ( p->flow ) - { - const char* app_name = appid_api.get_application_name(p->flow, p->is_from_client()); - if ( app_name ) - memcpy_s(alertdata.app_name, sizeof(alertdata.app_name), app_name, strlen(app_name) + 1); - } - } + if ( p->proto_bits & PROTO_BIT__MPLS ) + u2_event.pkt_mpls_label = htonl(p->ptrs.mplsHdr.label); - if ( config->limit && (u2.current + write_len) > config->limit ) - Unified2RotateFile(config); + if ( p->proto_bits & PROTO_BIT__VLAN ) + u2_event.pkt_vlan_id = htons(layer::get_vlan_layer(p)->vid()); - hdr.length = htonl(sizeof(alertdata)); - hdr.type = htonl(UNIFIED2_IDS_EVENT_VLAN); + u2_event.pkt_ip_proto = (uint8_t)p->get_ip_proto_next(); - memcpy_s(write_pkt_buffer, sizeof(write_pkt_buffer), &hdr, sizeof(hdr)); + const char* app_name = p->flow ? + appid_api.get_application_name(p->flow, p->is_from_client()) : nullptr; - size_t offset = sizeof(hdr); + if ( app_name ) + memcpy_s(u2_event.app_name, sizeof(u2_event.app_name), + app_name, strlen(app_name) + 1); + } - memcpy_s(write_pkt_buffer + offset, sizeof(write_pkt_buffer) - offset, &alertdata, sizeof(alertdata)); + u2_event.snort_status = Active::get_status(); + u2_event.snort_action = Active::get_action(); - Unified2Write(write_pkt_buffer, write_len, config); -} - -static void _AlertIP6_v2(Packet* p, const char*, Unified2Config* config, const Event* event) -{ Serial_Unified2_Header hdr; - Unified2IDSEventIPv6 alertdata; - uint32_t write_len = sizeof(Serial_Unified2_Header) + sizeof(Unified2IDSEventIPv6); - - memset(&alertdata, 0, sizeof(alertdata)); - - alertdata.event_id = htonl(event->event_id); - alertdata.event_second = htonl(event->ref_time.tv_sec); - alertdata.event_microsecond = htonl(event->ref_time.tv_usec); - alertdata.generator_id = htonl(event->sig_info->gid); - alertdata.signature_id = htonl(event->sig_info->sid); - alertdata.signature_revision = htonl(event->sig_info->rev); - alertdata.classification_id = htonl(event->sig_info->class_id); - alertdata.priority_id = htonl(event->sig_info->priority); - - if (p) - { - alertdata.blocked = GetU2Flags(p, &alertdata.impact_flag); - - if(p->ptrs.ip_api.is_ip()) - { - const SfIp* ip; - ip = p->ptrs.ip_api.get_src(); - alertdata.ip_source = *(struct in6_addr*)ip->get_ip6_ptr(); - ip = p->ptrs.ip_api.get_dst(); - alertdata.ip_destination = *(struct in6_addr*)ip->get_ip6_ptr(); - } - else if (p->flow) - { - if (p->is_from_client()) - { - alertdata.ip_source = *(struct in6_addr*)p->flow->client_ip.get_ip6_ptr(); - alertdata.ip_destination = *(struct in6_addr*)p->flow->server_ip.get_ip6_ptr(); - } - else - { - alertdata.ip_source = *(struct in6_addr*)p->flow->server_ip.get_ip6_ptr(); - alertdata.ip_destination = *(struct in6_addr*)p->flow->client_ip.get_ip6_ptr(); - } - } - - alertdata.ip_proto = p->get_ip_proto_next(); - - if ( p->type() == PktType::ICMP) - { - // If PktType == ICMP, icmph is set - alertdata.sport_itype = htons(p->ptrs.icmph->type); - alertdata.dport_icode = htons(p->ptrs.icmph->code); - } - - alertdata.sport_itype = htons(p->ptrs.sp); - alertdata.dport_icode = htons(p->ptrs.dp); - - if ((p->proto_bits & PROTO_BIT__MPLS) && (config->mpls_event_types)) - { - alertdata.mpls_label = htonl(p->ptrs.mplsHdr.label); - } - if (config->vlan_event_types) - { - if (p->proto_bits & PROTO_BIT__VLAN) - { - alertdata.vlanId = htons(layer::get_vlan_layer(p)->vid()); - } - - alertdata.pad2 = htons(p->user_policy_id); - } - - if ( p->flow ) - { - const char* app_name = appid_api.get_application_name(p->flow, p->is_from_client()); - if ( app_name ) - memcpy_s(alertdata.app_name, sizeof(alertdata.app_name), app_name, strlen(app_name) + 1); - } - } + uint32_t write_len = sizeof(hdr) + sizeof(u2_event); if ( config->limit && (u2.current + write_len) > config->limit ) Unified2RotateFile(config); - hdr.length = htonl(sizeof(Unified2IDSEventIPv6)); - hdr.type = htonl(UNIFIED2_IDS_EVENT_IPV6_VLAN); + hdr.length = htonl(sizeof(Unified2Event)); + hdr.type = htonl(UNIFIED2_EVENT3); - memcpy_s(write_pkt_buffer, sizeof(write_pkt_buffer), &hdr, sizeof(hdr)); + memcpy_s(write_pkt_buffer, u2_buf_sz, &hdr, sizeof(hdr)); size_t offset = sizeof(hdr); - memcpy_s(write_pkt_buffer + offset, sizeof(write_pkt_buffer) - offset, - &alertdata, sizeof(alertdata)); + memcpy_s(write_pkt_buffer + offset, u2_buf_sz - offset, + &u2_event, sizeof(u2_event)); Unified2Write(write_pkt_buffer, write_len, config); } @@ -526,23 +404,23 @@ static void _Unified2LogPacketAlert( hdr.length = htonl(sizeof(Serial_Unified2Packet) - 4 + pkt_length); hdr.type = ( p and p->is_rebuilt() ) ? htonl(UNIFIED2_BUFFER) : htonl(UNIFIED2_PACKET); - memcpy_s(write_pkt_buffer, sizeof(write_pkt_buffer), &hdr, sizeof(hdr)); + memcpy_s(write_pkt_buffer, u2_buf_sz, &hdr, sizeof(hdr)); size_t offset = sizeof(hdr); - memcpy_s(write_pkt_buffer + offset, sizeof(write_pkt_buffer) - offset, + memcpy_s(write_pkt_buffer + offset, u2_buf_sz - offset, &logheader, sizeof(logheader) - 4); offset += sizeof(logheader) - 4; if (pkt_length != 0) { - if (pkt_length > sizeof(write_pkt_buffer) - offset) + if (pkt_length > u2_buf_sz - offset) return; uint8_t *start = write_pkt_buffer + offset; - memcpy_s(start, sizeof(write_pkt_buffer) - offset, + memcpy_s(start, u2_buf_sz - offset, p->is_data() ? p->data : p->pkt, pkt_length); if ( p->obfuscator ) @@ -875,6 +753,9 @@ void U2Logger::open() } u2.base_proto = htonl(SFDAQ::get_base_protocol()); + write_pkt_buffer = new uint8_t[u2_buf_sz]; + io_buffer = new char[u2_buf_sz]; + Unified2InitFile(&config); Stream::reg_xtra_data_log(AlertExtraData, &config); @@ -884,29 +765,17 @@ void U2Logger::close() { if ( u2.stream ) fclose(u2.stream); + + delete[] write_pkt_buffer; + delete[] io_buffer; + + write_pkt_buffer = nullptr; + io_buffer = nullptr; } void U2Logger::alert(Packet* p, const char* msg, const Event& event) { - if (p->ptrs.ip_api.is_ip6()) - { - _AlertIP6_v2(p, msg, &config, &event); - - // FIXIT-M delete ip6 extra data; support ip6 normally - if (SnortConfig::get_log_ip6_extra() && p->ptrs.ip_api.is_ip6()) - { - const SfIp* ip = p->ptrs.ip_api.get_src(); - _WriteExtraData(&config, event.event_id, event.ref_time.tv_sec, - (const uint8_t*) ip->get_ip6_ptr(), sizeof(struct in6_addr), EVENT_INFO_IPV6_SRC); - ip = p->ptrs.ip_api.get_dst(); - _WriteExtraData(&config, event.event_id, event.ref_time.tv_sec, - (const uint8_t*) ip->get_ip6_ptr(), sizeof(struct in6_addr), EVENT_INFO_IPV6_DST); - } - } - else // ip4 or data - { - _AlertIP4_v2(p, msg, &config, &event); - } + alert_event(p, msg, &config, &event); if ( p->flow ) Stream::update_flow_alert( diff --git a/tools/u2spewfoo/u2spewfoo.cc b/tools/u2spewfoo/u2spewfoo.cc index aa9e03771..b9f645230 100644 --- a/tools/u2spewfoo/u2spewfoo.cc +++ b/tools/u2spewfoo/u2spewfoo.cc @@ -36,10 +36,6 @@ #include #include -#ifdef HAVE_UUID_UUID_H -#include -#endif - static long s_pos = 0, s_off = 0; #define TO_IP(x) x >> 24, (x >> 16)& 0xff, (x >> 8)& 0xff, x& 0xff @@ -211,16 +207,14 @@ static void extradata_dump(u2record* record) memcpy(&ip, record->data + sizeof(Unified2ExtraDataHdr) + sizeof(SerialUnified2ExtraData), sizeof(uint32_t)); ip = ntohl(ip); - printf("Original Client IP: %u.%u.%u.%u\n", - TO_IP(ip)); + printf("Original Client IP: %u.%u.%u.%u\n", TO_IP(ip)); break; case EVENT_INFO_XFF_IPV6: memcpy(&ipAddr, record->data + sizeof(Unified2ExtraDataHdr) + sizeof(SerialUnified2ExtraData), sizeof(struct in6_addr)); inet_ntop(AF_INET6, &ipAddr, ip6buf, INET6_ADDRSTRLEN); - printf("Original Client IP: %s\n", - ip6buf); + printf("Original Client IP: %s\n", ip6buf); break; case EVENT_INFO_GZIP_DATA: @@ -275,16 +269,14 @@ static void extradata_dump(u2record* record) memcpy(&ipAddr, record->data + sizeof(Unified2ExtraDataHdr) + sizeof(SerialUnified2ExtraData), sizeof(struct in6_addr)); inet_ntop(AF_INET6, &ipAddr, ip6buf, INET6_ADDRSTRLEN); - printf("IPv6 Source Address: %s\n", - ip6buf); + printf("IPv6 Source Address: %s\n", ip6buf); break; case EVENT_INFO_IPV6_DST: memcpy(&ipAddr, record->data + sizeof(Unified2ExtraDataHdr) + sizeof(SerialUnified2ExtraData), sizeof(struct in6_addr)); inet_ntop(AF_INET6, &ipAddr, ip6buf, INET6_ADDRSTRLEN); - printf("IPv6 Destination Address: %s\n", - ip6buf); + printf("IPv6 Destination Address: %s\n", ip6buf); break; default: @@ -292,88 +284,74 @@ static void extradata_dump(u2record* record) } } -static void event_dump(u2record* record) +static const char* lookup(const char* list[], unsigned size, unsigned idx) { - uint8_t* field; - int i; - Serial_Unified2IDSEvent_legacy event; + if ( idx < size ) + return list[idx]; - memcpy(&event, record->data, sizeof(Serial_Unified2IDSEvent_legacy)); + static char buf[8]; + snprintf(buf, sizeof(buf), "%u", idx); + return buf; +} - /* network to host ordering - In the event structure, only the last 40 bits are not 32 bit fields - The first 11 fields need to be converted */ - field = (uint8_t*)&event; - for (i=0; i<11; i++, field+=4) - { - *(uint32_t*)field = ntohl(*(uint32_t*)field); - } +static const char* get_status(uint8_t stat) +{ + const char* stats[] = { "allow", "can't", "would", "force" }; + return lookup(stats, sizeof(stats)/sizeof(stats[0]), stat); +} - /* last 3 fields, with the exception of the last most since it's just one byte */ - *(uint16_t*)field = ntohs(*(uint16_t*)field); /* sport_itype */ - field += 2; - *(uint16_t*)field = ntohs(*(uint16_t*)field); /* dport_icode */ - /* done changing the network ordering */ +static const char* get_action(uint8_t act) +{ + const char* acts[] = { "pass", "dtop", "block", "reset" }; + return lookup(acts, sizeof(acts)/sizeof(acts[0]), act); +} - printf("\n(Event)\n" - "\tsensor id: %u\tevent id: %u\tevent second: %u\tevent microsecond: %u\n" - "\tsig id: %u\tgen id: %u\trevision: %u\t classification: %u\n" - "\tpriority: %u\tip source: %u.%u.%u.%u\tip destination: %u.%u.%u.%u\n" - "\tsrc port: %hu\tdest port: %hu\tip_proto: %hhu\timpact_flag: %hhu\tblocked: %hhu\n", - event.sensor_id, event.event_id, - event.event_second, event.event_microsecond, - event.signature_id, event.generator_id, - event.signature_revision, event.classification_id, - event.priority_id, TO_IP(event.ip_source), - TO_IP(event.ip_destination), event.sport_itype, - event.dport_icode, to_utype(event.ip_proto), - event.impact_flag, event.blocked); +static void print_addr_port( + const char* which, unsigned af, const uint32_t* addr, uint16_t port) +{ + uint16_t fam = (af == 0x4) ? AF_INET : AF_INET6; + unsigned idx = (fam == AF_INET) ? 3 : 0; + + char ip_buf[INET6_ADDRSTRLEN+1]; + inet_ntop(fam, addr+idx, ip_buf, sizeof(ip_buf)); + + printf("\t%s IP: %s\tPort: %hu\n", which, ip_buf, htons(port)); } -static void event6_dump(u2record* record) +static void event3_dump(u2record* record) { - uint8_t* field; - int i; - Serial_Unified2IDSEventIPv6_legacy event; - char ip6buf[INET6_ADDRSTRLEN+1]; + Unified2Event event; + memcpy(&event, record->data, sizeof(event)); - memcpy(&event, record->data, sizeof(Serial_Unified2IDSEventIPv6_legacy)); + printf("%s", "\n(Event)\n"); - /* network to host ordering - In the event structure, only the last 40 bits are not 32 bit fields - The first fields need to be converted */ - field = (uint8_t*)&event; - for (i=0; i<9; i++, field+=4) - { - *(uint32_t*)field = ntohl(*(uint32_t*)field); - } + printf("\tSnort ID: %u\tEvent ID: %u\tSeconds: %u.%06u\n", + htonl(event.snort_id), htonl(event.event_id), + htonl(event.event_second), htonl(event.event_microsecond)); - field = field + 2*sizeof(struct in6_addr); + printf( + "\tPolicy ID:\tContext: %u\tInspect: %u\tDetect: %u\n", + htonl(event.policy_id_context), htonl(event.policy_id_inspect), + htonl(event.policy_id_detect)); - /* last 3 fields, with the exception of the last most since it's just one byte */ - *(uint16_t*)field = ntohs(*(uint16_t*)field); /* sport_itype */ - field += 2; - *(uint16_t*)field = ntohs(*(uint16_t*)field); /* dport_icode */ - /* done changing the network ordering */ + printf( + "\tRule %u:%u:%u\tClass: %u\tPriority: %u\n", + htonl(event.rule_gid), htonl(event.rule_sid), htonl(event.rule_rev), + htonl(event.rule_class), htonl(event.rule_priority)); - inet_ntop(AF_INET6, &event.ip_source, ip6buf, INET6_ADDRSTRLEN); + printf( + "\tMPLS Label: %u\tVLAN ID: %hu\tIP Version: 0x%hhX\tIP Proto: %hhu\n", + htonl(event.pkt_mpls_label), htons(event.pkt_vlan_id), + event.pkt_ip_ver, event.pkt_ip_proto); - printf("\n(IPv6 Event)\n" - "\tsensor id: %u\tevent id: %u\tevent second: %u\tevent microsecond: %u\n" - "\tsig id: %u\tgen id: %u\trevision: %u\t classification: %u\n" - "\tpriority: %u\tip source: %s\t", - event.sensor_id, event.event_id, - event.event_second, event.event_microsecond, - event.signature_id, event.generator_id, - event.signature_revision, event.classification_id, - event.priority_id, ip6buf); + print_addr_port("Src", event.pkt_ip_ver >> 4, event.pkt_src_ip, event.pkt_src_port_itype); + print_addr_port("Dst", event.pkt_ip_ver & 0xF, event.pkt_dst_ip, event.pkt_dst_port_icode); - inet_ntop(AF_INET6, &event.ip_destination, ip6buf, INET6_ADDRSTRLEN); - printf("ip destination: %s\n" - "\tsrc port: %hu\tdest port: %hu\tip_proto: %hhu\timpact_flag: %hhu\tblocked: %hhu\n", - ip6buf, event.sport_itype, - event.dport_icode, to_utype(event.ip_proto), - event.impact_flag, event.blocked); + printf("\tApp Name: %s\n", event.app_name[0] ? event.app_name : "none"); + + printf( + "\tStatus: %s\tAction: %s\n", + get_status(event.snort_status), get_action(event.snort_action)); } static void event2_dump(u2record* record) @@ -381,9 +359,9 @@ static void event2_dump(u2record* record) uint8_t* field; int i; - Serial_Unified2IDSEvent event; + Unified2IDSEvent event; - memcpy(&event, record->data, sizeof(Serial_Unified2IDSEvent)); + memcpy(&event, record->data, sizeof(event)); /* network to host ordering In the event structure, only the last 40 bits are not 32 bit fields @@ -430,9 +408,9 @@ static void event2_6_dump(u2record* record) uint8_t* field; int i; char ip6buf[INET6_ADDRSTRLEN+1]; - Serial_Unified2IDSEventIPv6 event; + Unified2IDSEventIPv6 event; - memcpy(&event, record->data, sizeof(Serial_Unified2IDSEventIPv6)); + memcpy(&event, record->data, sizeof(event)); /* network to host ordering In the event structure, only the last 40 bits are not 32 bit fields @@ -572,27 +550,41 @@ static int u2dump(char* file) if (!it) { - printf("u2dump: Failed to create new iterator with file: %s\n", file); + printf("ERROR: failed to create new iterator with file: %s\n", file); return -1; } while ( get_record(it, &record) ) { - if (record.type == UNIFIED2_IDS_EVENT) - event_dump(&record); - else if (record.type == UNIFIED2_IDS_EVENT_VLAN) - event2_dump(&record); - else if ((record.type == UNIFIED2_PACKET) || (record.type == UNIFIED2_BUFFER)) + if ( record.type == UNIFIED2_EVENT3 and record.length == sizeof(Unified2Event) ) + event3_dump(&record); + + else if ( (record.type == UNIFIED2_PACKET) or (record.type == UNIFIED2_BUFFER) ) packet_dump(&record); - else if (record.type == UNIFIED2_IDS_EVENT_IPV6) - event6_dump(&record); - else if (record.type == UNIFIED2_IDS_EVENT_IPV6_VLAN) - event2_6_dump(&record); + else if (record.type == UNIFIED2_EXTRA_DATA) extradata_dump(&record); + + // deprecated + else if ( record.type == UNIFIED2_IDS_EVENT_VLAN and + record.length == sizeof(Unified2IDSEvent) ) + { + event2_dump(&record); + } + else if ( record.type == UNIFIED2_IDS_EVENT_IPV6_VLAN and + record.length == sizeof(Unified2IDSEventIPv6) ) + { + event2_6_dump(&record); + } + else + { + printf("WARNING: skipping unknown record (%u) or bad length (%u)\n", + record.type, record.length); + } } free_iterator(it); + if (record.data) free(record.data);