static void JsonNetFlowLogJSONToClient(JsonNetFlowLogThread *aft, json_t *js, Flow *f) { json_t *hjs = json_object(); if (hjs == NULL) { return; } json_object_set_new(js, "app_proto", json_string(AppProtoToString(f->alproto_tc ? f->alproto_tc : f->alproto))); json_object_set_new(hjs, "pkts", json_integer(f->tosrcpktcnt)); json_object_set_new(hjs, "bytes", json_integer(f->tosrcbytecnt)); char timebuf1[64], timebuf2[64]; CreateIsoTimeString(&f->startts, timebuf1, sizeof(timebuf1)); CreateIsoTimeString(&f->lastts, timebuf2, sizeof(timebuf2)); json_object_set_new(hjs, "start", json_string(timebuf1)); json_object_set_new(hjs, "end", json_string(timebuf2)); int32_t age = f->lastts.tv_sec - f->startts.tv_sec; json_object_set_new(hjs, "age", json_integer(age)); /* To client is zero if we did not see any packet */ if (f->tosrcpktcnt) { json_object_set_new(hjs, "min_ttl", json_integer(f->min_ttl_toclient)); json_object_set_new(hjs, "max_ttl", json_integer(f->max_ttl_toclient)); } json_object_set_new(js, "netflow", hjs); /* TCP */ if (f->proto == IPPROTO_TCP) { json_t *tjs = json_object(); if (tjs == NULL) { return; } TcpSession *ssn = f->protoctx; char hexflags[3]; snprintf(hexflags, sizeof(hexflags), "%02x", ssn ? ssn->server.tcp_flags : 0); json_object_set_new(tjs, "tcp_flags", json_string(hexflags)); JsonTcpFlags(ssn ? ssn->server.tcp_flags : 0, tjs); json_object_set_new(js, "tcp", tjs); } }
static int JsonStatsLogger(ThreadVars *tv, void *thread_data, const StatsTable *st) { SCEnter(); JsonStatsLogThread *aft = (JsonStatsLogThread *)thread_data; struct timeval tval; gettimeofday(&tval, NULL); json_t *js = json_object(); if (unlikely(js == NULL)) return 0; char timebuf[64]; CreateIsoTimeString(&tval, timebuf, sizeof(timebuf)); json_object_set_new(js, "timestamp", json_string(timebuf)); json_object_set_new(js, "event_type", json_string("stats")); json_t *js_stats = StatsToJSON(st, aft->statslog_ctx->flags); if (js_stats == NULL) { json_decref(js); return 0; } json_object_set_new(js, "stats", js_stats); OutputJSONBuffer(js, aft->statslog_ctx->file_ctx, &aft->buffer); MemBufferReset(aft->buffer); json_object_clear(js_stats); json_object_del(js, "stats"); json_object_clear(js); json_decref(js); SCReturnInt(0); }
void JsonAddFlow(Flow *f, json_t *js, json_t *hjs) { json_object_set_new(js, "app_proto", json_string(AppProtoToString(f->alproto))); if (f->alproto_ts != f->alproto) { json_object_set_new(js, "app_proto_ts", json_string(AppProtoToString(f->alproto_ts))); } if (f->alproto_tc != f->alproto) { json_object_set_new(js, "app_proto_tc", json_string(AppProtoToString(f->alproto_tc))); } if (f->alproto_orig != f->alproto && f->alproto_orig != ALPROTO_UNKNOWN) { json_object_set_new(js, "app_proto_orig", json_string(AppProtoToString(f->alproto_orig))); } if (f->alproto_expect != f->alproto && f->alproto_expect != ALPROTO_UNKNOWN) { json_object_set_new(js, "app_proto_expected", json_string(AppProtoToString(f->alproto_expect))); } json_object_set_new(hjs, "pkts_toserver", json_integer(f->todstpktcnt)); json_object_set_new(hjs, "pkts_toclient", json_integer(f->tosrcpktcnt)); json_object_set_new(hjs, "bytes_toserver", json_integer(f->todstbytecnt)); json_object_set_new(hjs, "bytes_toclient", json_integer(f->tosrcbytecnt)); char timebuf1[64]; CreateIsoTimeString(&f->startts, timebuf1, sizeof(timebuf1)); json_object_set_new(hjs, "start", json_string(timebuf1)); }
static int AlertJsonDecoderEvent(ThreadVars *tv, JsonAlertLogThread *aft, const Packet *p) { int i; char timebuf[64]; json_t *js; if (p->alerts.cnt == 0) return TM_ECODE_OK; CreateIsoTimeString(&p->ts, timebuf, sizeof(timebuf)); for (i = 0; i < p->alerts.cnt; i++) { MemBufferReset(aft->json_buffer); const PacketAlert *pa = &p->alerts.alerts[i]; if (unlikely(pa->s == NULL)) { continue; } char *action = "allowed"; if (pa->action & (ACTION_REJECT|ACTION_REJECT_DST|ACTION_REJECT_BOTH)) { action = "blocked"; } else if ((pa->action & ACTION_DROP) && EngineModeIsIPS()) { action = "blocked"; } char buf[(32 * 3) + 1]; PrintRawLineHexBuf(buf, sizeof(buf), GET_PKT_DATA(p), GET_PKT_LEN(p) < 32 ? GET_PKT_LEN(p) : 32); js = json_object(); if (js == NULL) return TM_ECODE_OK; json_t *ajs = json_object(); if (ajs == NULL) { json_decref(js); return TM_ECODE_OK; } /* time & tx */ json_object_set_new(js, "timestamp", json_string(timebuf)); /* tuple */ //json_object_set_new(js, "srcip", json_string(srcip)); //json_object_set_new(js, "sp", json_integer(p->sp)); //json_object_set_new(js, "dstip", json_string(dstip)); //json_object_set_new(js, "dp", json_integer(p->dp)); //json_object_set_new(js, "proto", json_integer(proto)); 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", json_string((pa->s->msg) ? pa->s->msg : "")); json_object_set_new(ajs, "category", json_string((pa->s->class_msg) ? pa->s->class_msg : "")); json_object_set_new(ajs, "severity", json_integer(pa->s->prio)); if (p->tenant_id > 0) json_object_set_new(ajs, "tenant_id", json_integer(p->tenant_id)); /* alert */ json_object_set_new(js, "alert", ajs); OutputJSONBuffer(js, aft->file_ctx, &aft->json_buffer); json_object_clear(js); json_decref(js); } return TM_ECODE_OK; }
json_t *CreateJSONHeader(Packet *p, int direction_sensitive, char *event_type) { char timebuf[64]; char srcip[46], dstip[46]; Port sp, dp; json_t *js = json_object(); if (unlikely(js == NULL)) return NULL; CreateIsoTimeString(&p->ts, timebuf, sizeof(timebuf)); srcip[0] = '\0'; dstip[0] = '\0'; if (direction_sensitive) { 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; } } else { 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; } char proto[16]; 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)); } /* time & tx */ json_object_set_new(js, "timestamp", json_string(timebuf)); /* sensor id */ if (sensor_id >= 0) json_object_set_new(js, "sensor_id", json_integer(sensor_id)); /* pcap_cnt */ if (p->pcap_cnt != 0) { json_object_set_new(js, "pcap_cnt", json_integer(p->pcap_cnt)); } if (event_type) { json_object_set_new(js, "event_type", json_string(event_type)); } /* vlan */ if (p->vlan_idx > 0) { json_t *js_vlan; switch (p->vlan_idx) { case 1: json_object_set_new(js, "vlan", json_integer(VLAN_GET_ID1(p))); break; case 2: js_vlan = json_array(); if (unlikely(js != NULL)) { json_array_append_new(js_vlan, json_integer(VLAN_GET_ID1(p))); json_array_append_new(js_vlan, json_integer(VLAN_GET_ID2(p))); json_object_set_new(js, "vlan", js_vlan); } break; default: /* shouldn't get here */ break; } } /* tuple */ json_object_set_new(js, "src_ip", json_string(srcip)); switch(p->proto) { case IPPROTO_ICMP: break; case IPPROTO_UDP: case IPPROTO_TCP: case IPPROTO_SCTP: json_object_set_new(js, "src_port", json_integer(sp)); break; } json_object_set_new(js, "dest_ip", json_string(dstip)); switch(p->proto) { case IPPROTO_ICMP: break; case IPPROTO_UDP: case IPPROTO_TCP: case IPPROTO_SCTP: json_object_set_new(js, "dest_port", json_integer(dp)); break; } json_object_set_new(js, "proto", json_string(proto)); switch (p->proto) { case IPPROTO_ICMP: if (p->icmpv4h) { json_object_set_new(js, "icmp_type", json_integer(p->icmpv4h->type)); json_object_set_new(js, "icmp_code", json_integer(p->icmpv4h->code)); } break; case IPPROTO_ICMPV6: if (p->icmpv6h) { json_object_set_new(js, "icmp_type", json_integer(p->icmpv6h->type)); json_object_set_new(js, "icmp_code", json_integer(p->icmpv6h->code)); } break; } return js; }
static json_t *CreateJSONHeaderFromFlow(const Flow *f, const char *event_type) { char timebuf[64]; char srcip[46] = {0}, dstip[46] = {0}; Port sp, dp; json_t *js = json_object(); if (unlikely(js == NULL)) return NULL; struct timeval tv; memset(&tv, 0x00, sizeof(tv)); TimeGet(&tv); CreateIsoTimeString(&tv, timebuf, sizeof(timebuf)); if ((f->flags & FLOW_DIR_REVERSED) == 0) { if (FLOW_IS_IPV4(f)) { PrintInet(AF_INET, (const void *)&(f->src.addr_data32[0]), srcip, sizeof(srcip)); PrintInet(AF_INET, (const void *)&(f->dst.addr_data32[0]), dstip, sizeof(dstip)); } else if (FLOW_IS_IPV6(f)) { PrintInet(AF_INET6, (const void *)&(f->src.address), srcip, sizeof(srcip)); PrintInet(AF_INET6, (const void *)&(f->dst.address), dstip, sizeof(dstip)); } sp = f->sp; dp = f->dp; } else { if (FLOW_IS_IPV4(f)) { PrintInet(AF_INET, (const void *)&(f->dst.addr_data32[0]), srcip, sizeof(srcip)); PrintInet(AF_INET, (const void *)&(f->src.addr_data32[0]), dstip, sizeof(dstip)); } else if (FLOW_IS_IPV6(f)) { PrintInet(AF_INET6, (const void *)&(f->dst.address), srcip, sizeof(srcip)); PrintInet(AF_INET6, (const void *)&(f->src.address), dstip, sizeof(dstip)); } sp = f->dp; dp = f->sp; } char proto[16]; if (SCProtoNameValid(f->proto) == TRUE) { strlcpy(proto, known_proto[f->proto], sizeof(proto)); } else { snprintf(proto, sizeof(proto), "%03" PRIu32, f->proto); } /* time */ json_object_set_new(js, "timestamp", json_string(timebuf)); CreateJSONFlowId(js, (const Flow *)f); #if 0 // TODO /* sensor id */ if (sensor_id >= 0) json_object_set_new(js, "sensor_id", json_integer(sensor_id)); #endif /* input interface */ if (f->livedev) { json_object_set_new(js, "in_iface", json_string(f->livedev->dev)); } if (event_type) { json_object_set_new(js, "event_type", json_string(event_type)); } /* vlan */ if (f->vlan_idx > 0) { json_t *js_vlan = json_array(); json_array_append_new(js_vlan, json_integer(f->vlan_id[0])); if (f->vlan_idx > 1) { json_array_append_new(js_vlan, json_integer(f->vlan_id[1])); } json_object_set_new(js, "vlan", js_vlan); } /* tuple */ json_object_set_new(js, "src_ip", json_string(srcip)); switch(f->proto) { case IPPROTO_ICMP: break; case IPPROTO_UDP: case IPPROTO_TCP: case IPPROTO_SCTP: json_object_set_new(js, "src_port", json_integer(sp)); break; } json_object_set_new(js, "dest_ip", json_string(dstip)); switch(f->proto) { case IPPROTO_ICMP: break; case IPPROTO_UDP: case IPPROTO_TCP: case IPPROTO_SCTP: json_object_set_new(js, "dest_port", json_integer(dp)); break; } json_object_set_new(js, "proto", json_string(proto)); switch (f->proto) { case IPPROTO_ICMP: case IPPROTO_ICMPV6: json_object_set_new(js, "icmp_type", json_integer(f->icmp_s.type)); json_object_set_new(js, "icmp_code", json_integer(f->icmp_s.code)); if (f->tosrcpktcnt) { json_object_set_new(js, "response_icmp_type", json_integer(f->icmp_d.type)); json_object_set_new(js, "response_icmp_code", json_integer(f->icmp_d.code)); } break; } return js; }
/* JSON format logging */ static void JsonFlowLogJSON(JsonFlowLogThread *aft, json_t *js, Flow *f) { LogJsonFileCtx *flow_ctx = aft->flowlog_ctx; json_t *hjs = json_object(); if (hjs == NULL) { return; } JsonAddFlow(f, js, hjs); char timebuf2[64]; CreateIsoTimeString(&f->lastts, timebuf2, sizeof(timebuf2)); json_object_set_new(hjs, "end", json_string(timebuf2)); int32_t age = f->lastts.tv_sec - f->startts.tv_sec; json_object_set_new(hjs, "age", json_integer(age)); if (f->flow_end_flags & FLOW_END_FLAG_EMERGENCY) json_object_set_new(hjs, "emergency", json_true()); const char *state = NULL; if (f->flow_end_flags & FLOW_END_FLAG_STATE_NEW) state = "new"; else if (f->flow_end_flags & FLOW_END_FLAG_STATE_ESTABLISHED) state = "established"; else if (f->flow_end_flags & FLOW_END_FLAG_STATE_CLOSED) state = "closed"; else if (f->flow_end_flags & FLOW_END_FLAG_STATE_BYPASSED) { state = "bypassed"; int flow_state = SC_ATOMIC_GET(f->flow_state); switch (flow_state) { case FLOW_STATE_LOCAL_BYPASSED: json_object_set_new(hjs, "bypass", json_string("local")); break; case FLOW_STATE_CAPTURE_BYPASSED: json_object_set_new(hjs, "bypass", json_string("capture")); break; default: SCLogError(SC_ERR_INVALID_VALUE, "Invalid flow state: %d, contact developers", flow_state); } } json_object_set_new(hjs, "state", json_string(state)); const char *reason = NULL; if (f->flow_end_flags & FLOW_END_FLAG_TIMEOUT) reason = "timeout"; else if (f->flow_end_flags & FLOW_END_FLAG_FORCED) reason = "forced"; else if (f->flow_end_flags & FLOW_END_FLAG_SHUTDOWN) reason = "shutdown"; json_object_set_new(hjs, "reason", json_string(reason)); json_object_set_new(hjs, "alerted", json_boolean(FlowHasAlerts(f))); if (f->flags & FLOW_WRONG_THREAD) json_object_set_new(hjs, "wrong_thread", json_true()); json_object_set_new(js, "flow", hjs); JsonAddCommonOptions(&flow_ctx->cfg, NULL, f, js); /* TCP */ if (f->proto == IPPROTO_TCP) { json_t *tjs = json_object(); if (tjs == NULL) { return; } TcpSession *ssn = f->protoctx; char hexflags[3]; snprintf(hexflags, sizeof(hexflags), "%02x", ssn ? ssn->tcp_packet_flags : 0); json_object_set_new(tjs, "tcp_flags", json_string(hexflags)); snprintf(hexflags, sizeof(hexflags), "%02x", ssn ? ssn->client.tcp_flags : 0); json_object_set_new(tjs, "tcp_flags_ts", json_string(hexflags)); snprintf(hexflags, sizeof(hexflags), "%02x", ssn ? ssn->server.tcp_flags : 0); json_object_set_new(tjs, "tcp_flags_tc", json_string(hexflags)); JsonTcpFlags(ssn ? ssn->tcp_packet_flags : 0, tjs); if (ssn) { const char *tcp_state = NULL; switch (ssn->state) { case TCP_NONE: tcp_state = "none"; break; case TCP_LISTEN: tcp_state = "listen"; break; case TCP_SYN_SENT: tcp_state = "syn_sent"; break; case TCP_SYN_RECV: tcp_state = "syn_recv"; break; case TCP_ESTABLISHED: tcp_state = "established"; break; case TCP_FIN_WAIT1: tcp_state = "fin_wait1"; break; case TCP_FIN_WAIT2: tcp_state = "fin_wait2"; break; case TCP_TIME_WAIT: tcp_state = "time_wait"; break; case TCP_LAST_ACK: tcp_state = "last_ack"; break; case TCP_CLOSE_WAIT: tcp_state = "close_wait"; break; case TCP_CLOSING: tcp_state = "closing"; break; case TCP_CLOSED: tcp_state = "closed"; break; } json_object_set_new(tjs, "state", json_string(tcp_state)); if (ssn->client.flags & STREAMTCP_STREAM_FLAG_GAP) json_object_set_new(tjs, "gap_ts", json_true()); if (ssn->server.flags & STREAMTCP_STREAM_FLAG_GAP) json_object_set_new(tjs, "gap_tc", json_true()); } json_object_set_new(js, "tcp", tjs); } }
static json_t *CreateJSONHeaderFromFlow(Flow *f, char *event_type, int dir) { char timebuf[64]; char srcip[46], dstip[46]; Port sp, dp; json_t *js = json_object(); if (unlikely(js == NULL)) return NULL; struct timeval tv; memset(&tv, 0x00, sizeof(tv)); TimeGet(&tv); CreateIsoTimeString(&tv, timebuf, sizeof(timebuf)); srcip[0] = '\0'; dstip[0] = '\0'; if (FLOW_IS_IPV4(f)) { if (dir == 0) { PrintInet(AF_INET, (const void *)&(f->src.addr_data32[0]), srcip, sizeof(srcip)); PrintInet(AF_INET, (const void *)&(f->dst.addr_data32[0]), dstip, sizeof(dstip)); } else { PrintInet(AF_INET, (const void *)&(f->dst.addr_data32[0]), srcip, sizeof(srcip)); PrintInet(AF_INET, (const void *)&(f->src.addr_data32[0]), dstip, sizeof(dstip)); } } else if (FLOW_IS_IPV6(f)) { if (dir == 0) { PrintInet(AF_INET6, (const void *)&(f->src.address), srcip, sizeof(srcip)); PrintInet(AF_INET6, (const void *)&(f->dst.address), dstip, sizeof(dstip)); } else { PrintInet(AF_INET6, (const void *)&(f->dst.address), srcip, sizeof(srcip)); PrintInet(AF_INET6, (const void *)&(f->src.address), dstip, sizeof(dstip)); } } if (dir == 0) { sp = f->sp; dp = f->dp; } else { sp = f->dp; dp = f->sp; } char proto[16]; if (SCProtoNameValid(f->proto) == TRUE) { strlcpy(proto, known_proto[f->proto], sizeof(proto)); } else { snprintf(proto, sizeof(proto), "%03" PRIu32, f->proto); } /* time */ json_object_set_new(js, "timestamp", json_string(timebuf)); CreateJSONFlowId(js, (const Flow *)f); #if 0 // TODO /* sensor id */ if (sensor_id >= 0) json_object_set_new(js, "sensor_id", json_integer(sensor_id)); #endif if (event_type) { json_object_set_new(js, "event_type", json_string(event_type)); } #if 0 /* vlan */ if (f->vlan_id[0] > 0) { json_t *js_vlan; switch (f->vlan_idx) { case 1: json_object_set_new(js, "vlan", json_integer(f->vlan_id[0])); break; case 2: js_vlan = json_array(); if (unlikely(js != NULL)) { json_array_append_new(js_vlan, json_integer(VLAN_GET_ID1(p))); json_array_append_new(js_vlan, json_integer(VLAN_GET_ID2(p))); json_object_set_new(js, "vlan", js_vlan); } break; default: /* shouldn't get here */ break; } } #endif /* tuple */ json_object_set_new(js, "src_ip", json_string(srcip)); switch(f->proto) { case IPPROTO_ICMP: break; case IPPROTO_UDP: case IPPROTO_TCP: case IPPROTO_SCTP: json_object_set_new(js, "src_port", json_integer(sp)); break; } json_object_set_new(js, "dest_ip", json_string(dstip)); switch(f->proto) { case IPPROTO_ICMP: break; case IPPROTO_UDP: case IPPROTO_TCP: case IPPROTO_SCTP: json_object_set_new(js, "dest_port", json_integer(dp)); break; } json_object_set_new(js, "proto", json_string(proto)); switch (f->proto) { case IPPROTO_ICMP: case IPPROTO_ICMPV6: json_object_set_new(js, "icmp_type", json_integer(f->type)); json_object_set_new(js, "icmp_code", json_integer(f->code)); break; } return js; }
/* JSON format logging */ static void JsonFlowLogJSON(JsonFlowLogThread *aft, json_t *js, Flow *f) { #if 0 LogJsonFileCtx *flow_ctx = aft->flowlog_ctx; #endif json_t *hjs = json_object(); if (hjs == NULL) { return; } json_object_set_new(js, "app_proto", json_string(AppProtoToString(f->alproto))); json_object_set_new(hjs, "pkts_toserver", json_integer(f->todstpktcnt)); json_object_set_new(hjs, "pkts_toclient", json_integer(f->tosrcpktcnt)); json_object_set_new(hjs, "bytes_toserver", json_integer(f->todstbytecnt)); json_object_set_new(hjs, "bytes_toclient", json_integer(f->tosrcbytecnt)); char timebuf1[64], timebuf2[64]; CreateIsoTimeString(&f->startts, timebuf1, sizeof(timebuf1)); CreateIsoTimeString(&f->lastts, timebuf2, sizeof(timebuf2)); json_object_set_new(hjs, "start", json_string(timebuf1)); json_object_set_new(hjs, "end", json_string(timebuf2)); int32_t age = f->lastts.tv_sec - f->startts.tv_sec; json_object_set_new(hjs, "age", json_integer(age)); if (f->flow_end_flags & FLOW_END_FLAG_EMERGENCY) json_object_set_new(hjs, "emergency", json_true()); const char *state = NULL; if (f->flow_end_flags & FLOW_END_FLAG_STATE_NEW) state = "new"; else if (f->flow_end_flags & FLOW_END_FLAG_STATE_ESTABLISHED) state = "established"; else if (f->flow_end_flags & FLOW_END_FLAG_STATE_CLOSED) state = "closed"; json_object_set_new(hjs, "state", json_string(state)); const char *reason = NULL; if (f->flow_end_flags & FLOW_END_FLAG_TIMEOUT) reason = "timeout"; else if (f->flow_end_flags & FLOW_END_FLAG_FORCED) reason = "forced"; else if (f->flow_end_flags & FLOW_END_FLAG_SHUTDOWN) reason = "shutdown"; json_object_set_new(hjs, "reason", json_string(reason)); json_object_set_new(js, "flow", hjs); /* TCP */ if (f->proto == IPPROTO_TCP) { json_t *tjs = json_object(); if (tjs == NULL) { return; } TcpSession *ssn = f->protoctx; char hexflags[3] = ""; snprintf(hexflags, sizeof(hexflags), "%02x", ssn ? ssn->tcp_packet_flags : 0); json_object_set_new(tjs, "tcp_flags", json_string(hexflags)); snprintf(hexflags, sizeof(hexflags), "%02x", ssn ? ssn->client.tcp_flags : 0); json_object_set_new(tjs, "tcp_flags_ts", json_string(hexflags)); snprintf(hexflags, sizeof(hexflags), "%02x", ssn ? ssn->server.tcp_flags : 0); json_object_set_new(tjs, "tcp_flags_tc", json_string(hexflags)); JsonTcpFlags(ssn ? ssn->tcp_packet_flags : 0, tjs); if (ssn) { char *state = NULL; switch (ssn->state) { case TCP_NONE: state = "none"; break; case TCP_LISTEN: state = "listen"; break; case TCP_SYN_SENT: state = "syn_sent"; break; case TCP_SYN_RECV: state = "syn_recv"; break; case TCP_ESTABLISHED: state = "established"; break; case TCP_FIN_WAIT1: state = "fin_wait1"; break; case TCP_FIN_WAIT2: state = "fin_wait2"; break; case TCP_TIME_WAIT: state = "time_wait"; break; case TCP_LAST_ACK: state = "last_ack"; break; case TCP_CLOSE_WAIT: state = "close_wait"; break; case TCP_CLOSING: state = "closing"; break; case TCP_CLOSED: state = "closed"; break; } json_object_set_new(tjs, "state", json_string(state)); } json_object_set_new(js, "tcp", tjs); } }
json_t *CreateJSONHeader(const Packet *p, enum OutputJsonLogDirection dir, const char *event_type) { char timebuf[64]; const Flow *f = (const Flow *)p->flow; json_t *js = json_object(); if (unlikely(js == NULL)) return NULL; CreateIsoTimeString(&p->ts, timebuf, sizeof(timebuf)); /* time & tx */ json_object_set_new(js, "timestamp", json_string(timebuf)); CreateJSONFlowId(js, f); /* sensor id */ if (sensor_id >= 0) json_object_set_new(js, "sensor_id", json_integer(sensor_id)); /* input interface */ if (p->livedev) { json_object_set_new(js, "in_iface", json_string(p->livedev->dev)); } /* pcap_cnt */ if (p->pcap_cnt != 0) { json_object_set_new(js, "pcap_cnt", json_integer(p->pcap_cnt)); } if (event_type) { json_object_set_new(js, "event_type", json_string(event_type)); } /* vlan */ if (p->vlan_idx > 0) { json_t *js_vlan = json_array(); if (js_vlan) { json_array_append_new(js_vlan, json_integer(p->vlan_id[0])); if (p->vlan_idx > 1) { json_array_append_new(js_vlan, json_integer(p->vlan_id[1])); } json_object_set_new(js, "vlan", js_vlan); } } /* 5-tuple */ JsonFiveTuple(p, dir, js); /* icmp */ switch (p->proto) { case IPPROTO_ICMP: if (p->icmpv4h) { json_object_set_new(js, "icmp_type", json_integer(p->icmpv4h->type)); json_object_set_new(js, "icmp_code", json_integer(p->icmpv4h->code)); } break; case IPPROTO_ICMPV6: if (p->icmpv6h) { json_object_set_new(js, "icmp_type", json_integer(p->icmpv6h->type)); json_object_set_new(js, "icmp_code", json_integer(p->icmpv6h->code)); } break; } return js; }