#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 <netinet/in.h>
#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;
};
// UNIFIED2_IDS_EVENT_IPV6_VLAN = type 105
-typedef struct _Unified2IDSEventIPv6
+struct Unified2IDSEventIPv6
{
uint32_t sensor_id;
uint32_t event_id;
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,
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
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
#include "config.h"
#endif
+#include <cassert>
+
#include "detection/signature.h"
#include "detection/detection_util.h"
#include "events/event.h"
/* 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 - \
* 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];
/* 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",
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);
}
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 )
}
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);
{
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(
#include <netinet/in.h>
#include <arpa/inet.h>
-#ifdef HAVE_UUID_UUID_H
-#include <uuid/uuid.h>
-#endif
-
static long s_pos = 0, s_off = 0;
#define TO_IP(x) x >> 24, (x >> 16)& 0xff, (x >> 8)& 0xff, x& 0xff
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:
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:
}
}
-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)
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
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
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);