#include #include #include #include #include "bytes.h" #include "queue.h" #include int flow_read_end(); int flow_write_end(); int flow_write(); int flow_flush(); struct flow_data *flow_read(); int flow_read_header(); char *strerror(); int writen(); int flow_print_header(); int profile_start(); int profile_end(); void swap_flow_pdu(); void swap_flow_pdu2(); void swap_flow_header(); void swap_flow_data(); #define FH_HOSTNAME_LEN 68 #define FH_COMMENTS_LEN 256 /* shut up gcc */ time_t time(); #define DEBUG 1 #ifndef BIG_ENDIAN #define BIG_ENDIAN 4321 #endif #ifndef LITTLE_ENDIAN #define LITTLE_ENDIAN 1234 #endif #ifndef BYTE_ORDER #define BYTE_ORDER BIG_ENDIAN #endif #define FF_LITTLE_ENDIAN 1 #define FF_BIG_ENDIAN 2 #define FF_FLAG_DONE 0x1 /* file is not being written to */ #define FF_FLAG_COMPRESS 0x2 /* file is compressed */ #define FF_FLAG_MULT_PDU 0x4 /* multiple pdu types received */ #define FF_COMMENT_LEN 256 /* length of comment buffer */ #define FF_D_VERSION_UNKNOWN 0xFFFF /* unknown data */ #define FS_FLAG_ZINIT 0x1 #define FS_FLAG_COMPRESS 0x2 #define MAXFLOWS_V1 24 /* max flow records in a flow PDU */ #define MAXFLOWS_V5 25 /* max flow records in a flow PDU */ #define FLOWPORT 9991 #define MAXPATHNAME 255 /* max pathname length */ #define FLOW_BUFS 256 /* # of flows to buffer before disk write, min 2 */ #define FF_MAGIC1 0xCF #define FF_MAGIC2 0x10 #define Z_BUFSIZE 16384 /* size of inflate/deflate buffer */ #define PROTO_UDP 17 #define PROT_TCP 6 #define FSTREAM_VERSION 1 #define FLOWFILELEN 23 /* size of flow file name length */ /* tmp05.YYYY-MM-DD.HHMMSS */ /* cf05.YYYY-MM-DD.HHMMSS */ #define FLOW_RECV_BUFSIZE 2048 /* large enough to handle a flow pdu */ struct flow_profile { struct timeval t0; /* profile start */ struct timeval t1; /* profile end */ struct rusage r0; /* system resources used */ u_int64 nflows; /* total # of flows processed */ }; struct flow_header { u_int8 magic1; /* 0xCF */ u_int8 magic2; /* 0xL0 (cisco flow) */ u_int8 byte_order; /* 1 for little endian (VAX) */ /* 2 for big endian (Motorolla) */ u_int8 s_version; /* flow stream format version 0, or 1 */ /* here down is in the byte order specified by byte_order */ u_int16 d_version; /* 1 or 5 */ u_int32 start; /* start time of flow capture */ u_int32 end; /* end time of flow capture */ u_int32 flags; u_int32 rotation; /* rotation schedule */ u_int32 nflows; /* # of flows */ u_int32 pdu_drops; /* # of dropped pdu's detected */ u_int32 pdu_misordered; /* # of detected misordered packets */ char hostname[FH_HOSTNAME_LEN]; /* 0 terminated name of capture device */ char comments[FH_COMMENTS_LEN]; /* 0 terminated ascii comments */ }; struct flow_data { u_int32 unix_secs; /* offset from real time the flow started */ u_int32 unix_msecs; /* "" */ u_int32 srcaddr; /* Source IP Address */ u_int32 dstaddr; /* Destination IP Address */ u_int32 nexthop; /* Next hop router's IP Address */ u_int16 input; /* Input interface index */ u_int16 output; /* Output interface index */ u_int32 dPkts; /* Packets sent in Duration */ u_int32 dOctets; /* Octets sent in Duration. */ u_int32 First; /* SysUptime at start of flow */ u_int32 Last; /* and of last packet of flow */ u_int16 srcport; /* TCP/UDP source port number or equivalent */ u_int16 dstport; /* TCP/UDP destination port number or equiv */ u_int16 pad; u_int8 prot; /* IP protocol, e.g., 6=TCP, 17=UDP, ... */ u_int8 tos; /* IP Type-of-Service */ u_int8 flags; /* Reason flow was discarded, etc... */ u_int8 tcp_retx_cnt; /* Number of mis-seq with delay > 1sec */ u_int8 tcp_retx_secs; /* Cumulative secs between mis-sequenced pkts */ u_int8 tcp_misseq_cnt; /* Number of mis-sequenced tcp pkts seen */ u_int16 src_as; /* originating AS of source address */ u_int16 dst_as; /* originating AS of destination address */ u_int8 src_mask; /* source address prefix mask bits */ u_int8 dst_mask; /* destination address prefix mask bits */ u_int16 drops; /* ?? */ }; struct flow_stream { int count; /* # of flows in the buffer */ int leftover; /* # of bytes left over after read */ int next; /* next flow */ struct flow_data fdata[FLOW_BUFS]; /* flows */ struct flow_header fh; /* flow header */ u_char z_buf[Z_BUFSIZE]; /* inflate/deflate buffer */ int z_level; /* compression level */ z_stream zs; /* zlib io */ int flags; int fd; }; struct flow_pdu_v1 { /* 16 byte header */ u_int16 version; /* 1 for now. */ u_int16 count; /* The number of records in the PDU */ u_int32 sysUpTime; /* Current time in millisecs since router booted */ u_int32 unix_secs; /* Current seconds since 0000 UTC 1970 */ u_int32 unix_nsecs; /* Residual nanoseconds since 0000 UTC 1970 */ /* 48 byte payload */ struct flow_rec_v1 { u_int32 srcaddr; /* Source IP Address */ u_int32 dstaddr; /* Destination IP Address */ u_int32 nexthop; /* Next hop router's IP Address */ u_int16 input; /* Input interface index */ u_int16 output; /* Output interface index */ u_int32 dPkts; /* Packets sent in Duration */ u_int32 dOctets; /* Octets sent in Duration. */ u_int32 First; /* SysUptime at start of flow */ u_int32 Last; /* and of last packet of flow */ u_int16 srcport; /* TCP/UDP source port number or equivalent */ u_int16 dstport; /* TCP/UDP destination port number or equiv */ u_int16 pad; u_int8 prot; /* IP protocol, e.g., 6=TCP, 17=UDP, ... */ u_int8 tos; /* IP Type-of-Service */ u_int8 flags; /* Reason flow was discarded, etc... */ u_int8 tcp_retx_cnt; /* Number of mis-seq with delay > 1sec */ u_int8 tcp_retx_secs; /* Cumulative secs between mis-sequenced pkts */ u_int8 tcp_misseq_cnt; /* Number of mis-sequenced tcp pkts seen */ u_int32 reserved; } records[MAXFLOWS_V1]; }; struct flow_pdu_v5 { /* 24 byte header */ u_int16 version; /* 5 */ u_int16 count; /* The number of records in the PDU */ u_int32 sysUpTime; /* Current time in millisecs since router booted */ u_int32 unix_secs; /* Current seconds since 0000 UTC 1970 */ u_int32 unix_nsecs; /* Residual nanoseconds since 0000 UTC 1970 */ u_int32 flow_sequence; /* Seq counter of total flows seen */ u_int32 reserved; /* 48 byte payload */ struct flow_rec_v5 { u_int32 srcaddr; /* Source IP Address */ u_int32 dstaddr; /* Destination IP Address */ u_int32 nexthop; /* Next hop router's IP Address */ u_int16 input; /* Input interface index */ u_int16 output; /* Output interface index */ u_int32 dPkts; /* Packets sent in Duration */ u_int32 dOctets; /* Octets sent in Duration. */ u_int32 First; /* SysUptime at start of flow */ u_int32 Last; /* and of last packet of flow */ u_int16 srcport; /* TCP/UDP source port number or equivalent */ u_int16 dstport; /* TCP/UDP destination port number or equiv */ u_int8 pad; u_int8 tcp_flags; /* Cumulative OR of tcp flags */ u_int8 prot; /* IP protocol, e.g., 6=TCP, 17=UDP, ... */ u_int8 tos; /* IP Type-of-Service */ u_int16 src_as; /* originating AS of source address */ u_int16 dst_as; /* originating AS of destination address */ u_int8 src_mask; /* source address prefix mask bits */ u_int8 dst_mask; /* destination address prefix mask bits */ u_int16 drops; } records[MAXFLOWS_V5]; }; struct jump { int (*where)(); }; struct flow_stat0 { u_int64 nflows; /* total # flows */ u_int64 noctets; /* total # octets */ u_int64 npackets; /* total # packets */ u_int64 time; /* total time in 1/1000 of flows */ double aflowtime; /* average time of flow */ double aps; /* average packet size */ double afs; /* average flow size */ double apf; /* average packets per flow */ double fps; /* average flows per second */ double aos; /* average octets per second */ u_int64 start; /* earliest flow time */ u_int64 end; /* latest flow time */ /* average packet sizes */ u_int64 psize32; /* bytes/packet 1 <= p <= 32 */ u_int64 psize64; /* bytes/packet 32 < p <= 64 */ u_int64 psize96; u_int64 psize128; u_int64 psize160; u_int64 psize192; u_int64 psize224; u_int64 psize256; u_int64 psize288; u_int64 psize320; u_int64 psize352; u_int64 psize384; u_int64 psize416; u_int64 psize448; u_int64 psize480; u_int64 psize512; u_int64 psize544; u_int64 psize576; u_int64 psize1024; u_int64 psize1536; u_int64 psize2048; u_int64 psize2560; u_int64 psize3072; u_int64 psize3584; u_int64 psize4096; u_int64 psize4608; /* packets per flow */ u_int64 fpsize1; /* packets/flow = 1 */ u_int64 fpsize2; /* packets/flow = 2 */ u_int64 fpsize4; /* packets/flow 2 < p <= 4 */ u_int64 fpsize8; /* packets/flow 4 < p <= 8 */ u_int64 fpsize12; u_int64 fpsize16; u_int64 fpsize20; u_int64 fpsize24; u_int64 fpsize28; u_int64 fpsize32; u_int64 fpsize36; u_int64 fpsize40; u_int64 fpsize44; u_int64 fpsize48; u_int64 fpsize52; u_int64 fpsize60; u_int64 fpsize100; u_int64 fpsize200; u_int64 fpsize300; u_int64 fpsize400; u_int64 fpsize500; u_int64 fpsize600; u_int64 fpsize700; u_int64 fpsize800; u_int64 fpsize900; u_int64 fpsize_other; /* packets/flow 200 < p */ /* octets per flow */ u_int64 fosize32; /* octets/flow 1 <= p <= 32 */ u_int64 fosize64; /* octets/flow 32 < p <= 64 */ u_int64 fosize128; /* octets/flow 64 < p <= 128 */ u_int64 fosize256; /* octets/flow 128 < p <= 256 */ u_int64 fosize512; u_int64 fosize1280; u_int64 fosize2048; u_int64 fosize2816; u_int64 fosize3584; u_int64 fosize4352; u_int64 fosize5120; u_int64 fosize5888; u_int64 fosize6656; u_int64 fosize7424; u_int64 fosize8192; u_int64 fosize8960; u_int64 fosize9728; u_int64 fosize10496; u_int64 fosize11264; u_int64 fosize12032; u_int64 fosize12800; u_int64 fosize13568; u_int64 fosize14336; u_int64 fosize15104; u_int64 fosize15872; u_int64 fosize_other; /* octets/flow 15872 < p */ /* time per flow */ u_int64 ftime10; /* time/flow 1 <= p <= 10 */ u_int64 ftime50; /* time/flow 10 < p <= 50 */ u_int64 ftime100; u_int64 ftime200; u_int64 ftime500; u_int64 ftime1000; u_int64 ftime2000; u_int64 ftime3000; u_int64 ftime4000; u_int64 ftime5000; u_int64 ftime6000; u_int64 ftime7000; u_int64 ftime8000; u_int64 ftime9000; u_int64 ftime10000; u_int64 ftime12000; u_int64 ftime14000; u_int64 ftime16000; u_int64 ftime18000; u_int64 ftime20000; u_int64 ftime22000; u_int64 ftime24000; u_int64 ftime26000; u_int64 ftime28000; u_int64 ftime30000; u_int64 ftime_other; /* time/flow 2000 < p */ }; struct file_entry { char *name[FLOWFILELEN+1]; off_t size; u_int32 start; TAILQ_ENTRY(file_entry) chain; }; struct file_ager { TAILQ_HEAD(talkqhead, file_entry) head; u_int64 num_bytes; /* space used by all flow files except current */ u_int64 max_bytes; /* min space before removing files 0=disable */ u_int32 max_files; /* max num of files to keep before removing 0=disable */ u_int32 num_files; /* number of files in the queue */ };