eve/fivetuple: use intermediate address struct (jsonbuilder prep)

Currently alert logging relies on the ability to change existing
values in the json_t structure to overwrite addresses with xff
data. This feature is also used for the "target" logging.

As we can't do this with JsonBuilder, create a new struct to
hold the 5 tuple, with the values swapped as needed, and
overwritten with XFF data if needed. This struct will now
be used to write out the 5 tuple, as well as cache the information
for log fields to be written out later on in the log path.
pull/5012/head
Jason Ish 5 years ago committed by Victor Julien
parent cc4f9d7f3d
commit 99f460aa5a

@ -59,7 +59,7 @@ SCMutex g_rule_dump_write_m = SCMUTEX_INITIALIZER;
void RulesDumpMatchArray(const DetectEngineThreadCtx *det_ctx,
const SigGroupHead *sgh, const Packet *p)
{
json_t *js = CreateJSONHeader(p, LOG_DIR_PACKET, "inspectedrules");
json_t *js = CreateJSONHeader(p, LOG_DIR_PACKET, "inspectedrules", NULL);
if (js == NULL)
return;
json_t *ir = json_object();

@ -411,7 +411,39 @@ static int AlertJson(ThreadVars *tv, JsonAlertLogThread *aft, const Packet *p)
continue;
}
json_t *js = CreateJSONHeader(p, LOG_DIR_PACKET, "alert");
/* First initialize the address info (5-tuple). */
JsonAddrInfo addr;
JsonAddrInfoInit(p, LOG_DIR_PACKET, &addr);
/* Check for XFF, overwriting address info if needed. */
HttpXFFCfg *xff_cfg = json_output_ctx->xff_cfg != NULL ?
json_output_ctx->xff_cfg : json_output_ctx->parent_xff_cfg;;
int have_xff_ip = 0;
char xff_buffer[XFF_MAXLEN];
if ((xff_cfg != NULL) && !(xff_cfg->flags & XFF_DISABLED) && p->flow != NULL) {
if (FlowGetAppProtocol(p->flow) == ALPROTO_HTTP) {
if (pa->flags & PACKET_ALERT_FLAG_TX) {
have_xff_ip = HttpXFFGetIPFromTx(p->flow, pa->tx_id, xff_cfg,
xff_buffer, XFF_MAXLEN);
} else {
have_xff_ip = HttpXFFGetIP(p->flow, xff_cfg, xff_buffer,
XFF_MAXLEN);
}
}
if (have_xff_ip && xff_cfg->flags & XFF_OVERWRITE) {
if (p->flowflags & FLOW_PKT_TOCLIENT) {
strlcpy(addr.dst_ip, xff_buffer, JSON_ADDR_LEN);
} else {
strlcpy(addr.src_ip, xff_buffer, JSON_ADDR_LEN);
}
/* Clear have_xff_ip so the xff field does not get
* logged below. */
have_xff_ip = false;
}
}
json_t *js = CreateJSONHeader(p, LOG_DIR_PACKET, "alert", &addr);
if (unlikely(js == NULL))
return TM_ECODE_OK;
@ -565,34 +597,8 @@ static int AlertJson(ThreadVars *tv, JsonAlertLogThread *aft, const Packet *p)
JsonPacket(p, js, 0);
}
HttpXFFCfg *xff_cfg = json_output_ctx->xff_cfg != NULL ?
json_output_ctx->xff_cfg : json_output_ctx->parent_xff_cfg;;
/* xff header */
if ((xff_cfg != NULL) && !(xff_cfg->flags & XFF_DISABLED) && p->flow != NULL) {
int have_xff_ip = 0;
char buffer[XFF_MAXLEN];
if (FlowGetAppProtocol(p->flow) == ALPROTO_HTTP) {
if (pa->flags & PACKET_ALERT_FLAG_TX) {
have_xff_ip = HttpXFFGetIPFromTx(p->flow, pa->tx_id, xff_cfg, buffer, XFF_MAXLEN);
} else {
have_xff_ip = HttpXFFGetIP(p->flow, xff_cfg, buffer, XFF_MAXLEN);
}
}
if (have_xff_ip) {
if (xff_cfg->flags & XFF_EXTRADATA) {
json_object_set_new(js, "xff", json_string(buffer));
}
else if (xff_cfg->flags & XFF_OVERWRITE) {
if (p->flowflags & FLOW_PKT_TOCLIENT) {
json_object_set(js, "dest_ip", json_string(buffer));
} else {
json_object_set(js, "src_ip", json_string(buffer));
}
}
}
if (have_xff_ip && xff_cfg->flags & XFF_EXTRADATA) {
json_object_set_new(js, "xff", json_string(xff_buffer));
}
OutputJSONBuffer(js, aft->file_ctx, &aft->json_buffer);
@ -602,7 +608,7 @@ static int AlertJson(ThreadVars *tv, JsonAlertLogThread *aft, const Packet *p)
if ((p->flags & PKT_HAS_TAG) && (json_output_ctx->flags &
LOG_JSON_TAGGED_PACKETS)) {
MemBufferReset(aft->json_buffer);
json_t *packetjs = CreateJSONHeader(p, LOG_DIR_PACKET, "packet");
json_t *packetjs = CreateJSONHeader(p, LOG_DIR_PACKET, "packet", NULL);
if (unlikely(packetjs != NULL)) {
JsonPacket(p, packetjs, 0);
OutputJSONBuffer(packetjs, aft->file_ctx, &aft->json_buffer);

@ -105,7 +105,7 @@ static int AnomalyDecodeEventJson(ThreadVars *tv, JsonAnomalyLogThread *aft,
MemBufferReset(aft->json_buffer);
json_t *js = CreateJSONHeader(p, LOG_DIR_PACKET, ANOMALY_EVENT_TYPE);
json_t *js = CreateJSONHeader(p, LOG_DIR_PACKET, ANOMALY_EVENT_TYPE, NULL);
if (unlikely(js == NULL)) {
return TM_ECODE_OK;
}
@ -167,7 +167,7 @@ static int AnomalyAppLayerDecoderEventJson(JsonAnomalyLogThread *aft,
js = CreateJSONHeaderWithTxId(p, LOG_DIR_PACKET,
ANOMALY_EVENT_TYPE, tx_id);
} else {
js = CreateJSONHeader(p, LOG_DIR_PACKET, ANOMALY_EVENT_TYPE);
js = CreateJSONHeader(p, LOG_DIR_PACKET, ANOMALY_EVENT_TYPE, NULL);
}
if (unlikely(js == NULL)) {
return TM_ECODE_OK;

@ -64,7 +64,7 @@ static int JsonDHCPLogger(ThreadVars *tv, void *thread_data,
LogDHCPLogThread *thread = thread_data;
LogDHCPFileCtx *ctx = thread->dhcplog_ctx;
json_t *js = CreateJSONHeader((Packet *)p, 0, "dhcp");
json_t *js = CreateJSONHeader((Packet *)p, 0, "dhcp", NULL);
if (unlikely(js == NULL)) {
return TM_ECODE_FAILED;
}

@ -309,7 +309,7 @@ static int JsonDNP3LoggerToServer(ThreadVars *tv, void *thread_data,
MemBufferReset(buffer);
if (tx->has_request && tx->request_done) {
json_t *js = CreateJSONHeader(p, LOG_DIR_FLOW, "dnp3");
json_t *js = CreateJSONHeader(p, LOG_DIR_FLOW, "dnp3", NULL);
if (unlikely(js == NULL)) {
return TM_ECODE_OK;
}
@ -338,7 +338,7 @@ static int JsonDNP3LoggerToClient(ThreadVars *tv, void *thread_data,
MemBufferReset(buffer);
if (tx->has_response && tx->response_done) {
json_t *js = CreateJSONHeader(p, LOG_DIR_FLOW, "dnp3");
json_t *js = CreateJSONHeader(p, LOG_DIR_FLOW, "dnp3", NULL);
if (unlikely(js == NULL)) {
return TM_ECODE_OK;
}

@ -307,7 +307,7 @@ static int JsonDnsLoggerToServer(ThreadVars *tv, void *thread_data,
}
for (uint16_t i = 0; i < 0xffff; i++) {
js = CreateJSONHeader(p, LOG_DIR_FLOW, "dns");
js = CreateJSONHeader(p, LOG_DIR_FLOW, "dns", NULL);
if (unlikely(js == NULL)) {
return TM_ECODE_OK;
}
@ -339,7 +339,7 @@ static int JsonDnsLoggerToClient(ThreadVars *tv, void *thread_data,
return TM_ECODE_OK;
}
json_t *js = CreateJSONHeader(p, LOG_DIR_FLOW, "dns");
json_t *js = CreateJSONHeader(p, LOG_DIR_FLOW, "dns", NULL);
if (unlikely(js == NULL))
return TM_ECODE_OK;

@ -87,7 +87,7 @@ static int DropLogJSON (JsonDropLogThread *aft, const Packet *p)
{
JsonDropOutputCtx *drop_ctx = aft->drop_ctx;
json_t *js = CreateJSONHeader(p, LOG_DIR_PACKET, "drop");
json_t *js = CreateJSONHeader(p, LOG_DIR_PACKET, "drop", NULL);
if (unlikely(js == NULL))
return TM_ECODE_OK;

@ -98,7 +98,7 @@ json_t *JsonBuildFileInfoRecord(const Packet *p, const File *ff,
break;
}
json_t *js = CreateJSONHeader(p, fdir, "fileinfo");
json_t *js = CreateJSONHeader(p, fdir, "fileinfo", NULL);
if (unlikely(js == NULL))
return NULL;

@ -66,7 +66,7 @@ static int JsonIKEv2Logger(ThreadVars *tv, void *thread_data,
LogIKEv2LogThread *thread = thread_data;
json_t *js, *ikev2js;
js = CreateJSONHeader((Packet *)p, LOG_DIR_PACKET, "ikev2");
js = CreateJSONHeader((Packet *)p, LOG_DIR_PACKET, "ikev2", NULL);
if (unlikely(js == NULL)) {
return TM_ECODE_FAILED;
}

@ -66,7 +66,7 @@ static int JsonKRB5Logger(ThreadVars *tv, void *thread_data,
LogKRB5LogThread *thread = thread_data;
json_t *js, *krb5js;
js = CreateJSONHeader(p, LOG_DIR_PACKET, "krb5");
js = CreateJSONHeader(p, LOG_DIR_PACKET, "krb5", NULL);
if (unlikely(js == NULL)) {
return TM_ECODE_FAILED;
}

@ -81,7 +81,7 @@ typedef struct JsonMetadataLogThread_ {
static int MetadataJson(ThreadVars *tv, JsonMetadataLogThread *aft, const Packet *p)
{
json_t *js = CreateJSONHeader(p, LOG_DIR_PACKET, "metadata");
json_t *js = CreateJSONHeader(p, LOG_DIR_PACKET, "metadata", NULL);
if (unlikely(js == NULL))
return TM_ECODE_OK;

@ -83,7 +83,7 @@ static int JsonNFSLogger(ThreadVars *tv, void *thread_data,
if (rs_nfs_tx_logging_is_filtered(state, nfstx))
return TM_ECODE_OK;
json_t *js = CreateJSONHeader(p, LOG_DIR_PACKET, "nfs");
json_t *js = CreateJSONHeader(p, LOG_DIR_PACKET, "nfs", NULL);
if (unlikely(js == NULL)) {
return TM_ECODE_FAILED;
}

@ -59,7 +59,7 @@ static int JsonRdpLogger(ThreadVars *tv, void *thread_data,
{
LogRdpLogThread *thread = thread_data;
json_t *js = CreateJSONHeader(p, LOG_DIR_PACKET, "rdp");
json_t *js = CreateJSONHeader(p, LOG_DIR_PACKET, "rdp", NULL);
if (unlikely(js == NULL)) {
return TM_ECODE_FAILED;
}

@ -75,7 +75,7 @@ static int JsonRFBLogger(ThreadVars *tv, void *thread_data,
{
LogRFBLogThread *thread = thread_data;
json_t *js = CreateJSONHeader(p, LOG_DIR_FLOW, "rfb");
json_t *js = CreateJSONHeader(p, LOG_DIR_FLOW, "rfb", NULL);
if (unlikely(js == NULL)) {
return TM_ECODE_FAILED;
}

@ -79,7 +79,7 @@ static int JsonSIPLogger(ThreadVars *tv, void *thread_data,
LogSIPLogThread *thread = thread_data;
json_t *js, *sipjs;
js = CreateJSONHeader(p, LOG_DIR_PACKET, "sip");
js = CreateJSONHeader(p, LOG_DIR_PACKET, "sip", NULL);
if (unlikely(js == NULL)) {
return TM_ECODE_FAILED;
}

@ -66,7 +66,7 @@ static int JsonSMBLogger(ThreadVars *tv, void *thread_data,
OutputJsonThreadCtx *thread = thread_data;
json_t *js, *smbjs;
js = CreateJSONHeader(p, LOG_DIR_FLOW, "smb");
js = CreateJSONHeader(p, LOG_DIR_FLOW, "smb", NULL);
if (unlikely(js == NULL)) {
return TM_ECODE_FAILED;
}

@ -66,7 +66,7 @@ static int JsonSNMPLogger(ThreadVars *tv, void *thread_data,
LogSNMPLogThread *thread = thread_data;
json_t *js, *snmpjs;
js = CreateJSONHeader(p, LOG_DIR_PACKET, "snmp");
js = CreateJSONHeader(p, LOG_DIR_PACKET, "snmp", NULL);
if (unlikely(js == NULL)) {
return TM_ECODE_FAILED;
}

@ -75,7 +75,7 @@ static int JsonSshLogger(ThreadVars *tv, void *thread_data, const Packet *p,
return 0;
}
json_t *js = CreateJSONHeader(p, LOG_DIR_FLOW, "ssh");
json_t *js = CreateJSONHeader(p, LOG_DIR_FLOW, "ssh", NULL);
if (unlikely(js == NULL))
return 0;

@ -71,7 +71,7 @@ static int JsonTemplateLogger(ThreadVars *tv, void *thread_data,
SCLogNotice("JsonTemplateLogger");
LogTemplateLogThread *thread = thread_data;
json_t *js = CreateJSONHeader(p, LOG_DIR_PACKET, "template-rust");
json_t *js = CreateJSONHeader(p, LOG_DIR_PACKET, "template-rust", NULL);
if (unlikely(js == NULL)) {
return TM_ECODE_FAILED;
}

@ -72,7 +72,7 @@ static int JsonTemplateLogger(ThreadVars *tv, void *thread_data,
SCLogNotice("Logging template transaction %"PRIu64".", templatetx->tx_id);
json_t *js = CreateJSONHeader(p, LOG_DIR_PACKET, "template");
json_t *js = CreateJSONHeader(p, LOG_DIR_PACKET, "template", NULL);
if (unlikely(js == NULL)) {
return TM_ECODE_FAILED;
}

@ -66,7 +66,7 @@ static int JsonTFTPLogger(ThreadVars *tv, void *thread_data,
{
LogTFTPLogThread *thread = thread_data;
json_t *js = CreateJSONHeader(p, LOG_DIR_PACKET, "tftp");
json_t *js = CreateJSONHeader(p, LOG_DIR_PACKET, "tftp", NULL);
if (unlikely(js == NULL)) {
return TM_ECODE_FAILED;
}

@ -411,7 +411,7 @@ static int JsonTlsLogger(ThreadVars *tv, void *thread_data, const Packet *p,
return 0;
}
json_t *js = CreateJSONHeader(p, LOG_DIR_FLOW, "tls");
json_t *js = CreateJSONHeader(p, LOG_DIR_FLOW, "tls", NULL);
if (unlikely(js == NULL)) {
return 0;
}

@ -445,6 +445,132 @@ void JsonTcpFlags(uint8_t flags, json_t *js)
json_object_set_new(js, "cwr", json_true());
}
void JsonAddrInfoInit(const Packet *p, enum OutputJsonLogDirection dir, JsonAddrInfo *addr)
{
char srcip[46] = {0}, dstip[46] = {0};
Port sp, dp;
char proto[16];
switch (dir) {
case LOG_DIR_PACKET:
if (PKT_IS_IPV4(p)) {
PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p),
srcip, sizeof(srcip));
PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p),
dstip, sizeof(dstip));
} else if (PKT_IS_IPV6(p)) {
PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p),
srcip, sizeof(srcip));
PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p),
dstip, sizeof(dstip));
} else {
/* Not an IP packet so don't do anything */
return;
}
sp = p->sp;
dp = p->dp;
break;
case LOG_DIR_FLOW:
case LOG_DIR_FLOW_TOSERVER:
if ((PKT_IS_TOSERVER(p))) {
if (PKT_IS_IPV4(p)) {
PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p),
srcip, sizeof(srcip));
PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p),
dstip, sizeof(dstip));
} else if (PKT_IS_IPV6(p)) {
PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p),
srcip, sizeof(srcip));
PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p),
dstip, sizeof(dstip));
}
sp = p->sp;
dp = p->dp;
} else {
if (PKT_IS_IPV4(p)) {
PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p),
srcip, sizeof(srcip));
PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p),
dstip, sizeof(dstip));
} else if (PKT_IS_IPV6(p)) {
PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p),
srcip, sizeof(srcip));
PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p),
dstip, sizeof(dstip));
}
sp = p->dp;
dp = p->sp;
}
break;
case LOG_DIR_FLOW_TOCLIENT:
if ((PKT_IS_TOCLIENT(p))) {
if (PKT_IS_IPV4(p)) {
PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p),
srcip, sizeof(srcip));
PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p),
dstip, sizeof(dstip));
} else if (PKT_IS_IPV6(p)) {
PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p),
srcip, sizeof(srcip));
PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p),
dstip, sizeof(dstip));
}
sp = p->sp;
dp = p->dp;
} else {
if (PKT_IS_IPV4(p)) {
PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p),
srcip, sizeof(srcip));
PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p),
dstip, sizeof(dstip));
} else if (PKT_IS_IPV6(p)) {
PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p),
srcip, sizeof(srcip));
PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p),
dstip, sizeof(dstip));
}
sp = p->dp;
dp = p->sp;
}
break;
default:
DEBUG_VALIDATE_BUG_ON(1);
return;
}
if (SCProtoNameValid(IP_GET_IPPROTO(p)) == TRUE) {
strlcpy(proto, known_proto[IP_GET_IPPROTO(p)], sizeof(proto));
} else {
snprintf(proto, sizeof(proto), "%03" PRIu32, IP_GET_IPPROTO(p));
}
strlcpy(addr->src_ip, srcip, JSON_ADDR_LEN);
switch(p->proto) {
case IPPROTO_ICMP:
break;
case IPPROTO_UDP:
case IPPROTO_TCP:
case IPPROTO_SCTP:
addr->sp = sp;
break;
}
strlcpy(addr->dst_ip, dstip, JSON_ADDR_LEN);
switch(p->proto) {
case IPPROTO_ICMP:
break;
case IPPROTO_UDP:
case IPPROTO_TCP:
case IPPROTO_SCTP:
addr->dp = dp;
break;
}
strlcpy(addr->proto, proto, JSON_PROTO_LEN);
}
/**
* \brief Add five tuple from packet to JSON object
*
@ -708,7 +834,7 @@ void CreateJSONFlowId(json_t *js, const Flow *f)
}
json_t *CreateJSONHeader(const Packet *p, enum OutputJsonLogDirection dir,
const char *event_type)
const char *event_type, JsonAddrInfo *addr)
{
char timebuf[64];
const Flow *f = (const Flow *)p->flow;
@ -755,7 +881,16 @@ json_t *CreateJSONHeader(const Packet *p, enum OutputJsonLogDirection dir,
}
/* 5-tuple */
JsonFiveTuple(p, dir, js);
JsonAddrInfo addr_info = {0};
if (addr == NULL) {
JsonAddrInfoInit(p, dir, &addr_info);
addr = &addr_info;
}
json_object_set_new(js, "src_ip", json_string(addr->src_ip));
json_object_set_new(js, "src_port", json_integer(addr->sp));
json_object_set_new(js, "dest_ip", json_string(addr->dst_ip));
json_object_set_new(js, "dest_port", json_integer(addr->dp));
json_object_set_new(js, "proto", json_string(addr->proto));
/* icmp */
switch (p->proto) {
@ -783,7 +918,7 @@ json_t *CreateJSONHeader(const Packet *p, enum OutputJsonLogDirection dir,
json_t *CreateJSONHeaderWithTxId(const Packet *p, enum OutputJsonLogDirection dir,
const char *event_type, uint64_t tx_id)
{
json_t *js = CreateJSONHeader(p, dir, event_type);
json_t *js = CreateJSONHeader(p, dir, event_type, NULL);
if (unlikely(js == NULL))
return NULL;

@ -40,6 +40,21 @@ enum OutputJsonLogDirection {
LOG_DIR_FLOW_TOSERVER,
};
#define JSON_ADDR_LEN 46
#define JSON_PROTO_LEN 16
/* A struct to contain address info for rendering to JSON. */
typedef struct JsonAddrInfo_ {
char src_ip[JSON_ADDR_LEN];
char dst_ip[JSON_ADDR_LEN];
Port sp;
Port dp;
char proto[JSON_PROTO_LEN];
} JsonAddrInfo;
void JsonAddrInfoInit(const Packet *p, enum OutputJsonLogDirection dir,
JsonAddrInfo *addr);
/* Suggested output buffer size */
#define JSON_OUTPUT_BUFFER_SIZE 65535
@ -56,7 +71,8 @@ void JsonTcpFlags(uint8_t flags, json_t *js);
void JsonPacket(const Packet *p, json_t *js, unsigned long max_length);
void JsonFiveTuple(const Packet *, enum OutputJsonLogDirection, json_t *);
json_t *CreateJSONHeader(const Packet *p,
enum OutputJsonLogDirection dir, const char *event_type);
enum OutputJsonLogDirection dir, const char *event_type,
JsonAddrInfo *addr);
json_t *CreateJSONHeaderWithTxId(const Packet *p,
enum OutputJsonLogDirection dir, const char *event_type, uint64_t tx_id);
int OutputJSONBuffer(json_t *js, LogFileCtx *file_ctx, MemBuffer **buffer);

Loading…
Cancel
Save