void netflow_format_flow(struct store_flow_complete* flow, char* buf, size_t len, int utc_flag, u_int32_t display_mask, int hostorder) { char tmp[256]; u_int32_t fields; u_int64_t (*fmt_ntoh64)(u_int64_t) = netflow_swp_ntoh64; u_int32_t (*fmt_ntoh32)(u_int32_t) = netflow_swp_ntoh32; u_int16_t (*fmt_ntoh16)(u_int16_t) = netflow_swp_ntoh16; if (hostorder) { fmt_ntoh64 = netflow_swp_fake64; fmt_ntoh32 = netflow_swp_fake32; fmt_ntoh16 = netflow_swp_fake16; } *buf = '\0'; fields = fmt_ntoh32(flow->hdr.fields) & display_mask; strlcat(buf, "FLOW ", len); if (SHASFIELD(TAG)) { snprintf(tmp, sizeof(tmp), "tag %u ", fmt_ntoh32(flow->tag.tag)); strlcat(buf, tmp, len); } if (SHASFIELD(RECV_TIME)) { snprintf(tmp, sizeof(tmp), "recv_time %s.%05d ", iso_time(fmt_ntoh32(flow->recv_time.recv_sec), utc_flag), fmt_ntoh32(flow->recv_time.recv_usec)); strlcat(buf, tmp, len); } if (SHASFIELD(PROTO_FLAGS_TOS)) { snprintf(tmp, sizeof(tmp), "proto %d ", flow->pft.protocol); strlcat(buf, tmp, len); snprintf(tmp, sizeof(tmp), "tcpflags %02x ", flow->pft.tcp_flags); strlcat(buf, tmp, len); snprintf(tmp, sizeof(tmp), "tos %02x " , flow->pft.tos); strlcat(buf, tmp, len); } if (SHASFIELD(AGENT_ADDR4) || SHASFIELD(AGENT_ADDR6)) { snprintf(tmp, sizeof(tmp), "agent [%s] ", addr_ntop_buf(&flow->agent_addr)); strlcat(buf, tmp, len); } if (SHASFIELD(SRC_ADDR4) || SHASFIELD(SRC_ADDR6)) { snprintf(tmp, sizeof(tmp), "src [%s]", addr_ntop_buf(&flow->src_addr)); strlcat(buf, tmp, len); if (SHASFIELD(SRCDST_PORT)) { snprintf(tmp, sizeof(tmp), ":%d", fmt_ntoh16(flow->ports.src_port)); strlcat(buf, tmp, len); } strlcat(buf, " ", len); } if (SHASFIELD(DST_ADDR4) || SHASFIELD(DST_ADDR6)) { snprintf(tmp, sizeof(tmp), "dst [%s]", addr_ntop_buf(&flow->dst_addr)); strlcat(buf, tmp, len); if (SHASFIELD(SRCDST_PORT)) { snprintf(tmp, sizeof(tmp), ":%d", fmt_ntoh16(flow->ports.dst_port)); strlcat(buf, tmp, len); } strlcat(buf, " ", len); } if (SHASFIELD(GATEWAY_ADDR4) || SHASFIELD(GATEWAY_ADDR6)) { snprintf(tmp, sizeof(tmp), "gateway [%s] ", addr_ntop_buf(&flow->gateway_addr)); strlcat(buf, tmp, len); } if (SHASFIELD(PACKETS)) { snprintf(tmp, sizeof(tmp), "packets %lu ", fmt_ntoh64(flow->packets.flow_packets)); strlcat(buf, tmp, len); } if (SHASFIELD(OCTETS)) { snprintf(tmp, sizeof(tmp), "octets %lu ", fmt_ntoh64(flow->octets.flow_octets)); strlcat(buf, tmp, len); } if (SHASFIELD(IF_INDICES)) { snprintf(tmp, sizeof(tmp), "in_if %d out_if %d ", fmt_ntoh32(flow->ifndx.if_index_in), fmt_ntoh32(flow->ifndx.if_index_out)); strlcat(buf, tmp, len); } if (SHASFIELD(AGENT_INFO)) { snprintf(tmp, sizeof(tmp), "sys_uptime_ms %s.%03u ", interval_time(fmt_ntoh32(flow->ainfo.sys_uptime_ms) / 1000), fmt_ntoh32(flow->ainfo.sys_uptime_ms) % 1000); strlcat(buf, tmp, len); snprintf(tmp, sizeof(tmp), "time_sec %s ", iso_time(fmt_ntoh32(flow->ainfo.time_sec), utc_flag)); strlcat(buf, tmp, len); snprintf(tmp, sizeof(tmp), "time_nanosec %lu netflow ver %u ", (u_long)fmt_ntoh32(flow->ainfo.time_nanosec), fmt_ntoh16(flow->ainfo.netflow_version)); strlcat(buf, tmp, len); } if (SHASFIELD(FLOW_TIMES)) { snprintf(tmp, sizeof(tmp), "flow_start %s.%03u ", interval_time(fmt_ntoh32(flow->ftimes.flow_start) / 1000), fmt_ntoh32(flow->ftimes.flow_start) % 1000); strlcat(buf, tmp, len); snprintf(tmp, sizeof(tmp), "flow_finish %s.%03u ", interval_time(fmt_ntoh32(flow->ftimes.flow_finish) / 1000), fmt_ntoh32(flow->ftimes.flow_finish) % 1000); strlcat(buf, tmp, len); } if (SHASFIELD(AS_INFO)) { snprintf(tmp, sizeof(tmp), "src_AS %u src_masklen %u ", fmt_ntoh32(flow->asinf.src_as), flow->asinf.src_mask); strlcat(buf, tmp, len); snprintf(tmp, sizeof(tmp), "dst_AS %u dst_masklen %u ", fmt_ntoh32(flow->asinf.dst_as), flow->asinf.dst_mask); strlcat(buf, tmp, len); } if (SHASFIELD(FLOW_ENGINE_INFO)) { snprintf(tmp, sizeof(tmp), "engine_type %u engine_id %u seq %lu source %lu ", fmt_ntoh16(flow->finf.engine_type), fmt_ntoh16(flow->finf.engine_id), (u_long)fmt_ntoh32(flow->finf.flow_sequence), (u_long)fmt_ntoh32(flow->finf.source_id)); strlcat(buf, tmp, len); } if (SHASFIELD(CRC32)) { snprintf(tmp, sizeof(tmp), "crc32 %08x ", fmt_ntoh32(flow->crc32.crc32)); strlcat(buf, tmp, len); } }
int store_v2_flow_deserialise(u_int8_t *buf, int len, struct store_v2_flow_complete *f, char *ebuf, int elen) { int offset, r; struct store_v2_flow_AGENT_ADDR4 aa4; struct store_v2_flow_AGENT_ADDR6 aa6; struct store_v2_flow_SRC_ADDR4 sa4; struct store_v2_flow_SRC_ADDR6 sa6; struct store_v2_flow_DST_ADDR4 da4; struct store_v2_flow_DST_ADDR6 da6; struct store_v2_flow_GATEWAY_ADDR4 ga4; struct store_v2_flow_GATEWAY_ADDR6 ga6; u_int32_t fields, crc; bzero(f, sizeof(*f)); flowd_crc32_start(&crc); memcpy(&f->hdr.fields, buf, sizeof(f->hdr.fields)); if (len < sizeof(f->hdr)) SFAILX(STORE_ERR_BUFFER_SIZE, "supplied length is too small", 1); if ((r = store_v2_calc_flow_len((struct store_v2_flow *)buf)) == -1) SFAILX(STORE_ERR_FLOW_INVALID, "unsupported flow fields specified", 0); if (len - sizeof(f->hdr) < r) SFAILX(STORE_ERR_BUFFER_SIZE, "calulated flow length is less than supplied len", 1); flowd_crc32_update((u_char *)&f->hdr, sizeof(f->hdr), &crc); fields = ntohl(f->hdr.fields); offset = sizeof(f->hdr); #define RFIELD(flag, dest) do { \ if (SHASFIELD(flag)) { \ memcpy(&dest, buf + offset, sizeof(dest)); \ offset += sizeof(dest); \ if (SHASFIELD(CRC32) && \ STORE_V2_FIELD_##flag != STORE_V2_FIELD_CRC32) { \ flowd_crc32_update((u_char *)&dest, \ sizeof(dest), &crc); \ } \ } } while (0) RFIELD(TAG, f->tag); RFIELD(RECV_TIME, f->recv_time); RFIELD(PROTO_FLAGS_TOS, f->pft); RFIELD(AGENT_ADDR4, aa4); RFIELD(AGENT_ADDR6, aa6); RFIELD(SRC_ADDR4, sa4); RFIELD(SRC_ADDR6, sa6); RFIELD(DST_ADDR4, da4); RFIELD(DST_ADDR6, da6); RFIELD(GATEWAY_ADDR4, ga4); RFIELD(GATEWAY_ADDR6, ga6); RFIELD(SRCDST_PORT, f->ports); RFIELD(PACKETS, f->packets); RFIELD(OCTETS, f->octets); RFIELD(IF_INDICES, f->ifndx); RFIELD(AGENT_INFO, f->ainfo); RFIELD(FLOW_TIMES, f->ftimes); RFIELD(AS_INFO, f->asinf); RFIELD(FLOW_ENGINE_INFO, f->finf); RFIELD(CRC32, f->crc32); /* Sanity check and convert addresses */ if (SHASFIELD(AGENT_ADDR4) && SHASFIELD(AGENT_ADDR6)) SFAILX(-1, "Flow has both v4/v6 agent addrs", 0); if (SHASFIELD(SRC_ADDR4) && SHASFIELD(SRC_ADDR6)) SFAILX(-1, "Flow has both v4/v6 src addrs", 0); if (SHASFIELD(DST_ADDR4) && SHASFIELD(DST_ADDR6)) SFAILX(-1, "Flow has both v4/v6 dst addrs", 0); if (SHASFIELD(GATEWAY_ADDR4) && SHASFIELD(GATEWAY_ADDR6)) SFAILX(-1, "Flow has both v4/v6 gateway addrs", 0); #define S_CPYADDR(d, s, fam) do { \ (d).af = (fam == 4) ? AF_INET : AF_INET6; \ memcpy(&d.v##fam, &s, sizeof(d.v##fam)); \ } while (0) if (SHASFIELD(AGENT_ADDR4)) S_CPYADDR(f->agent_addr, aa4.flow_agent_addr, 4); if (SHASFIELD(AGENT_ADDR6)) S_CPYADDR(f->agent_addr, aa6.flow_agent_addr, 6); if (SHASFIELD(SRC_ADDR4)) S_CPYADDR(f->src_addr, sa4.src_addr, 4); if (SHASFIELD(SRC_ADDR6)) S_CPYADDR(f->src_addr, sa6.src_addr, 6); if (SHASFIELD(DST_ADDR4)) S_CPYADDR(f->dst_addr, da4.dst_addr, 4); if (SHASFIELD(DST_ADDR6)) S_CPYADDR(f->dst_addr, da6.dst_addr, 6); if (SHASFIELD(GATEWAY_ADDR4)) S_CPYADDR(f->gateway_addr, ga4.gateway_addr, 4); if (SHASFIELD(GATEWAY_ADDR6)) S_CPYADDR(f->gateway_addr, ga6.gateway_addr, 6); if (SHASFIELD(CRC32) && crc != ntohl(f->crc32.crc32)) SFAILX(STORE_ERR_CRC_MISMATCH, "Flow checksum mismatch", 0); #undef S_CPYADDR #undef RFIELD return (STORE_ERR_OK); }
uint8_t* ss_metadata_prepare_netflow( const char* source, nn_queue_t* nn_queue, struct store_flow_complete* flow, ss_ioc_entry_t* ioc_entry) { json_object* jobject = NULL; json_object* item = NULL; uint8_t* rv = NULL; uint8_t* jstring = NULL; uint32_t fields; uint64_t (*fmt_ntoh64)(uint64_t) = netflow_swp_ntoh64; uint32_t (*fmt_ntoh32)(uint32_t) = netflow_swp_ntoh32; uint16_t (*fmt_ntoh16)(uint16_t) = netflow_swp_ntoh16; uint32_t display_mask = STORE_DISPLAY_ALL; fields = fmt_ntoh32(flow->hdr.fields) & display_mask; int utc_flag = 0; jobject = json_object_new_object(); if (jobject == NULL) { RTE_LOG(ERR, EXTRACTOR, "could not allocate netflow json object\n"); goto error_out; } if (SHASFIELD(TAG)) { item = json_object_new_int(fmt_ntoh32(flow->tag.tag)); json_object_object_add(jobject, "tag", item); } if (SHASFIELD(RECV_TIME)) { item = json_object_new_string(iso_time(fmt_ntoh32(flow->recv_time.recv_sec), utc_flag)); json_object_object_add(jobject, "flow_sec", item); item = json_object_new_int(fmt_ntoh32(flow->recv_time.recv_usec)); json_object_object_add(jobject, "flow_usec", item); } if (SHASFIELD(PROTO_FLAGS_TOS)) { item = json_object_new_int(flow->pft.protocol); json_object_object_add(jobject, "ip_protocol", item); item = json_object_new_int(flow->pft.tcp_flags); json_object_object_add(jobject, "tcp_flags", item); item = json_object_new_int(flow->pft.tos); json_object_object_add(jobject, "ip_tos", item); } if (SHASFIELD(AGENT_ADDR4) || SHASFIELD(AGENT_ADDR6)) { item = json_object_new_string(addr_ntop_buf(&flow->agent_addr)); json_object_object_add(jobject, "agentip", item); } if (SHASFIELD(SRC_ADDR4) || SHASFIELD(SRC_ADDR6)) { item = json_object_new_string(addr_ntop_buf(&flow->src_addr)); json_object_object_add(jobject, "sip", item); item = json_object_new_int(fmt_ntoh16(flow->ports.src_port)); json_object_object_add(jobject, "sport", item); } if (SHASFIELD(DST_ADDR4) || SHASFIELD(DST_ADDR6)) { item = json_object_new_string(addr_ntop_buf(&flow->dst_addr)); json_object_object_add(jobject, "dip", item); item = json_object_new_int(fmt_ntoh16(flow->ports.dst_port)); json_object_object_add(jobject, "dport", item); } if (SHASFIELD(GATEWAY_ADDR4) || SHASFIELD(GATEWAY_ADDR6)) { item = json_object_new_string(addr_ntop_buf(&flow->gateway_addr)); json_object_object_add(jobject, "gatewayip", item); } if (SHASFIELD(PACKETS)) { item = json_object_new_int(fmt_ntoh64(flow->packets.flow_packets)); json_object_object_add(jobject, "packets", item); } if (SHASFIELD(OCTETS)) { item = json_object_new_int(fmt_ntoh64(flow->octets.flow_octets)); json_object_object_add(jobject, "bytes", item); } if (SHASFIELD(IF_INDICES)) { item = json_object_new_int(fmt_ntoh32(flow->ifndx.if_index_in)); json_object_object_add(jobject, "sifindex", item); item = json_object_new_int(fmt_ntoh32(flow->ifndx.if_index_out)); json_object_object_add(jobject, "difindex", item); } if (SHASFIELD(AGENT_INFO)) { item = json_object_new_string(interval_time(fmt_ntoh32(flow->ainfo.sys_uptime_ms) / 1000)); json_object_object_add(jobject, "sys_uptime_sec", item); item = json_object_new_int(fmt_ntoh32(flow->ainfo.sys_uptime_ms) % 1000); json_object_object_add(jobject, "sys_uptime_msec", item); item = json_object_new_string(iso_time(fmt_ntoh32(flow->ainfo.time_sec), utc_flag)); json_object_object_add(jobject, "sys_time_sec", item); item = json_object_new_int((u_long)fmt_ntoh32(flow->ainfo.time_nanosec)); json_object_object_add(jobject, "sys_time_nsec", item); item = json_object_new_int(fmt_ntoh16(flow->ainfo.netflow_version)); json_object_object_add(jobject, "netflow_version", item); } if (SHASFIELD(FLOW_TIMES)) { item = json_object_new_string(interval_time(fmt_ntoh32(flow->ftimes.flow_start) / 1000)); json_object_object_add(jobject, "flow_start_sec", item); item = json_object_new_int(fmt_ntoh32(flow->ftimes.flow_start) % 1000); json_object_object_add(jobject, "flow_start_msec", item); item = json_object_new_string(interval_time(fmt_ntoh32(flow->ftimes.flow_finish) / 1000)); json_object_object_add(jobject, "flow_stop_sec", item); item = json_object_new_int(fmt_ntoh32(flow->ftimes.flow_finish) % 1000); json_object_object_add(jobject, "flow_stop_msec", item); } if (SHASFIELD(AS_INFO)) { item = json_object_new_int(fmt_ntoh32(flow->asinf.src_as)); json_object_object_add(jobject, "src_as", item); item = json_object_new_int(fmt_ntoh32(flow->asinf.src_mask)); json_object_object_add(jobject, "src_masklen", item); item = json_object_new_int(fmt_ntoh32(flow->asinf.dst_as)); json_object_object_add(jobject, "dst_as", item); item = json_object_new_int(fmt_ntoh32(flow->asinf.dst_mask)); json_object_object_add(jobject, "dst_masklen", item); } if (SHASFIELD(FLOW_ENGINE_INFO)) { item = json_object_new_int(fmt_ntoh16(flow->finf.engine_type)); json_object_object_add(jobject, "engine_type", item); item = json_object_new_int(fmt_ntoh16(flow->finf.engine_id)); json_object_object_add(jobject, "engine_id", item); item = json_object_new_int((u_long)fmt_ntoh32(flow->finf.flow_sequence)); json_object_object_add(jobject, "seq_num", item); item = json_object_new_int((u_long)fmt_ntoh32(flow->finf.source_id)); json_object_object_add(jobject, "source_id", item); } if (SHASFIELD(CRC32)) { item = json_object_new_int(fmt_ntoh32(flow->crc32.crc32)); json_object_object_add(jobject, "crc32", item); } item = NULL; rv = 0; // XXX: NOTE: String pointer is internal to JSON object. jstring = (uint8_t*) json_object_to_json_string_ext(jobject, JSON_C_TO_STRING_SPACED); rv = (uint8_t*) je_strdup((char*)jstring); if (!rv) goto error_out; json_object_put(jobject); jobject = NULL; return rv; error_out: fprintf(stderr, "could not serialize packet metadata\n"); if (rv) { je_free(rv); rv = NULL; } if (jobject) { json_object_put(jobject); jobject = NULL; } if (item) { json_object_put(item); item = NULL; } return NULL; }