static void
process_netflow_v7(struct flow_packet *fp, struct flowd_config *conf,
    struct peer_state *peer, struct peers *peers, int log_fd, int log_socket)
{
	struct NF7_HEADER *nf7_hdr = (struct NF7_HEADER *)fp->packet;
	struct NF7_FLOW *nf7_flow;
	struct store_flow_complete flow;
	size_t offset;
	u_int i, nflows;
	if (fp->len < sizeof(*nf7_hdr)) {
		peer->ninvalid++;
		logit(LOG_WARNING, "short netflow v.7 packet %d bytes from %s",
		    fp->len, addr_ntop_buf(&fp->flow_source));
		return;
	}
	nflows = ntohs(nf7_hdr->c.flows);
	if (nflows == 0 || nflows > NF7_MAXFLOWS) {
		peer->ninvalid++;
		logit(LOG_WARNING, "Invalid number of flows (%u) in netflow "
		    "v.7 packet from %s", nflows,
		    addr_ntop_buf(&fp->flow_source));
		return;
	}
	if (fp->len != NF7_PACKET_SIZE(nflows)) {
		peer->ninvalid++;
		logit(LOG_WARNING, "Inconsistent Netflow v.7 packet from %s: "
		    "len %u expected %u", addr_ntop_buf(&fp->flow_source),
		    fp->len, NF7_PACKET_SIZE(nflows));
		return;
	}

	logit(LOG_DEBUG, "Valid netflow v.7 packet %d flows", nflows);
	update_peer(peers, peer, nflows, 7);

	for (i = 0; i < nflows; i++) {
		offset = NF7_PACKET_SIZE(i);
		nf7_flow = (struct NF7_FLOW *)(fp->packet + offset);

		bzero(&flow, sizeof(flow));

		/* NB. These are converted to network byte order later */
		flow.hdr.fields = STORE_FIELD_ALL;
		/* flow.hdr.tag is set later */
		flow.hdr.fields &= ~STORE_FIELD_TAG;
		flow.hdr.fields &= ~STORE_FIELD_SRC_ADDR6;
		flow.hdr.fields &= ~STORE_FIELD_DST_ADDR6;
		flow.hdr.fields &= ~STORE_FIELD_GATEWAY_ADDR6;

		/*
		 * XXX: we can parse the (undocumented) flags1 and flags2
		 * fields of the packet to disable flow fields not set by
		 * the Cat5k (e.g. destination-only mls nde mode)
		 */

		flow.recv_time.recv_sec = fp->recv_time.tv_sec;
		flow.recv_time.recv_usec = fp->recv_time.tv_usec;

		flow.pft.tcp_flags = nf7_flow->tcp_flags;
		flow.pft.protocol = nf7_flow->protocol;
		flow.pft.tos = nf7_flow->tos;

		memcpy(&flow.agent_addr, &fp->flow_source,
		    sizeof(flow.agent_addr));

		flow.src_addr.v4.s_addr = nf7_flow->src_ip;
		flow.src_addr.af = AF_INET;
		flow.dst_addr.v4.s_addr = nf7_flow->dest_ip;
		flow.dst_addr.af = AF_INET;
		flow.gateway_addr.v4.s_addr = nf7_flow->nexthop_ip;
		flow.gateway_addr.af = AF_INET;

		flow.ports.src_port = nf7_flow->src_port;
		flow.ports.dst_port = nf7_flow->dest_port;

#define NTO64(a) (store_htonll(ntohl(a)))
		flow.octets.flow_octets = NTO64(nf7_flow->flow_octets);
		flow.packets.flow_packets = NTO64(nf7_flow->flow_packets);
#undef NTO64

		flow.ifndx.if_index_in = htonl(ntohs(nf7_flow->if_index_in));
		flow.ifndx.if_index_out = htonl(ntohs(nf7_flow->if_index_out));

		flow.ainfo.sys_uptime_ms = nf7_hdr->uptime_ms;
		flow.ainfo.time_sec = nf7_hdr->time_sec;
		flow.ainfo.time_nanosec = nf7_hdr->time_nanosec;
		flow.ainfo.netflow_version = nf7_hdr->c.version;

		flow.ftimes.flow_start = nf7_flow->flow_start;
		flow.ftimes.flow_finish = nf7_flow->flow_finish;

		flow.asinf.src_as = htonl(ntohs(nf7_flow->src_as));
		flow.asinf.dst_as = htonl(ntohs(nf7_flow->dest_as));
		flow.asinf.src_mask = nf7_flow->src_mask;
		flow.asinf.dst_mask = nf7_flow->dst_mask;

		flow.finf.flow_sequence = nf7_hdr->flow_sequence;



/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                          ADD IMED

/*sem_wait (&semFlows);

Add_flow(&flow);

sem_post (&semFlows);
*/
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////




		process_flow(&flow, conf, log_fd, log_socket);
	}
}
예제 #2
0
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);
    }
}
예제 #3
0
void process_netflow_v5(struct flow_packet* fp, struct peer_state* peer)
{
    struct NF5_HEADER* nf5_hdr = (struct NF5_HEADER*)fp->packet;
    struct NF5_FLOW* nf5_flow;
    struct store_flow_complete flow;
    size_t offset;
    u_int i, nflows;

    if (fp->len < sizeof(*nf5_hdr)) {
        peer->ninvalid++;
        logit(LOG_WARNING, "short netflow v.5 packet %d bytes from %s",
            fp->len, addr_ntop_buf(&fp->flow_source));
        return;
    }
    nflows = ntohs(nf5_hdr->c.flows);
    if (nflows == 0 || nflows > NF5_MAXFLOWS) {
        peer->ninvalid++;
        logit(LOG_WARNING, "Invalid number of flows (%u) in netflow "
            "v.5 packet from %s", nflows,
            addr_ntop_buf(&fp->flow_source));
        return;
    }
    if (fp->len != NF5_PACKET_SIZE(nflows)) {
        peer->ninvalid++;
        logit(LOG_WARNING, "Inconsistent Netflow v.5 packet from %s: "
            "len %u expected %zu", addr_ntop_buf(&fp->flow_source),
            fp->len, NF5_PACKET_SIZE(nflows));
        return;
    }

    logit(LOG_DEBUG, "Valid netflow v.5 packet %d flows", nflows);
    update_peer(peer, nflows, 5);

    for (i = 0; i < nflows; i++) {
        offset = NF5_PACKET_SIZE(i);
        nf5_flow = (struct NF5_FLOW*)(fp->packet + offset);

        bzero(&flow, sizeof(flow));

        /* NB. These are converted to network byte order later */
        flow.hdr.fields = STORE_FIELD_ALL;
        /* flow.hdr.tag is set later */
        flow.hdr.fields &= ~STORE_FIELD_TAG;
        flow.hdr.fields &= ~STORE_FIELD_SRC_ADDR6;
        flow.hdr.fields &= ~STORE_FIELD_DST_ADDR6;
        flow.hdr.fields &= ~STORE_FIELD_GATEWAY_ADDR6;

        flow.recv_time.recv_sec = fp->recv_time.tv_sec;
        flow.recv_time.recv_usec = fp->recv_time.tv_usec;

        flow.pft.tcp_flags = nf5_flow->tcp_flags;
        flow.pft.protocol = nf5_flow->protocol;
        flow.pft.tos = nf5_flow->tos;

        rte_memcpy(&flow.agent_addr, &fp->flow_source,
            sizeof(flow.agent_addr));

        flow.src_addr.v4.s_addr = nf5_flow->src_ip;
        flow.src_addr.af = AF_INET;
        flow.dst_addr.v4.s_addr = nf5_flow->dest_ip;
        flow.dst_addr.af = AF_INET;
        flow.gateway_addr.v4.s_addr = nf5_flow->nexthop_ip;
        flow.gateway_addr.af = AF_INET;

        flow.ports.src_port = nf5_flow->src_port;
        flow.ports.dst_port = nf5_flow->dest_port;

#define NTO64(a) (netflow_htonll(ntohl(a)))
        flow.octets.flow_octets = NTO64(nf5_flow->flow_octets);
        flow.packets.flow_packets = NTO64(nf5_flow->flow_packets);
#undef NTO64

        flow.ifndx.if_index_in = htonl(ntohs(nf5_flow->if_index_in));
        flow.ifndx.if_index_out = htonl(ntohs(nf5_flow->if_index_out));

        flow.ainfo.sys_uptime_ms = nf5_hdr->uptime_ms;
        flow.ainfo.time_sec = nf5_hdr->time_sec;
        flow.ainfo.time_nanosec = nf5_hdr->time_nanosec;
        flow.ainfo.netflow_version = nf5_hdr->c.version;

        flow.ftimes.flow_start = nf5_flow->flow_start;
        flow.ftimes.flow_finish = nf5_flow->flow_finish;

        flow.asinf.src_as = htonl(ntohs(nf5_flow->src_as));
        flow.asinf.dst_as = htonl(ntohs(nf5_flow->dest_as));
        flow.asinf.src_mask = nf5_flow->src_mask;
        flow.asinf.dst_mask = nf5_flow->dst_mask;

        flow.finf.engine_type = nf5_hdr->engine_type;
        flow.finf.engine_id = nf5_hdr->engine_id;
        flow.finf.flow_sequence = nf5_hdr->flow_sequence;

        process_flow(&flow);
    }
}
예제 #4
0
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;
}