int parse_sflow5(const char **p) { u_int32_t format, len; u_int32_t seqno, src_id, srate, total, drops, input, output, nrecords; u_int32_t record_type, record_len; u_int32_t protocol, framelen, stripped; int snaplen, i; format = buffer_read_4(p) & 0xfff; len = buffer_read_4(p); if (verbose > 1) fprintf(stderr, "sflow5: format:%u, len:%u\n", format, len); switch (format) { case 1: /* flow sample */ seqno = buffer_read_4(p); src_id = buffer_read_4(p); srate = buffer_read_4(p); total = buffer_read_4(p); drops = buffer_read_4(p); input = buffer_read_4(p); output = buffer_read_4(p); nrecords = buffer_read_4(p); sampling_rate = srate; if (verbose > 1) fprintf(stderr, "flow sample: srate:%u, nrecords:%u\n", srate, nrecords); for (i = 0; i < nrecords; i++) { record_type = buffer_read_4(p); record_len = buffer_read_4(p); /* clear aguri_flow to be filled in parsers */ memset(&aguri_flow, 0, sizeof(aguri_flow)); switch (record_type) { case 1: /* raw packet header */ protocol = buffer_read_4(p); framelen = buffer_read_4(p); stripped = buffer_read_4(p); record_len -= 12; if (verbose > 1) fprintf(stderr, "record type: raw header: proto:%u, rlen:%u flen:%u, stripped:%u\n", protocol, record_len, framelen, stripped); switch (protocol) { case 1: /* ethernet */ /* read the first 4 bytes for snaplen */ snaplen = ntohl(*((u_int32_t *)*p)); snapend = *p + 4 + snaplen; /* frame_length holds ethernet frame * length; we remove 4 bytes of FCS to * be consistent with pcap */ frame_length = framelen - 4; etherhdr_parse(*p + 4, snaplen); break; default: break; } buffer_skip(p, record_len); break; default: if (verbose > 1) fprintf(stderr, "record type:%u, len:%u\n", record_type, record_len); buffer_skip(p, record_len); break; } /* switch */ if (aguri_flow.agflow_fs.fs_ipver != 0) { /* flow info was filled by the parser: * for frame_length, we remove 4 bytes of FCS * to be consistent with pcap */ aguri_flow.agflow_packets = htonl(1 * srate); aguri_flow.agflow_bytes = htonl((framelen - 4) * srate); aguri_flow.agflow_first = aguri_flow.agflow_last = htonl((u_int32_t)timestamp); if (debug == 0) { if (fwrite(&aguri_flow, sizeof(aguri_flow), 1, stdout) != 1) err(1, "fwrite failed!"); } else print_flow(&aguri_flow); } } /* nrecords in sample */ break; case 2: /* counter sample */ buffer_skip(p, len); break; case 3: /* expanded flow sample */ buffer_skip(p, len); break; case 4: /* expanded counter sample */ buffer_skip(p, len); break; default: buffer_skip(p, len); break; } return (0); }
static void ether_if_read(u_char *user, const struct pcap_pkthdr *h, const u_char *p) { etherhdr_parse((const char *)p, h->caplen); }
int parse_sflow4_sample(const char **p) { u_int32_t sample_type, packetdata_type; u_int32_t seqno, src_id, srate, total, drops, input, output; u_int32_t protocol, framelen, snaplen; u_int32_t interval, counters_version; u_int32_t nextended, extended_type, addr_type; u_int32_t aspath_len, asn_len, community_len, str_len; int i; sample_type = buffer_read_4(p); if (verbose > 1) fprintf(stderr, "sflow4: sample_type:%u\n", sample_type); switch (sample_type) { case 1: /* flow sample */ seqno = buffer_read_4(p); src_id = buffer_read_4(p); srate = buffer_read_4(p); total = buffer_read_4(p); drops = buffer_read_4(p); input = buffer_read_4(p); output = buffer_read_4(p); sampling_rate = srate; packetdata_type = buffer_read_4(p); if (verbose > 1) fprintf(stderr, "flow_sample: packetdata_type:%u, srate:%u\n", packetdata_type, srate); switch (packetdata_type) { case 1: /* header */ protocol = buffer_read_4(p); framelen = buffer_read_4(p); snaplen = buffer_read_4(p); if (verbose > 0) fprintf(stderr, "header: framelen:%u, snaplen:%u, proto:%u\n", framelen, snaplen, protocol); /* clear aguri_flow to be filled in parsers */ memset(&aguri_flow, 0, sizeof(aguri_flow)); switch (protocol) { case 1: /* ethernet */ snapend = *p + snaplen; etherhdr_parse(*p, snaplen); break; default: if (verbose > 0) fprintf(stderr, "unknown proto:%u\n", protocol); break; } buffer_skip(p, snaplen); if (aguri_flow.agflow_fs.fs_ipver != 0) { /* flow info was filled by the parser: * for frame_length, we remove 4 bytes of FCS * to be consistent with pcap */ aguri_flow.agflow_packets = htonl(1 * srate); aguri_flow.agflow_bytes = htonl((framelen - 4) * srate); aguri_flow.agflow_first = aguri_flow.agflow_last = htonl((u_int32_t)timestamp); if (debug == 0) { if (fwrite(&aguri_flow, sizeof(aguri_flow), 1, stdout) != 1) err(1, "fwrite failed!"); } else print_flow(&aguri_flow); } break; case 2: /* IPv4 */ buffer_skip(p, 8*4); if (verbose > 0) fprintf(stderr, "packetdata IPv4 not supported\n"); break; case 3: /* IPv6 */ buffer_skip(p, 14*4); if (verbose > 0) fprintf(stderr, "packetdata IPv6 not supported\n"); break; default: if (verbose > 0) fprintf(stderr, "unknown packetdata_type:%u\n", packetdata_type); return (-1); } /* extended data */ nextended = buffer_read_4(p); if (verbose > 0) fprintf(stderr, "extended data:%u\n", nextended); for (i = 0; i < nextended; i++) { extended_type = buffer_read_4(p); switch (extended_type) { case 1: /* switch */ buffer_skip(p, 4*4); break; case 2: /* router */ addr_type = buffer_read_4(p); switch (addr_type) { case 1: /* IPv4 */ buffer_skip(p, 4); break; case 2: /* IPv6 */ buffer_skip(p, 16); break; default: return (-1); } buffer_skip(p, 2*4); break; case 3: /* gateway */ buffer_skip(p, 3*4); aspath_len = buffer_read_4(p); while (aspath_len-- > 0) { buffer_skip(p, 4); if (sflow_version >= 4) { asn_len = buffer_read_4(p); while (asn_len-- > 0) buffer_skip(p, 4); } } community_len = buffer_read_4(p); buffer_skip(p, community_len * 4); buffer_skip(p, 4); break; case 4: /* user */ str_len = buffer_read_4(p); buffer_skip(p, str_len); str_len = buffer_read_4(p); buffer_skip(p, str_len); break; case 5: /* url */ buffer_skip(p, 4); str_len = buffer_read_4(p); buffer_skip(p, str_len); break; default: return (-1); } } break; case 2: /* counter sample */ seqno = buffer_read_4(p); src_id = buffer_read_4(p); interval = buffer_read_4(p); counters_version = buffer_read_4(p); if (verbose > 0) fprintf(stderr, "counter sample: type:%u\n", counters_version); switch (counters_version) { case 1: /* generic */ buffer_skip(p, 22*4); break; case 2: /* ethernet */ buffer_skip(p, 22*4); buffer_skip(p, 13*4); break; case 3: /* tokenring */ buffer_skip(p, 22*4); buffer_skip(p, 18*4); break; case 4: /* fddi */ buffer_skip(p, 22*4); break; case 5: /* 100basevg */ buffer_skip(p, 22*4); buffer_skip(p, 20*4); break; case 6: /* wan */ buffer_skip(p, 22*4); break; case 7: /* vlan */ buffer_skip(p, 7*4); break; default: if (verbose > 0) fprintf(stderr, "counter sample %d not supported\n", counters_version); return (-1); } break; default: if (verbose > 0) fprintf(stderr, "unknown sample_type %u\n", sample_type); return (-1); } return (0); }