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); } }
/* 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); } }
/* 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); } }