return 1;
}
-static void AlertJsonTls(const Flow *f, json_t *js)
+static void AlertJsonTls(const Flow *f, JsonBuilder *js)
{
SSLState *ssl_state = (SSLState *)FlowGetAppState(f);
if (ssl_state) {
JsonTlsLogJSONBasic(tjs, ssl_state);
JsonTlsLogJSONExtended(tjs, ssl_state);
- json_object_set_new(js, "tls", tjs);
+ jb_set_jsont(js, "tls", tjs);
+ json_decref(tjs);
}
return;
}
-static void AlertJsonSsh(const Flow *f, json_t *js)
+static void AlertJsonSsh(const Flow *f, JsonBuilder *js)
{
void *ssh_state = FlowGetAppState(f);
if (ssh_state) {
if (unlikely(tjs == NULL))
return;
- json_object_set_new(js, "ssh", tjs);
+ jb_set_jsont(js, "ssh", tjs);
+ json_decref(tjs);
}
return;
}
-static void AlertJsonDnp3(const Flow *f, const uint64_t tx_id, json_t *js)
+static void AlertJsonDnp3(const Flow *f, const uint64_t tx_id, JsonBuilder *js)
{
DNP3State *dnp3_state = (DNP3State *)FlowGetAppState(f);
if (dnp3_state) {
json_object_set_new(dnp3js, "response", response);
}
}
- json_object_set_new(js, "dnp3", dnp3js);
+ jb_set_jsont(js, "dnp3", dnp3js);
+ json_decref(dnp3js);
}
}
}
return;
}
-static void AlertJsonDns(const Flow *f, const uint64_t tx_id, json_t *js)
+static void AlertJsonDns(const Flow *f, const uint64_t tx_id, JsonBuilder *js)
{
void *dns_state = (void *)FlowGetAppState(f);
if (dns_state) {
if (ajs != NULL) {
json_object_set_new(dnsjs, "answer", ajs);
}
- json_object_set_new(js, "dns", dnsjs);
+ jb_set_jsont(js, "dns", dnsjs);
+ json_decref(dnsjs);
}
}
return;
}
static void AlertJsonSourceTarget(const Packet *p, const PacketAlert *pa,
- json_t* ajs, JsonAddrInfo *addr)
+ JsonBuilder *js, JsonAddrInfo *addr)
{
- json_t *sjs = json_object();
- if (sjs == NULL) {
- return;
- }
-
- json_t *tjs = json_object();
- if (tjs == NULL) {
- json_decref(sjs);
- return;
+ jb_open_object(js, "source");
+ if (pa->s->flags & SIG_FLAG_DEST_IS_TARGET) {
+ jb_set_string(js, "ip", addr->src_ip);
+ switch (p->proto) {
+ case IPPROTO_ICMP:
+ case IPPROTO_ICMPV6:
+ break;
+ case IPPROTO_UDP:
+ case IPPROTO_TCP:
+ case IPPROTO_SCTP:
+ jb_set_uint(js, "port", addr->sp);
+ break;
+ }
+ } else if (pa->s->flags & SIG_FLAG_SRC_IS_TARGET) {
+ jb_set_string(js, "ip", addr->dst_ip);
+ switch (p->proto) {
+ case IPPROTO_ICMP:
+ case IPPROTO_ICMPV6:
+ break;
+ case IPPROTO_UDP:
+ case IPPROTO_TCP:
+ case IPPROTO_SCTP:
+ jb_set_uint(js, "port", addr->dp);
+ break;
+ }
}
+ jb_close(js);
+ jb_open_object(js, "target");
if (pa->s->flags & SIG_FLAG_DEST_IS_TARGET) {
- json_object_set(sjs, "ip", json_string(addr->src_ip));
- json_object_set(tjs, "ip", json_string(addr->dst_ip));
+ jb_set_string(js, "ip", addr->dst_ip);
switch (p->proto) {
case IPPROTO_ICMP:
case IPPROTO_ICMPV6:
case IPPROTO_UDP:
case IPPROTO_TCP:
case IPPROTO_SCTP:
- json_object_set(sjs, "port", json_integer(addr->sp));
- json_object_set(tjs, "port", json_integer(addr->dp));
+ jb_set_uint(js, "port", addr->dp);
break;
}
} else if (pa->s->flags & SIG_FLAG_SRC_IS_TARGET) {
- json_object_set(sjs, "ip", json_string(addr->dst_ip));
- json_object_set(tjs, "ip", json_string(addr->src_ip));
+ jb_set_string(js, "ip", addr->src_ip);
switch (p->proto) {
case IPPROTO_ICMP:
case IPPROTO_ICMPV6:
case IPPROTO_UDP:
case IPPROTO_TCP:
case IPPROTO_SCTP:
- json_object_set(sjs, "port", json_integer(addr->dp));
- json_object_set(tjs, "port", json_integer(addr->sp));
+ jb_set_uint(js, "port", addr->sp);
break;
}
}
- json_object_set_new(ajs, "source", sjs);
- json_object_set_new(ajs, "target", tjs);
+ jb_close(js);
}
-static void AlertJsonMetadata(AlertJsonOutputCtx *json_output_ctx, const PacketAlert *pa, json_t *ajs)
+static void AlertJsonMetadata(AlertJsonOutputCtx *json_output_ctx,
+ const PacketAlert *pa, JsonBuilder *ajs)
{
if (pa->s->metadata) {
const DetectMetadata* kv = pa->s->metadata;
kv = kv->next;
}
- if (json_object_size(mjs) == 0) {
- json_decref(mjs);
- } else {
- json_object_set_new(ajs, "metadata", mjs);
+ if (json_object_size(mjs) > 0) {
+ jb_set_jsont(ajs, "metadata", mjs);
}
+ json_decref(mjs);
}
}
-
-void AlertJsonHeader(void *ctx, const Packet *p, const PacketAlert *pa, json_t *js,
- uint16_t flags, JsonAddrInfo *addr)
+void AlertJsonHeader(void *ctx, const Packet *p, const PacketAlert *pa,
+ JsonBuilder *js, uint16_t flags, JsonAddrInfo *addr)
{
AlertJsonOutputCtx *json_output_ctx = (AlertJsonOutputCtx *)ctx;
const char *action = "allowed";
}
/* Add tx_id to root element for correlation with other events. */
- json_object_del(js, "tx_id");
- if (pa->flags & PACKET_ALERT_FLAG_TX)
- json_object_set_new(js, "tx_id", json_integer(pa->tx_id));
-
- json_t *ajs = json_object();
- if (ajs == NULL) {
- return;
+ /* json_object_del(js, "tx_id"); */
+ if (pa->flags & PACKET_ALERT_FLAG_TX) {
+ jb_set_uint(js, "tx_id", pa->tx_id);
}
- json_object_set_new(ajs, "action", json_string(action));
- json_object_set_new(ajs, "gid", json_integer(pa->s->gid));
- json_object_set_new(ajs, "signature_id", json_integer(pa->s->id));
- json_object_set_new(ajs, "rev", json_integer(pa->s->rev));
- json_object_set_new(ajs, "signature",
- SCJsonString((pa->s->msg) ? pa->s->msg : ""));
- json_object_set_new(ajs, "category",
- SCJsonString((pa->s->class_msg) ? pa->s->class_msg : ""));
- json_object_set_new(ajs, "severity", json_integer(pa->s->prio));
+ jb_open_object(js, "alert");
- if (p->tenant_id > 0)
- json_object_set_new(ajs, "tenant_id", json_integer(p->tenant_id));
+ jb_set_string(js, "action", action);
+ jb_set_uint(js, "gid", pa->s->gid);
+ jb_set_uint(js, "signature_id", pa->s->id);
+ jb_set_uint(js, "rev", pa->s->rev);
+ /* TODO: JsonBuilder should handle unprintable characters like
+ * SCJsonString. */
+ jb_set_string(js, "signature", pa->s->msg ? pa->s->msg: "");
+ jb_set_string(js, "category", pa->s->class_msg ? pa->s->class_msg: "");
+ jb_set_uint(js, "severity", pa->s->prio);
+
+ if (p->tenant_id > 0) {
+ jb_set_uint(js, "tenant_id", p->tenant_id);
+ }
if (addr && pa->s->flags & SIG_FLAG_HAS_TARGET) {
- AlertJsonSourceTarget(p, pa, ajs, addr);
+ AlertJsonSourceTarget(p, pa, js, addr);
}
if ((json_output_ctx != NULL) && (flags & LOG_JSON_RULE_METADATA)) {
- AlertJsonMetadata(json_output_ctx, pa, ajs);
+ AlertJsonMetadata(json_output_ctx, pa, js);
}
if (flags & LOG_JSON_RULE) {
- json_object_set_new(ajs, "rule", json_string(pa->s->sig_str));
+ jb_set_string(js, "rule", pa->s->sig_str);
}
- /* alert */
- json_object_set_new(js, "alert", ajs);
+ jb_close(js);
}
-static void AlertJsonTunnel(const Packet *p, json_t *js)
+static void AlertJsonTunnel(const Packet *p, JsonBuilder *js)
{
- json_t *tunnel = json_object();
- if (tunnel == NULL)
- return;
-
if (p->root == NULL) {
- json_decref(tunnel);
return;
}
+ jb_open_object(js, "tunnel");
+
/* get a lock to access root packet fields */
SCMutex *m = &p->root->tunnel_mutex;
+ JsonAddrInfo addr = json_addr_info_zero;
SCMutexLock(m);
- JsonFiveTuple((const Packet *)p->root, 0, tunnel);
+ JsonAddrInfoInit(p->root, 0, &addr);
SCMutexUnlock(m);
- json_object_set_new(tunnel, "depth", json_integer(p->recursion_level));
+ jb_set_string(js, "src_ip", addr.src_ip);
+ jb_set_uint(js, "src_port", addr.sp);
+ jb_set_string(js, "dest_ip", addr.dst_ip);
+ jb_set_uint(js, "dest_port", addr.dp);
+ jb_set_string(js, "proto", addr.proto);
- json_object_set_new(js, "tunnel", tunnel);
+ jb_set_uint(js, "depth", p->recursion_level);
+
+ jb_close(js);
}
-static void AlertAddPayload(AlertJsonOutputCtx *json_output_ctx, json_t *js, const Packet *p)
+static void AlertAddPayload(AlertJsonOutputCtx *json_output_ctx, JsonBuilder *js, const Packet *p)
{
if (json_output_ctx->flags & LOG_JSON_PAYLOAD_BASE64) {
unsigned long len = p->payload_len * 2 + 1;
uint8_t encoded[len];
if (Base64Encode(p->payload, p->payload_len, encoded, &len) == SC_BASE64_OK) {
- json_object_set_new(js, "payload", json_string((char *)encoded));
+ jb_set_string(js, "payload", (char *)encoded);
}
}
p->payload_len + 1,
p->payload, p->payload_len);
printable_buf[p->payload_len] = '\0';
- json_object_set_new(js, "payload_printable", json_string((char *)printable_buf));
+ jb_set_string(js, "payload_printable", (char *)printable_buf);
}
}
}
/* First initialize the address info (5-tuple). */
- JsonAddrInfo addr;
+ JsonAddrInfo addr = json_addr_info_zero;
JsonAddrInfoInit(p, LOG_DIR_PACKET, &addr);
/* Check for XFF, overwriting address info if needed. */
}
}
- json_t *js = CreateJSONHeader(p, LOG_DIR_PACKET, "alert", &addr);
- if (unlikely(js == NULL))
+ JsonBuilder *jb = CreateEveHeader(p, LOG_DIR_PACKET, "alert", &addr);
+ if (unlikely(jb == NULL))
return TM_ECODE_OK;
-
- JsonAddCommonOptions(&json_output_ctx->cfg, p, p->flow, js);
+ EveAddCommonOptions(&json_output_ctx->cfg, p, p->flow, jb);
MemBufferReset(aft->json_buffer);
/* alert */
- AlertJsonHeader(json_output_ctx, p, pa, js, json_output_ctx->flags,
+ AlertJsonHeader(json_output_ctx, p, pa, jb, json_output_ctx->flags,
&addr);
if (IS_TUNNEL_PKT(p)) {
- AlertJsonTunnel(p, js);
+ AlertJsonTunnel(p, jb);
}
if (json_output_ctx->flags & LOG_JSON_APP_LAYER && p->flow != NULL) {
if (json_output_ctx->flags & LOG_JSON_HTTP_BODY_BASE64) {
JsonHttpLogJSONBodyBase64(hjs, p->flow, pa->tx_id);
}
- json_object_set_new(js, "http", hjs);
+ jb_set_jsont(jb, "http", hjs);
+ json_decref(hjs);
}
break;
case ALPROTO_TLS:
- AlertJsonTls(p->flow, js);
+ AlertJsonTls(p->flow, jb);
break;
case ALPROTO_SSH:
- AlertJsonSsh(p->flow, js);
+ AlertJsonSsh(p->flow, jb);
break;
case ALPROTO_SMTP:
hjs = JsonSMTPAddMetadata(p->flow, pa->tx_id);
if (hjs) {
- json_object_set_new(js, "smtp", hjs);
+ jb_set_jsont(jb, "smtp", hjs);
+ json_decref(hjs);
}
hjs = JsonEmailAddMetadata(p->flow, pa->tx_id);
if (hjs) {
- json_object_set_new(js, "email", hjs);
+ jb_set_jsont(jb, "email", hjs);
+ json_decref(hjs);
}
break;
case ALPROTO_NFS:
hjs = JsonNFSAddMetadataRPC(p->flow, pa->tx_id);
- if (hjs)
- json_object_set_new(js, "rpc", hjs);
+ if (hjs) {
+ jb_set_jsont(jb, "rpc", hjs);
+ json_decref(hjs);
+ }
hjs = JsonNFSAddMetadata(p->flow, pa->tx_id);
- if (hjs)
- json_object_set_new(js, "nfs", hjs);
+ if (hjs) {
+ jb_set_jsont(jb, "nfs", hjs);
+ json_decref(hjs);
+ }
break;
case ALPROTO_SMB:
hjs = JsonSMBAddMetadata(p->flow, pa->tx_id);
- if (hjs)
- json_object_set_new(js, "smb", hjs);
+ if (hjs) {
+ jb_set_jsont(jb, "smb", hjs);
+ json_decref(hjs);
+ }
break;
case ALPROTO_SIP:
hjs = JsonSIPAddMetadata(p->flow, pa->tx_id);
- if (hjs)
- json_object_set_new(js, "sip", hjs);
+ if (hjs) {
+ jb_set_jsont(jb, "sip", hjs);
+ json_decref(hjs);
+ }
break;
case ALPROTO_RFB:
hjs = JsonRFBAddMetadata(p->flow, pa->tx_id);
if (hjs)
- json_object_set_new(js, "rfb", hjs);
+ jb_set_jsont(jb, "rfb", hjs);
break;
case ALPROTO_FTPDATA:
hjs = JsonFTPDataAddMetadata(p->flow);
- if (hjs)
- json_object_set_new(js, "ftp-data", hjs);
+ if (hjs) {
+ jb_set_jsont(jb, "ftp-data", hjs);
+ json_decref(hjs);
+ }
break;
case ALPROTO_DNP3:
- AlertJsonDnp3(p->flow, pa->tx_id, js);
+ AlertJsonDnp3(p->flow, pa->tx_id, jb);
break;
case ALPROTO_DNS:
- AlertJsonDns(p->flow, pa->tx_id, js);
+ AlertJsonDns(p->flow, pa->tx_id, jb);
break;
default:
break;
}
if (p->flow) {
- JsonAddAppProto(p->flow, js);
+ EveAddAppProto(p->flow, jb);
if (json_output_ctx->flags & LOG_JSON_FLOW) {
hjs = json_object();
if (hjs != NULL) {
JsonAddFlow(p->flow, hjs);
- json_object_set_new(js, "flow", hjs);
+ jb_set_jsont(jb, "flow", hjs);
+ json_decref(hjs);
}
}
}
unsigned long len = json_output_ctx->payload_buffer_size * 2;
uint8_t encoded[len];
Base64Encode(payload->buffer, payload->offset, encoded, &len);
- json_object_set_new(js, "payload", json_string((char *)encoded));
+ jb_set_string(jb, "payload", (char *)encoded);
}
if (json_output_ctx->flags & LOG_JSON_PAYLOAD) {
PrintStringsToBuffer(printable_buf, &offset,
sizeof(printable_buf),
payload->buffer, payload->offset);
- json_object_set_new(js, "payload_printable",
- json_string((char *)printable_buf));
+ jb_set_string(jb, "payload_printable", (char *)printable_buf);
}
} else if (p->payload_len) {
/* Fallback on packet payload */
- AlertAddPayload(json_output_ctx, js, p);
+ AlertAddPayload(json_output_ctx, jb, p);
}
} else {
/* This is a single packet and not a stream */
- AlertAddPayload(json_output_ctx, js, p);
+ AlertAddPayload(json_output_ctx, jb, p);
}
- json_object_set_new(js, "stream", json_integer(stream));
+ jb_set_uint(jb, "stream", stream);
}
/* base64-encoded full packet */
if (json_output_ctx->flags & LOG_JSON_PACKET) {
- JsonPacket(p, js, 0);
+ EvePacket(p, jb, 0);
}
if (have_xff_ip && xff_cfg->flags & XFF_EXTRADATA) {
- json_object_set_new(js, "xff", json_string(xff_buffer));
+ jb_set_string(jb, "xff", xff_buffer);
}
- OutputJSONBuffer(js, aft->file_ctx, &aft->json_buffer);
- json_decref(js);
+ OutputJsonBuilderBuffer(jb, aft->file_ctx, &aft->json_buffer);
+ jb_free(jb);
}
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", NULL);
+ JsonBuilder *packetjs = CreateEveHeader(p, LOG_DIR_PACKET, "packet", NULL);
if (unlikely(packetjs != NULL)) {
- JsonPacket(p, packetjs, 0);
- OutputJSONBuffer(packetjs, aft->file_ctx, &aft->json_buffer);
- json_decref(packetjs);
+ EvePacket(p, packetjs, 0);
+ OutputJsonBuilderBuffer(packetjs, aft->file_ctx, &aft->json_buffer);
+ jb_free(packetjs);
}
}
#define __OUTPUT_JSON_ALERT_H__
void JsonAlertLogRegister(void);
-void AlertJsonHeader(void *ctx, const Packet *p, const PacketAlert *pa, json_t *js,
+void AlertJsonHeader(void *ctx, const Packet *p, const PacketAlert *pa, JsonBuilder *js,
uint16_t flags, JsonAddrInfo *addr);
#endif /* __OUTPUT_JSON_ALERT_H__ */
JsonAddrInfo addr = json_addr_info_zero;
JsonAddrInfoInit(p, LOG_DIR_PACKET, &addr);
- json_t *js = CreateJSONHeader(p, LOG_DIR_PACKET, "drop", &addr);
+ JsonBuilder *js = CreateEveHeader(p, LOG_DIR_PACKET, "drop", &addr);
if (unlikely(js == NULL))
return TM_ECODE_OK;
- JsonAddCommonOptions(&drop_ctx->cfg, p, p->flow, js);
+ EveAddCommonOptions(&drop_ctx->cfg, p, p->flow, js);
- json_t *djs = json_object();
- if (unlikely(djs == NULL)) {
- json_decref(js);
- return TM_ECODE_OK;
- }
+ jb_open_object(js, "drop");
/* reset */
MemBufferReset(aft->buffer);
uint16_t proto = 0;
if (PKT_IS_IPV4(p)) {
- json_object_set_new(djs, "len", json_integer(IPV4_GET_IPLEN(p)));
- json_object_set_new(djs, "tos", json_integer(IPV4_GET_IPTOS(p)));
- json_object_set_new(djs, "ttl", json_integer(IPV4_GET_IPTTL(p)));
- json_object_set_new(djs, "ipid", json_integer(IPV4_GET_IPID(p)));
+ jb_set_uint(js, "len", IPV4_GET_IPLEN(p));
+ jb_set_uint(js, "tos", IPV4_GET_IPTOS(p));
+ jb_set_uint(js, "ttl", IPV4_GET_IPTTL(p));
+ jb_set_uint(js, "ipid", IPV4_GET_IPID(p));
proto = IPV4_GET_IPPROTO(p);
} else if (PKT_IS_IPV6(p)) {
- json_object_set_new(djs, "len", json_integer(IPV6_GET_PLEN(p)));
- json_object_set_new(djs, "tc", json_integer(IPV6_GET_CLASS(p)));
- json_object_set_new(djs, "hoplimit", json_integer(IPV6_GET_HLIM(p)));
- json_object_set_new(djs, "flowlbl", json_integer(IPV6_GET_FLOW(p)));
+ jb_set_uint(js, "len", IPV6_GET_PLEN(p));
+ jb_set_uint(js, "tc", IPV6_GET_CLASS(p));
+ jb_set_uint(js, "hoplimit", IPV6_GET_HLIM(p));
+ jb_set_uint(js, "flowlbl", IPV6_GET_FLOW(p));
proto = IPV6_GET_L4PROTO(p);
}
switch (proto) {
case IPPROTO_TCP:
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)));
+ jb_set_uint(js, "tcpseq", TCP_GET_SEQ(p));
+ jb_set_uint(js, "tcpack", TCP_GET_ACK(p));
+ jb_set_uint(js, "tcpwin", TCP_GET_WINDOW(p));
+ jb_set_bool(js, "syn", TCP_ISSET_FLAG_SYN(p) ? true : false);
+ jb_set_bool(js, "ack", TCP_ISSET_FLAG_ACK(p) ? true : false);
+ jb_set_bool(js, "psh", TCP_ISSET_FLAG_PUSH(p) ? true : false);
+ jb_set_bool(js, "rst", TCP_ISSET_FLAG_RST(p) ? true : false);
+ jb_set_bool(js, "urg", TCP_ISSET_FLAG_URG(p) ? true : false);
+ jb_set_bool(js, "fin", TCP_ISSET_FLAG_FIN(p) ? true : false);
+ jb_set_uint(js, "tcpres", TCP_GET_RAW_X2(p->tcph));
+ jb_set_uint(js, "tcpurgp", TCP_GET_URG_POINTER(p));
}
break;
case IPPROTO_UDP:
if (PKT_IS_UDP(p)) {
- json_object_set_new(djs, "udplen", json_integer(UDP_GET_LEN(p)));
+ jb_set_uint(js, "udplen", UDP_GET_LEN(p));
}
break;
case IPPROTO_ICMP:
if (PKT_IS_ICMPV4(p)) {
- json_object_set_new(djs, "icmp_id", json_integer(ICMPV4_GET_ID(p)));
- json_object_set_new(djs, "icmp_seq", json_integer(ICMPV4_GET_SEQ(p)));
+ jb_set_uint(js, "icmp_id", ICMPV4_GET_ID(p));
+ jb_set_uint(js, "icmp_seq", ICMPV4_GET_SEQ(p));
} else if(PKT_IS_ICMPV6(p)) {
- json_object_set_new(djs, "icmp_id", json_integer(ICMPV6_GET_ID(p)));
- json_object_set_new(djs, "icmp_seq", json_integer(ICMPV6_GET_SEQ(p)));
+ jb_set_uint(js, "icmp_id", ICMPV6_GET_ID(p));
+ jb_set_uint(js, "icmp_seq", ICMPV6_GET_SEQ(p));
}
break;
}
- json_object_set_new(js, "drop", djs);
+
+ /* Close drop. */
+ jb_close(js);
if (aft->drop_ctx->flags & LOG_DROP_ALERTS) {
int logged = 0;
}
}
- OutputJSONBuffer(js, aft->drop_ctx->file_ctx, &aft->buffer);
- json_object_del(js, "drop");
- json_object_clear(js);
- json_decref(js);
+ OutputJsonBuilderBuffer(js, aft->drop_ctx->file_ctx, &aft->buffer);
+ jb_free(js);
return TM_ECODE_OK;
}
}
+void EveAddAppProto(Flow *f, JsonBuilder *js)
+{
+ if (f->alproto) {
+ jb_set_string(js, "app_proto", AppProtoToString(f->alproto));
+ }
+ if (f->alproto_ts && f->alproto_ts != f->alproto) {
+ jb_set_string(js, "app_proto_ts", AppProtoToString(f->alproto_ts));
+ }
+ if (f->alproto_tc && f->alproto_tc != f->alproto) {
+ jb_set_string(js, "app_proto_tc", AppProtoToString(f->alproto_tc));
+ }
+ if (f->alproto_orig != f->alproto && f->alproto_orig != ALPROTO_UNKNOWN) {
+ jb_set_string(js, "app_proto_orig", AppProtoToString(f->alproto_orig));
+ }
+ if (f->alproto_expect != f->alproto && f->alproto_expect != ALPROTO_UNKNOWN) {
+ jb_set_string(js, "app_proto_expected",
+ AppProtoToString(f->alproto_expect));
+ }
+
+}
+
void JsonAddFlow(Flow *f, json_t *js)
{
FlowBypassInfo *fc = FlowGetStorageById(f, GetFlowBypassInfoID());
void JsonFlowLogRegister(void);
void JsonAddFlow(Flow *f, json_t *js);
void JsonAddAppProto(Flow *f, json_t *js);
+void EveAddAppProto(Flow *f, JsonBuilder *js);
#endif /* __OUTPUT_JSON_FLOW_H__ */
static void OutputJsonDeInitCtx(OutputCtx *);
static void CreateJSONCommunityFlowId(json_t *js, const Flow *f, const uint16_t seed);
+static void CreateEveCommunityFlowId(JsonBuilder *js, const Flow *f, const uint16_t seed);
static const char *TRAFFIC_ID_PREFIX = "traffic/id/";
static const char *TRAFFIC_LABEL_PREFIX = "traffic/label/";
return SCJsonString(tmpbuf);
}
+
static void JsonAddPacketvars(const Packet *p, json_t *js_vars)
{
if (p == NULL || p->pktvar == NULL) {
}
}
+static void EveAddPacketVars(const Packet *p, JsonBuilder *js_vars)
+{
+ if (p == NULL || p->pktvar == NULL) {
+ return;
+ }
+ PktVar *pv = p->pktvar;
+ bool open = false;
+ while (pv != NULL) {
+ if (pv->key || pv->id > 0) {
+ if (!open) {
+ jb_open_array(js_vars, "pktvars");
+ open = true;
+ }
+ jb_start_object(js_vars);
+
+ if (pv->key != NULL) {
+ uint32_t offset = 0;
+ uint8_t keybuf[pv->key_len + 1];
+ PrintStringsToBuffer(keybuf, &offset,
+ sizeof(keybuf),
+ pv->key, pv->key_len);
+ uint32_t len = pv->value_len;
+ uint8_t printable_buf[len + 1];
+ offset = 0;
+ PrintStringsToBuffer(printable_buf, &offset,
+ sizeof(printable_buf),
+ pv->value, pv->value_len);
+ jb_set_string(js_vars, (char *)keybuf, (char *)printable_buf);
+ } else {
+ const char *varname = VarNameStoreLookupById(pv->id, VAR_TYPE_PKT_VAR);
+ uint32_t len = pv->value_len;
+ uint8_t printable_buf[len + 1];
+ uint32_t offset = 0;
+ PrintStringsToBuffer(printable_buf, &offset,
+ sizeof(printable_buf),
+ pv->value, pv->value_len);
+ jb_set_string(js_vars, varname, (char *)printable_buf);
+ }
+ jb_close(js_vars);
+ }
+ pv = pv->next;
+ }
+ if (open) {
+ jb_close(js_vars);
+ }
+}
+
/**
* \brief Check if string s has prefix prefix.
*
}
}
+static void EveAddFlowVars(const Flow *f, JsonBuilder *js_root, JsonBuilder **js_traffic)
+{
+ if (f == NULL || f->flowvar == NULL) {
+ return;
+ }
+ JsonBuilder *js_flowvars = NULL;
+ JsonBuilder *js_traffic_id = NULL;
+ JsonBuilder *js_traffic_label = NULL;
+ JsonBuilder *js_flowints = NULL;
+ JsonBuilder *js_flowbits = NULL;
+ GenericVar *gv = f->flowvar;
+ while (gv != NULL) {
+ if (gv->type == DETECT_FLOWVAR || gv->type == DETECT_FLOWINT) {
+ FlowVar *fv = (FlowVar *)gv;
+ if (fv->datatype == FLOWVAR_TYPE_STR && fv->key == NULL) {
+ const char *varname = VarNameStoreLookupById(fv->idx,
+ VAR_TYPE_FLOW_VAR);
+ if (varname) {
+ if (js_flowvars == NULL) {
+ js_flowvars = jb_new_array();
+ if (js_flowvars == NULL)
+ break;
+ }
+
+ uint32_t len = fv->data.fv_str.value_len;
+ uint8_t printable_buf[len + 1];
+ uint32_t offset = 0;
+ PrintStringsToBuffer(printable_buf, &offset,
+ sizeof(printable_buf),
+ fv->data.fv_str.value, fv->data.fv_str.value_len);
+
+ jb_start_object(js_flowvars);
+ jb_set_string(js_flowvars, varname, (char *)printable_buf);
+ jb_close(js_flowvars);
+ }
+ } else if (fv->datatype == FLOWVAR_TYPE_STR && fv->key != NULL) {
+ if (js_flowvars == NULL) {
+ js_flowvars = jb_new_array();
+ if (js_flowvars == NULL)
+ break;
+ }
+
+ uint8_t keybuf[fv->keylen + 1];
+ uint32_t offset = 0;
+ PrintStringsToBuffer(keybuf, &offset,
+ sizeof(keybuf),
+ fv->key, fv->keylen);
+
+ uint32_t len = fv->data.fv_str.value_len;
+ uint8_t printable_buf[len + 1];
+ offset = 0;
+ PrintStringsToBuffer(printable_buf, &offset,
+ sizeof(printable_buf),
+ fv->data.fv_str.value, fv->data.fv_str.value_len);
+
+ jb_start_object(js_flowvars);
+ jb_set_string(js_flowvars, (const char *)keybuf, (char *)printable_buf);
+ jb_close(js_flowvars);
+ } else if (fv->datatype == FLOWVAR_TYPE_INT) {
+ const char *varname = VarNameStoreLookupById(fv->idx,
+ VAR_TYPE_FLOW_INT);
+ if (varname) {
+ if (js_flowints == NULL) {
+ js_flowints = jb_new_object();
+ if (js_flowints == NULL)
+ break;
+ }
+ jb_set_uint(js_flowints, varname, fv->data.fv_int.value);
+ }
+
+ }
+ } else if (gv->type == DETECT_FLOWBITS) {
+ FlowBit *fb = (FlowBit *)gv;
+ const char *varname = VarNameStoreLookupById(fb->idx,
+ VAR_TYPE_FLOW_BIT);
+ if (varname) {
+ if (SCStringHasPrefix(varname, TRAFFIC_ID_PREFIX)) {
+ if (js_traffic_id == NULL) {
+ js_traffic_id = jb_new_array();
+ if (unlikely(js_traffic_id == NULL)) {
+ break;
+ }
+ }
+ jb_append_string(js_traffic_id, &varname[traffic_id_prefix_len]);
+ } else if (SCStringHasPrefix(varname, TRAFFIC_LABEL_PREFIX)) {
+ if (js_traffic_label == NULL) {
+ js_traffic_label = jb_new_array();
+ if (unlikely(js_traffic_label == NULL)) {
+ break;
+ }
+ }
+ jb_append_string(js_traffic_label, &varname[traffic_label_prefix_len]);
+ } else {
+ if (js_flowbits == NULL) {
+ js_flowbits = jb_new_array();
+ if (unlikely(js_flowbits == NULL))
+ break;
+ }
+ jb_append_string(js_flowbits, varname);
+ }
+ }
+ }
+ gv = gv->next;
+ }
+ if (js_flowbits) {
+ jb_close(js_flowbits);
+ jb_set_object(js_root, "flowbits", js_flowbits);
+ jb_free(js_flowbits);
+ }
+ if (js_flowints) {
+ jb_close(js_flowints);
+ jb_set_object(js_root, "flowints", js_flowints);
+ jb_free(js_flowints);
+ }
+ if (js_flowvars) {
+ jb_close(js_flowvars);
+ jb_set_object(js_root, "flowvars", js_flowvars);
+ jb_free(js_flowvars);
+ }
+
+ if (js_traffic_id != NULL || js_traffic_label != NULL) {
+ *js_traffic = jb_new_object();
+ if (likely(*js_traffic != NULL)) {
+ if (js_traffic_id != NULL) {
+ jb_close(js_traffic_id);
+ jb_set_object(*js_traffic, "id", js_traffic_id);
+ jb_free(js_traffic_id);
+ }
+ if (js_traffic_label != NULL) {
+ jb_close(js_traffic_label);
+ jb_set_object(*js_traffic, "label", js_traffic_label);
+ jb_free(js_traffic_label);
+ }
+ jb_close(*js_traffic);
+ }
+ }
+}
+
/**
* \brief Add top-level metadata to the eve json object.
*/
}
}
+static void EveAddMetadata(const Packet *p, const Flow *f, JsonBuilder *js)
+{
+ if ((p && p->pktvar) || (f && f->flowvar)) {
+ JsonBuilder *js_vars = jb_new_object();
+ if (js_vars) {
+ if (f && f->flowvar) {
+ JsonBuilder *js_traffic = NULL;
+ EveAddFlowVars(f, js_vars, &js_traffic);
+ if (js_traffic != NULL) {
+ jb_set_object(js, "traffic", js_traffic);
+ jb_free(js_traffic);
+ }
+ }
+ if (p && p->pktvar) {
+ EveAddPacketVars(p, js_vars);
+ }
+ jb_close(js_vars);
+ jb_set_object(js, "metadata", js_vars);
+ jb_free(js_vars);
+ }
+ }
+}
+
void JsonAddCommonOptions(const OutputJsonCommonSettings *cfg,
const Packet *p, const Flow *f, json_t *js)
{
}
}
+void EveAddCommonOptions(const OutputJsonCommonSettings *cfg,
+ const Packet *p, const Flow *f, JsonBuilder *js)
+{
+ if (cfg->include_metadata) {
+ EveAddMetadata(p, f, js);
+ }
+ if (cfg->include_community_id && f != NULL) {
+ CreateEveCommunityFlowId(js, f, cfg->community_id_seed);
+ }
+}
+
/**
* \brief Jsonify a packet
*
json_object_set_new(packetinfo_js, "linktype", json_integer(p->datalink));
json_object_set_new(js, "packet_info", packetinfo_js);
}
+
+/**
+ * \brief Jsonify a packet
+ *
+ * \param p Packet
+ * \param js JSON object
+ * \param max_length If non-zero, restricts the number of packet data bytes handled.
+ */
+void EvePacket(const Packet *p, JsonBuilder *js, unsigned long max_length)
+{
+ unsigned long max_len = max_length == 0 ? GET_PKT_LEN(p) : max_length;
+ unsigned long len = 2 * max_len;
+ uint8_t encoded_packet[len];
+ if (Base64Encode((unsigned char*) GET_PKT_DATA(p), max_len, encoded_packet, &len) == SC_BASE64_OK) {
+ jb_set_string(js, "packet", (char *)encoded_packet);
+ }
+
+ if (!jb_open_object(js, "packet_info")) {
+ return;
+ }
+ if (!jb_set_uint(js, "linktype", p->datalink)) {
+ return;
+ }
+ jb_close(js);
+}
+
/** \brief jsonify tcp flags field
* Only add 'true' fields in an attempt to keep things reasonably compact.
*/
json_object_set_new(js, "proto", json_string(proto));
}
-static void CreateJSONCommunityFlowIdv4(json_t *js, const Flow *f,
- const uint16_t seed)
+#define COMMUNITY_ID_BUF_SIZE 64
+
+static bool CalculateCommunityFlowIdv4(const Flow *f,
+ const uint16_t seed, unsigned char *base64buf)
{
struct {
uint16_t seed;
uint8_t hash[20];
if (ComputeSHA1((const uint8_t *)&ipv4, sizeof(ipv4), hash, sizeof(hash)) == 1) {
- unsigned char base64buf[64] = "1:";
- unsigned long out_len = sizeof(base64buf) - 2;
+ strlcpy((char *)base64buf, "1:", COMMUNITY_ID_BUF_SIZE);
+ unsigned long out_len = COMMUNITY_ID_BUF_SIZE - 2;
if (Base64Encode(hash, sizeof(hash), base64buf+2, &out_len) == SC_BASE64_OK) {
- json_object_set_new(js, "community_id", json_string((const char *)base64buf));
+ return true;
}
}
+ return false;
}
static inline bool FlowHashRawAddressIPv6LtU32(const uint32_t *a, const uint32_t *b)
return false;
}
-static void CreateJSONCommunityFlowIdv6(json_t *js, const Flow *f,
- const uint16_t seed)
+static bool CalculateCommunityFlowIdv6(const Flow *f,
+ const uint16_t seed, unsigned char *base64buf)
{
struct {
uint16_t seed;
uint8_t hash[20];
if (ComputeSHA1((const uint8_t *)&ipv6, sizeof(ipv6), hash, sizeof(hash)) == 1) {
- unsigned char base64buf[64] = "1:";
- unsigned long out_len = sizeof(base64buf) - 2;
+ strlcpy((char *)base64buf, "1:", COMMUNITY_ID_BUF_SIZE);
+ unsigned long out_len = COMMUNITY_ID_BUF_SIZE - 2;
if (Base64Encode(hash, sizeof(hash), base64buf+2, &out_len) == SC_BASE64_OK) {
- json_object_set_new(js, "community_id", json_string((const char *)base64buf));
+ return true;
}
}
+ return false;
}
static void CreateJSONCommunityFlowId(json_t *js, const Flow *f, const uint16_t seed)
{
- if (f->flags & FLOW_IPV4)
- return CreateJSONCommunityFlowIdv4(js, f, seed);
- else if (f->flags & FLOW_IPV6)
- return CreateJSONCommunityFlowIdv6(js, f, seed);
+ unsigned char buf[COMMUNITY_ID_BUF_SIZE];
+ if (f->flags & FLOW_IPV4) {
+ if (CalculateCommunityFlowIdv4(f, seed, buf)) {
+ json_object_set_new(js, "community_id", json_string((const char *)buf));
+ }
+ } else if (f->flags & FLOW_IPV6) {
+ if (CalculateCommunityFlowIdv6(f, seed, buf)) {
+ json_object_set_new(js, "community_id", json_string((const char *)buf));
+ }
+ }
+}
+
+static void CreateEveCommunityFlowId(JsonBuilder *js, const Flow *f, const uint16_t seed)
+{
+ unsigned char buf[COMMUNITY_ID_BUF_SIZE];
+ if (f->flags & FLOW_IPV4) {
+ if (CalculateCommunityFlowIdv4(f, seed, buf)) {
+ jb_set_string(js, "community_id", (const char *)buf);
+ }
+ } else if (f->flags & FLOW_IPV6) {
+ if (CalculateCommunityFlowIdv6(f, seed, buf)) {
+ jb_set_string(js, "community_id", (const char *)buf);
+ }
+ }
}
void CreateJSONFlowId(json_t *js, const Flow *f)
}
}
+void CreateEveFlowId(JsonBuilder *js, const Flow *f)
+{
+ if (f == NULL) {
+ return;
+ }
+ int64_t flow_id = FlowGetId(f);
+ jb_set_uint(js, "flow_id", flow_id);
+ if (f->parent_id) {
+ jb_set_uint(js, "parent_id", f->parent_id);
+ }
+}
+
json_t *CreateJSONHeader(const Packet *p, enum OutputJsonLogDirection dir,
const char *event_type, JsonAddrInfo *addr)
{
return js;
}
+JsonBuilder *CreateEveHeader(const Packet *p, enum OutputJsonLogDirection dir,
+ const char *event_type, JsonAddrInfo *addr)
+{
+ char timebuf[64];
+ const Flow *f = (const Flow *)p->flow;
+
+ JsonBuilder *js = jb_new_object();
+ if (unlikely(js == NULL)) {
+ return NULL;
+ }
+
+ CreateIsoTimeString(&p->ts, timebuf, sizeof(timebuf));
+
+ jb_set_string(js, "timestamp", timebuf);
+
+ CreateEveFlowId(js, f);
+
+ /* sensor id */
+ if (sensor_id >= 0) {
+ jb_set_uint(js, "sensor_id", sensor_id);
+ }
+
+ /* input interface */
+ if (p->livedev) {
+ jb_set_string(js, "in_iface", p->livedev->dev);
+ }
+
+ /* pcap_cnt */
+ if (p->pcap_cnt != 0) {
+ jb_set_uint(js, "pcap_cnt", p->pcap_cnt);
+ }
+
+ if (event_type) {
+ jb_set_string(js, "event_type", event_type);
+ }
+
+ /* vlan */
+ if (p->vlan_idx > 0) {
+ jb_open_array(js, "vlan");
+ jb_append_uint(js, p->vlan_id[0]);
+ if (p->vlan_idx > 1) {
+ jb_append_uint(js, p->vlan_id[1]);
+ }
+ jb_close(js);
+ }
+
+ /* 5-tuple */
+ JsonAddrInfo addr_info = json_addr_info_zero;
+ if (addr == NULL) {
+ JsonAddrInfoInit(p, dir, &addr_info);
+ addr = &addr_info;
+ }
+ jb_set_string(js, "src_ip", addr->src_ip);
+ jb_set_uint(js, "src_port", addr->sp);
+ jb_set_string(js, "dest_ip", addr->dst_ip);
+ jb_set_uint(js, "dest_port", addr->dp);
+ jb_set_string(js, "proto", addr->proto);
+
+ /* icmp */
+ switch (p->proto) {
+ case IPPROTO_ICMP:
+ if (p->icmpv4h) {
+ jb_set_uint(js, "icmp_type", p->icmpv4h->type);
+ jb_set_uint(js, "icmp_code", p->icmpv4h->code);
+ }
+ break;
+ case IPPROTO_ICMPV6:
+ if (p->icmpv6h) {
+ jb_set_uint(js, "icmp_type", p->icmpv6h->type);
+ jb_set_uint(js, "icmp_code", p->icmpv6h->code);
+ }
+ break;
+ }
+
+ return js;
+}
+
json_t *CreateJSONHeaderWithTxId(const Packet *p, enum OutputJsonLogDirection dir,
const char *event_type, uint64_t tx_id)
{
return 0;
}
+int OutputJsonBuilderBuffer(JsonBuilder *js, LogFileCtx *file_ctx, MemBuffer **buffer)
+{
+ if (file_ctx->sensor_name) {
+ jb_set_string(js, "host", file_ctx->sensor_name);
+ }
+
+ if (file_ctx->is_pcap_offline) {
+ jb_set_string(js, "pcap_filename", PcapFileGetFilename());
+ }
+
+ jb_close(js);
+
+ if (file_ctx->prefix) {
+ MemBufferWriteRaw((*buffer), file_ctx->prefix, file_ctx->prefix_len);
+ }
+
+ size_t jslen = jb_len(js);
+ if (MEMBUFFER_OFFSET(*buffer) + jslen >= MEMBUFFER_SIZE(*buffer)) {
+ MemBufferExpand(buffer, jslen);
+ }
+
+ MemBufferWriteRaw((*buffer), jb_ptr(js), jslen);
+ LogFileWrite(file_ctx, *buffer);
+
+ return 0;
+}
+
/**
* \brief Create a new LogFileCtx for "fast" output style.
* \param conf The configuration node for this output.
#include "util-buffer.h"
#include "util-logopenfile.h"
#include "output.h"
+#include "rust.h"
#include "app-layer-htp-xff.h"
int OutputJSONMemBufferCallback(const char *str, size_t size, void *data);
void CreateJSONFlowId(json_t *js, const Flow *f);
+void CreateEveFlowId(JsonBuilder *js, const Flow *f);
void JsonTcpFlags(uint8_t flags, json_t *js);
void JsonPacket(const Packet *p, json_t *js, unsigned long max_length);
+void EvePacket(const Packet *p, JsonBuilder *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,
JsonAddrInfo *addr);
+JsonBuilder *CreateEveHeader(const Packet *p,
+ 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);
+int OutputJsonBuilderBuffer(JsonBuilder *js, LogFileCtx *file_ctx, MemBuffer **buffer);
OutputInitResult OutputJsonInitCtx(ConfNode *);
OutputInitResult OutputJsonLogInitSub(ConfNode *conf, OutputCtx *parent_ctx);
void JsonAddCommonOptions(const OutputJsonCommonSettings *cfg,
const Packet *p, const Flow *f, json_t *js);
+void EveAddCommonOptions(const OutputJsonCommonSettings *cfg,
+ const Packet *p, const Flow *f, JsonBuilder *js);
#endif /* __OUTPUT_JSON_H__ */