/* 1705, Sat 7 July 01 (NZT) FLOWHASH.H: Data structures for AU Meter Copyright (C) 1992-2002 by Nevil Brownlee, CAIDA | University of Auckland */ /* * $Log: flowhash.h,v $ * Revision 1.1.1.2.2.12 2002/02/23 01:57:30 nevil * Moving srl examples to examples/ directory. Modified examples/Makefile.in * * Revision 1.1.1.2.2.10 2001/05/24 02:19:52 nevil * LfapMet implemented by Remco Poortinga. * MinPDUs implemented by Nevil. * * Revision 1.1.1.2.2.7 2000/08/08 19:44:52 nevil * 44b8 release * * Revision 1.1.1.2.2.5 2000/06/06 03:38:19 nevil * Combine NEW_ATR with TCP_ATR, various bug fixes * * Revision 1.1.1.2.2.2 2000/01/12 02:57:09 nevil * Implement 'packet pair matched' turnaroundtime distribution attributes. * Fix ASN-related bugs in NeTraMet, distribution-related bugs in fd_filter. * * Revision 1.1.1.2.2.1 1999/11/29 00:17:26 nevil * Make changes to support NetBSD on an Alpha (see version.history for details) * * Revision 1.1.1.2 1999/10/03 21:06:23 nevil * *** empty log message *** * * Revision 1.1.1.1.2.14 1999/09/24 04:09:46 nevil * *** empty log message *** * * Revision 1.1.1.1.2.13 1999/09/24 02:58:39 nevil * Polish up code to get rid of warning messages from Borland (DOS) compiler. * Make manager PeerAddress buffers NSAP_ADDR_LEN bytes long. * Add asn_lookup variable - only call FindSubnet if ruleset uses ASNs. * * Revision 1.1.1.1.2.12 1999/09/22 05:38:41 nevil * Improve code to work properly on 64-bit machines * - Add OS=ALPHA handling to configure.in * - Clean up the Alpha compiler warnings * - Change all the snmp-related code to use Bit32 instead of unsigned long * * Revision 1.1.1.1.2.11 1999/09/14 00:45:28 nevil * 4.3 Release .. * - Implement -D option to run NeTraMet as a daemon * - Tidy up the on-line help displays * * Revision 1.1.1.1.2.10 1999/05/26 02:41:39 nevil * Integrate V6 and ASN code into PC versions of the meter. * This required a rework of the makefiles, using @cflags.opt files * to provide a much longer command line to the Borland C compiler. * * Revision 1.1.1.1.2.9 1999/05/18 03:36:28 nevil * Implement IPv6 in NeTraMet, and its manager/collectors. * - This is controlled by the V6 #define * - NeTraMet recognises v6 packets and fishes through their extension * headers until it finds the actual payload. * - NeMaC et al display v6 addresses in the fom specified by RFC 2373 * - fd_util and fd_extract allow colons in addresses (for defining tags) * * Revision 1.1.1.1.2.8 1999/05/17 00:11:57 nevil * Fixed 'reuse of ruleset row' problem: * When a ruleset row is destroyed, set_RowStatus calls free_rulespace() * and recover_flows(). free_rulespace() zeroed its varibales in the * ri[] row, but recover_flows() didn't (it should have zeroed * ri_flow_chain). This left ri_flow_chain pointing to a free flow, * which cause problems if a manager tried to reuse this row for a * new ruleset. Fixed by zeroing all of the ri[] row. (Also commented * out the zeroing code from free_rulesace). * * Revision 1.1.1.1.2.7 1999/02/16 00:10:53 nevil * Make sure globals are declared when TCP_ATR=0 * * Revision 1.1.1.1.2.6 1999/02/15 21:24:08 nevil * Distribution file for 4.3b9 * * Revision 1.1.1.1.2.4 1999/01/20 03:55:50 nevil * Implementation of TCP attributes, part 4 * * Revision 1.1.1.1.2.3 1999/01/08 01:31:53 nevil * Implementation of TCP attributes, part 3 * * Revision 1.1.1.1.2.2 1998/12/22 23:53:08 nevil * Implementation of TCP attributes, part 2 * * Revision 1.1.1.1 1998/11/16 03:57:29 nevil * Import of NeTraMet 4.3b3 * * Revision 1.1.1.1.2.2 1998/11/16 02:46:58 nevil * Implementation of TCP attributes, part 1 * * Revision 1.1.1.1.2.1 1998/11/11 23:14:44 nevil * Only include malloc.h if we HAVE_MALLOC_H * * Revision 1.1.1.1 1998/10/28 20:31:27 nevil * Import of NeTraMet 4.3b1 * * Revision 1.1.3.1.2.3 1998/10/27 04:09:03 nevil * Modified OCX defines for 'flat memory' testing for 32-bit DOS * meters. Changed some data defines to allow p2primes[] comparisons * to work properly for 16-bit DOD meter * * Revision 1.1.3.1.2.2 1998/10/19 22:32:45 nevil * Meter improvements, mostly arising from developments for the * OCxMON meter. These are documented in notes_oc.txt * * Revision 1.1.3.1.2.1 1998/10/18 20:51:19 nevil * Added Nicolai's patches, some 'tidying up' of the source * * Revision 1.1.3.2 1998/10/14 04:53:22 nevil * Merge Nicolai's patches into 4.2.1 distribution * * Revision 1.3 1998/07/21 00:40:14 rtfm * Implement popto/poptoact actions for SRL * * Revision 1.2 1998/05/22 03:57:35 rtfm * Implement better hashing algorithm for flow and rule tables */ #ifndef EXTFLOW #define EXTFLOW extern #define DECLARE 0 #define INIT(v) #else #define EXTFLOW #define DECLARE 1 #define INIT(v) = v #endif #ifndef MAX_SUBID #include "asn1.h" #endif #define MXRTBLS 20 /* Max nbr of rule tables */ #define MXCLCTRS 20 /* Max nbr of Meter Readers */ #define MXMANAGERS 10 /* Max nbr of Managers */ #define RSTKSIZ 50 /* Max depth of rule matches stack */ #define ESTKSIZ 50 /* Max depth of rule gosub stack */ #define MXRHTSZ 3727 /* Max size for rule-group hash table */ #define MNCGRPSZ 5 /* Min nbr of rules in a compare group */ #define RCHUNKSZ 250 /* Rule hash size is a multiple of this */ #define RTSLOPSZ 20 /* Nbr of extra rules to add into rule tables */ #define NAMESZ 16 /* Chars in a name (rulesets, readers, managers) */ #if defined(__LARGE__) #define FLOW_INDEX 1 #else #define FLOW_INDEX 0 #endif #if OCX_NTM || OC3_NTM || CR_DATA /* High-speed (OCx) version. Default maxima .. */ #define DFMXFLOWS 100000 /* Nbr of traffic flows */ #define MXMASKS 70 /* Nbrbr of (different) mask values */ #define DFMXRULES 2000 /* Nbr of rules (in all rulsets) */ #define DFMXSTRBLOCKS 500 /* Nbr of flows metering TCP streams */ #define DFMXSTREAMS 2000 /* Nbr of TCP streams */ #define DFMXDISTRIBS 20 /* Nbr of distributions */ #define DFMXDISTEVENTS 10 /* Nbr of events (times) for distributions */ #define DFMXPKTDATS 4000 /* Nbr of packets we hold data on */ #elif defined(__FLAT__) /* 32-bit PC version */ #define DFMXFLOWS 10000 #define MXMASKS 70 #define DFMXRULES 2000 #define DFMXSTRBLOCKS 500 #define DFMXSTREAMS 2000 #define DFMXDISTRIBS 20 #define DFMXDISTEVENTS 10 #define DFMXPKTDATS 4000 #elif defined(DOS) /* 16-bit PC version */ #define DFMXFLOWS 2000 #define MXMASKS 50 #define DFMXRULES 1000 #define DFMXSTRBLOCKS 20 #define DFMXSTREAMS 100 #define DFMXDISTRIBS 5 #define DFMXDISTEVENTS 5 #define DFMXPKTDATS 200 #else /* Unix version */ #define DFMXFLOWS 10000 #define MXMASKS 70 #define DFMXRULES 2000 #define DFMXSTRBLOCKS 500 #define DFMXSTREAMS 2000 #define DFMXDISTRIBS 100 #define DFMXDISTEVENTS 20 #define DFMXPKTDATS 4000 #endif EXTFLOW int trace_interval INIT(0); /* Collection interval for trace file */ EXTFLOW const char *crl_info INIT(""); /* Null if can't read trace file */ EXTFLOW unsigned long last_t_sec INIT(0); /* Unix seconds from timestamp of last merged packet */ #if CR_DATA || DAG_DIRECT #define CT_WAIT_RULES 0 #define CT_RULES_READY 1 #define CT_PROCESS_FLOWS 2 #define CT_WAIT_FLOWS_READ 3 #define CT_TRACE_EOF 4 #define CT_SHUTDOWN 5 EXTFLOW int trace_state INIT(CT_WAIT_RULES); /* Interlock with NeMaC -T */ #endif EXTFLOW struct flow **flow_ht; EXTFLOW Bit32 fthashmod; /* Use a single hash table for all rulesets. Nevil, 11 Sep 98 */ #if 1 /* v4 */ #define AT_DUMMY 0 /* Addr_type values */ #define AT_IP4 1 /* Address Family numbers */ #define AT_IP6 2 #define AT_CLNS 3 #define AT_OTHER 6 /* (includes all 802 media) */ #define AT_NOVELL 11 #define AT_ETHERTALK 12 #define AT_DECNET 13 #define AT_ETHERNET 7 /* ifType 'ethernet-like' [RFC1643] */ #define AT_TOKENRING 9 /* ifType IEEE802.5 */ #define AT_FDDI 15 /* ifType FDDI [RFC1285] */ #define AT_PPP 23 /* ifType ppp [RFC1471] */ #define AT_ATM 37 /* ifType ATM */ #define AT_SONET 39 /* ifType SONET or SDH */ #define AT_AAL5 49 /* ifType AAL5 over ATM */ #if CR_DATA #define AT_TRACE 255 /* CoralReef trace file */ #endif #define MX_PROTOCOLS AT_DECNET #else /* v3 */ #define AT_DUMMY 1 #define AT_IP 2 #define AT_CLNS 3 #define AT_IDPR 4 #define AT_DECNET 5 #define AT_NOVELL 6 #define AT_ETHERTALK 7 #define AT_DETAIL 8 #define AT_OTHER 12 #endif #define PT_ICMP 1 /* IP protocol types */ #define PT_TCP 6 #define PT_UDP 17 #define PT_GRE 47 /* RFC 1701/1702 */ #define PT_OSPF 89 /* RFC 1583 */ /* IPv6 Next Header values (RFC 2460) */ #define PT_6HOP 0 /* Hop-by-hop options */ #define PT_6ROUT 43 /* Routing (Type 0) */ #define PT_6FRAG 44 /* Fragment */ #define PT_6DEST 60 /* Destination options */ #define PT_6AH 51 /* Authentication (AH) RFC 2402 */ #define PT_6ESP 50 /* Encapsulating Security Payload (ESP) RFC 2406 */ #define PT_6ICMP 58 /* ICMPv6 */ #define PT_6NONH 59 /* No next header */ EXTFLOW int addr_len[] /* Lengths for each address type (bytes) */ #if DECLARE = { PEER_ADDR_LEN, /* 0 'Didn't save PeerType' or 'dummy' */ IP4_ADDR_LEN, /* 1 IP4 */ IP6_ADDR_LEN, /* 2 IP6 */ NSAP_ADDR_LEN, /* 3 CLNS */ 0, /* 4 */ 0, /* 5 */ TRANS_ADDR_LEN, /* 6 Other */ 0, /* 7 */ 0, /* 8 */ 0, /* 9 */ 0, /* 10 */ IPX_ADDR_LEN, /* 11 Novell IPX */ ET_ADDR_LEN, /* 12 EtherTalk */ DN_ADDR_LEN /* 13 DECnet */ } #endif ; EXTFLOW int addr_len32[] /* Lengths for each address type (32-bit words) */ #if DECLARE = { (PEER_ADDR_LEN+3)/4, /* 0 'Didn't save PeerType' or 'dummy' */ (IP4_ADDR_LEN+3)/4, /* 1 IP4 */ (IP6_ADDR_LEN+3)/4, /* 2 IP6 */ (NSAP_ADDR_LEN+3)/4, /* 3 CLNS */ 0, /* 4 */ 0, /* 5 */ (TRANS_ADDR_LEN+3)/4, /* 6 Other */ 0, /* 7 */ 0, /* 8 */ 0, /* 9 */ 0, /* 10 */ (IPX_ADDR_LEN+3)/4, /* 11 Novell IPX */ (ET_ADDR_LEN+3)/4, /* 12 EtherTalk */ (DN_ADDR_LEN+3)/4 /* 13 DECnet */ } #endif ; EXTFLOW char *proto_names[] #if DECLARE = { "", /* 0 */ "IPv4", /* 1 IP4 */ #if V6 "IPv6", /* 2 IP6 */ #else "", /* 2 IP6 */ #endif #if CLNS "CLNS", /* 3 CLNS */ #else "", /* 3 CLNS */ #endif "", /* 4 */ "", /* 5 */ "Other", /* 6 Other */ "", /* 7 */ "", /* 8 */ "", /* 9 */ "", /* 10 */ "Novell IPX", /* 11 Novell IPX */ "EtherTalk", /* 12 EtherTalk */ "DECnet IV", /* 13 DECnet */ } #endif ; EXTFLOW int use_ip_length INIT(0); EXTFLOW int proto_reqd[1+MX_PROTOCOLS]; /* 1 => protocol used by rules */ EXTFLOW int adj_reqd; /* 1 => adjacent addresses used by rules */ #if NF_OCX_BGP EXTFLOW int asn_lookup INIT(0); /* 1 => ASNs used by rules */ #endif EXTFLOW Bit32 mxdistribs, mxdistevents; #if NEW_ATR struct event { struct event *next; Bit32 t; int interval; struct distribution *dp; }; EXTFLOW struct event eventq #if DECLARE = {NULL, 0L, 0, NULL} #endif ; EXTFLOW struct event *events, /* Space for events */ *free_events; EXTFLOW Bit32 n_free_events INIT(0); #define WNP_FTPDATA 20 /* Well-known tcp/udp port numbers */ #define WNP_FTP 21 #define WNP_TELNET 23 #define WNP_SMTP 25 #define WNP_DOMAIN 53 #define WNP_WWW 80 #define WNP_NNTP 119 #define WNP_NTP 123 #define WNP_SNMP 161 #define PP_NO_TEST 0 /* Packet-Pairs for TurnaroundTimes */ #define PP_ICMP_ECHO 1 #define PP_ICMP_TIMSTMP 2 #define PP_OTHER 7 /* Just build streams (for InterarrivalTimes) */ #define PP_UDP_DNS 11 #define PP_UDP_ECHO 12 #define PP_UDP_SNMP 13 #define PP_TCP 0xC0 /* (=192) Low-order bits as follows .. */ #define PP_OK_SYNACK 0x01 /* ->SYN, <-SYN+ACK pairs */ #define PP_OK_SYNRST 0x02 /* ->SYN, <-SYN+RST pairs */ #define PP_OK_MULTI 0x08 /* ->DATA, <-ACK for more than one packet */ #define PP_OK_SINGLE 0x10 /* ->DATA, <-ACK for single packets */ #define PP_OK_INGROUP 0x20 /* ->DATA, <-ACK for packets within a group */ struct peer_addrs { Bit8 SrcPeerAddr[PEER_ADDR_LEN], DestPeerAddr[PEER_ADDR_LEN]; }; struct pktdata { struct pktdata *next; double ts; /* Time (microseconds) meter saw the packet */ Bit16 pkt_len; /* Bytes (on the wire) in packet */ Bit8 direction, /* MFWD or MREV */ pp_type; /* Packet-Pair type (from defines above) */ union { struct { struct peer_addrs pa; Bit16 ident; Bit16 sequence; } icmp; union { struct { struct peer_addrs pa; Bit16 ident; /* Set by requestor */ } dns; struct { } snmp; } udp; struct { Bit32 ack, /* TCP ACK for this packet */ exp_seq; /* TCP SEQ + TCP data len */ Bit16 d_len, /* Nbr of TCP data bytes in packet */ pkt_nbr; /* Index of packet in stream */ /* send_win, /* Window advertised in this pkt */ /* recv_win; /* Space in receiver window (from last ACK) */ Bit8 flags; /* TCP flags for this packet */ } tcp; } pi; }; EXTFLOW struct pktdata *packet_data, /* Space for packet data blocks */ *free_pkt_dat; EXTFLOW Bit32 n_free_pktdata INIT(0); EXTFLOW Bit32 PktsCreated INIT(0), PktsRecovered INIT(0); #define DISTRIB_PARAM_LEN 6 #define MXBUCKETS 100 struct distribution { Bit32 counts[MXBUCKETS+1]; Bit8 non_empty, /* Sum of counts[] >= 1 */ selector, /* Attribute number */ mask_params[DISTRIB_PARAM_LEN], value_params[DISTRIB_PARAM_LEN]; double M; /* Range, for transform() */ Bit8 Transform, ScaleFactor; /* 'mask' parameters */ Bit16 LowerLimit, UpperLimit; Bit8 Buckets, Parameter1; /* 'value' parameters */ Bit16 Parameter2, Parameter3; int n_values, /* Number of points in 'dynamic' distribution */ lowerlim, upperlim, /* Specified by user */ min_val, max_val; /* Observed in data */ int trainlength, last_was_in_train; /* Experimental, May 01 */ struct flow *fp; /* Flow creating distrib */ struct distribution *next; /* Chain of distribs for the flow */ struct distribution *nrate; /* Chain of distribs for computing rates */ }; #define DS_NULL 0 /* Distribution transform type values */ #define DS_LIN 1 /* Linear */ #define DS_LOG 2 /* Logarithmic */ /* "Dynamic" distributions: Collects actual values until trigger point reached, then sets lower and upper parameters from data. Data values (actual and buckets) are **not** SNMP counters. Instead they are cleared after being read. */ #define DS_DYN_REQ 4 /* Dynamic: request */ #define DS_DYN_PTS 5 /* Dynamic: values (Buckets = nbr of values) */ #define DS_DYN_BKT 6 /* Dynamic: bucket counts (limits set from data */ #define PP_Type Parameter1 /* For To/From Turnaround (Bit8) */ #define RateInterval Parameter1 /* For To/From Bit/PDU Rate (Bit8) */ /* TCP Size/Rate filter parameters .. */ #define SizeScale Parameter1 /* Filter scale factor (Bit8) */ #define LowerSize Parameter2 /* Ignore if <= Lower (Bit16) */ #define UpperSize Parameter3 /* Ignore if > Upper (Bit16) */ EXTFLOW struct distribution *distribs, /* Space for distributions */ *free_distribs; EXTFLOW Bit32 n_free_distribs INIT(0); #endif /* NEW_ATR */ EXTFLOW Bit32 mxstreams, mxstr_blocks, mxpktdatas; #if NEW_ATR #define ToFINseen 0x01 #define FromFINseen 0x02 #define BothFINseen (FromFINseen | ToFINseen) #define ToSYNseen 0x04 #define FromSYNseen 0x08 #define BothSYNseen (FromSYNseen | ToSYNseen) #define RSTseen 0x10 #define TCP_STREAM_TIMEOUT 200 /* 200 cs = 2s (FIN_WAIT) */ #define OTHER_STREAM_TIMEOUT 1000 /* 10s */ #define STO_MULTIPLIER 10; /* Was 20 */ # if TCP_PKT_TRACE # define TRACE_SZ 20 # define sess_Forward 0x40 # define sess_PktPrinted 0x80 /* Use flags_seen defines (above) for rest of s_flags byte */ struct trace_rec { Bit16 pkt_nbr; Bit16 time_int; Bit16 TCPlen; /* MSB = 1 for 'to,' 0 for 'from' */ Bit8 flags, s_flags; Bit32 Seq, maxSeq; }; struct sf_trace { double last_pkt_time; int pkt_nbr; int sf_trx; /* Index of next trace record to fill */ struct trace_rec tr[TRACE_SZ]; }; # endif /* TCP_PKT_TRACE */ struct stream_name { #if QBYTE_PEER Bit32 SrcPeerAddr, DestPeerAddr; #else Bit32 SrcPeerAddr[(PEER_ADDR_LEN+3)/4], DestPeerAddr[(PEER_ADDR_LEN+3)/4]; #endif Bit16 SrcTransAddr, DestTransAddr; #if WORDS_BIGENDIAN Bit16 rsv1; Bit8 TransType, RuleSet; #else Bit8 TransType, RuleSet; Bit16 rsv1; #endif }; struct stream { struct stream huge *next_hc, /* Streams in a hash chain */ /* Must be first item in structure to allow circular hash chains */ *next_sp, /* Streams for a flow, free list */ *prev_sp; /* Reverse stream chain for flow */ double /* Time (microseconds) of STREAM's last packet in each direction */ LastToTime, LastFromTime, StrFirstTime; /* First packet time in micrtoseconds */ struct pktdata *pq; /* Recent packets for this stream */ Bit16 pkt_nbr; /* Nbr of pkts seen for this stream */ Bit16 pq_len; /* Packets in the queue */ Bit16 mx_pq_len; /* Max allowed packets in queue */ Bit8 ToSeen, FromSeen; /* Set when 'to' or 'from' packet seen */ Bit8 /* TCP things */ flags_seen, terminating, ToSeq_seen, FromSeq_seen, ToAck_seen, FromAck_seen; Bit8 rsv1, rsv2; Bit32 ToLastSeq, FromLastSeq, ToLastAck, FromLastAck, ToSeqOctets, FromSeqOctets, ToAckOctets, FromAckOctets; Bit32 /* Flow things */ ToPDUs, FromPDUs, /* We hope that these won't wrap, at */ ToOctets, FromOctets; /* least not for streams within a flow */ Bit32 /* uptime() when first and last packets seen for stream */ FirstTime, LastTime; /* FromWindow, ToWindow; */ struct flow *flowp; # if TCP_TRACE int sf_nbr; # endif # if TCP_PKT_TRACE struct sf_trace sft; # endif struct stream_name sfn; /* IP address and port pairs */ /* Have this last so can zero everything else */ }; EXTFLOW struct stream *sfa, /* Space for streams */ *free_streams; EXTFLOW Bit32 n_free_streams INIT(0); EXTFLOW struct stream **sfht; /* Stream hash table */ EXTFLOW Bit32 sfhashmod; EXTFLOW Bit32 StreamsCreated INIT(0), StreamsRecovered INIT(0); struct stream_data { /* For all IP flows with stream attributes */ struct stream_data *next; /* stream_data free list */ struct stream huge *sq, /* Streams for this flow, increasing FirstTime order */ *sq_tail; /* Tail of stream queue */ double U; /* Packets counted as lost after U centiseconds */ Bit32 n_streams, /* Total nbr of streams seen */ terminating_streams, active_streams, mx_active_streams, ToTCPDecrSeq, FromTCPDecrSeq, ToLostPDUs, FromLostPDUs, /* Detected via PP turnaround, or by timeouts or max pq_len restrictions */ ToPQOverflows, FromPQOverflows; /* max pq_len restrictions PQOF */ counter64 ToTCPSeqOctets, FromTCPSeqOctets, /* Last-First Seq nbrs */ ToTCPAckOctets, FromTCPAckOctets, /* Last-First Ack nbrs */ ToTCPLenOctets, FromTCPLenOctets; /* Sum of TCP data lengths */ double /* Time (microseconds) of FLOW's last packet in each direction */ LastToTime, LastFromTime; Bit8 ToSeen, FromSeen; /* Set when 'to' or 'from' packet seen */ Bit8 pp_match_reqd; /* Distrib list includes a turnaround attribute */ }; EXTFLOW struct stream_data *strb, /* Space for stream_data blocks */ *free_str_blocks; EXTFLOW Bit32 n_free_str_blocks INIT(0); #endif /* NEW_ATR */ #if NF_OCX_BGP EXTFLOW int use_owner_asns INIT(0); #endif struct key { union address PeerAddress; Bit32 AdjAddr_ms4; Bit16 AdjAddr_ls2; Bit16 TransAddress; Bit8 PeerMaskVal, TransMaskVal, AdjMaskVal, rsv1; Bit8 AdjAddrType, Interface, Class, Kind; #if NF_ASN_ATT Bit16 RouteASN; Bit8 ASNMaskVal, RoutePrefix; #endif }; struct flow_key { struct key Low, High; Bit8 PeerAddrType, TransAddrType; Bit8 FlowClass, FlowKind, MeterId, DSCodePoint; Bit8 rsv1, rsv2; /* Bit32-align keys */ }; struct flow { struct flow *ht_next; /* For hash chains */ /* Must be first item in structure to allow circular hash chains */ Bit32 rs_next; /* For ruleset chains */ struct flow_key fk; counter64 UpOctets,UpPDUs, DownOctets,DownPDUs; Bit32 FirstTime,LastTime; #if NF_CISCO_DATA Bit32 ntm_LastTime; /* Needed for TimeFiltering and garbage collecting */ #else #define ntm_LastTime LastTime #endif Bit8 FlowRuleSet; /* (1-org) index of set which created this flow */ /* Active flows are linked into hash chains, i.e. they have non-null 'next' fields */ #if NEW_ATR Bit32 distrib_bits; /* One bit set for each attribute counted */ struct distribution *distrib_list; counter64 /* For short-term bit rates */ LastUpOctets,LastUpPDUs, LastDownOctets,LastDownPDUs; struct stream_data *stdata; /* Each stream has its own packet queue */ #endif }; EXTFLOW Bit32 nflows, /* Nbr of flows in use */ mxflows; /* Max nbr of flows (i.e. size of flow table) */ EXTFLOW struct flow *fa; /* Space for flows */ #define flow_nbr(f) ((f-fa) + 1) /* Compiler does the /sizeof() ! */ EXTFLOW Bit32 /* Queue of free flows */ free_flow_head, free_flow_tail; /* States of entries in flow table: Idle = May be used for a new flow Inactive = Has been read, may be garbage collected Orphan = Not in hash table, (not running), waiting to be read Active = Ruleset running, waiting to be read */ #define flow_orphan(fp) (fp->ht_next == NULL) #define mark_orphan(fp) fp->ht_next = NULL #if FLOW_INDEX EXTFLOW struct flow **flow_ix; /* The flow table */ /* Flow 1 was a dummy for the Create and Active tables in v3 */ #define flow_idle(n) (flow_ix[n-1] == NULL) #define mark_idle(n) flow_ix[n-1] = NULL #else /* !FLOW_INDEX */ #define flow_idle(n) (fa[n-1].FlowRuleSet == 0) void mark_idle(Bit32 n); #endif EXTFLOW Bit32 empty_ix; /* Last flow number used by number_flow */ EXTFLOW Bit32 gcf_ix; /* Next possible flow for garbage collector */ EXTFLOW int /* Parameters for garbage collector */ gc_interval INIT(10), /* Seconds between calls */ gc_f INIT(4), /* Flow indexes to test each call */ already_complained INIT(0); /* True if GC knows there are no free flows */ EXTFLOW Bit32 GarbageCollectTime INIT(0), /* OK to recover flows with LastTime greater than this */ FlowsCreated INIT(0), FlowsRecovered INIT(0); struct MaskVal { union address Val[RULE_ADDR_LEN]; }; EXTFLOW struct MaskVal Masks[MXMASKS] #if DECLARE = { # if CLNS { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} # elif V6 || FULL_IPX { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} # else /* v4 */ {0,0,0,0,0,0}, {255,0,0,0,0,0} # endif } #endif ; EXTFLOW int n_masks INIT(2); struct rule { union address RuleMatchedValue; /* Rule's MIB variables */ Bit8 RuleSelector; Bit8 RuleMaskVal; /* Index to Masks[] */ Bit16 RuleJumpIndex; Bit8 RuleAction; Bit8 push_rule; /* For build_search_key() */ Bit32 hash_tbl_index; /* For match: 0 => simple compare */ Bit32 hash_link; }; EXTFLOW struct rule *rule_space; /* Single space for all rulesets. Nevil, 14 Sep 98 */ EXTFLOW Bit32 mxrules, inuse_rules; EXTFLOW Bit16 *rule_hash_space; /* Single space for all rulesets. Nevil, 16 Sep 98 */ EXTFLOW Bit32 mxrulehash, inuse_rule_hash; EXTFLOW int tbl_size[5] /* Meter info table sizes */ /* 1.1 = rule, 1.2 = interface, 1.3 = reader, 1.4 = manager table */ #if DECLARE = {0, MXRTBLS, 1, MXCLCTRS, MXMANAGERS} #endif ; struct rtinf_rec { /* v4 */ Bit16 ri_Size; char ri_Owner[NAMESZ+1]; /* +1 for terminating null */ Bit32 ri_TimeStamp; int ri_Status; char ri_Name[NAMESZ+1]; Bit32 ri_FlowRecords; Bit32 ri_flow_chain; /* First flow in chain (1-org) */ Bit32 ri_rule_offset; struct rule *ri_rule_table; int ri_rule_hash_size; Bit32 ri_rule_hash_offset; Bit16 *ri_rule_hash; int ri_running; int next_running_rt; /* (1-org) index of next running ruleset */ int ri_old_status; Bit32 ri_gc_time; }; EXTFLOW struct rtinf_rec ri[MXRTBLS]; EXTFLOW int running_rts INIT(0); /* Chain of running rulesets */ EXTFLOW Bit16 c_rtx; /* Rule table index of current rule table */ EXTFLOW struct rule *c_rt; /* Current Rule Table */ EXTFLOW Bit16 c_rsz; /* Nbr of rules in current rule table */ EXTFLOW struct hash_tbl *c_ht; /* Current Hash Table */ EXTFLOW Bit16 *c_rht; /* Current Rule Hash Table */ struct rule_hash_tbl { Bit16 group_last; /* Nbr of last rule in group */ Bit16 hashmod; /* Group hash table size */ Bit16 hash_ent[1]; }; #define RA_IGNORE 1 /* RuleAction values */ #define RA_RETRY 2 #define RA_COUNT 3 #define RA_COUNTPKT 4 #define RA_RETURN 5 #define RA_GOSUB 6 #define RA_GOSUBACT 7 #define RA_ASSIGN 8 #define RA_ASSIGNACT 9 #define RA_GOTO 10 #define RA_GOTOACT 11 #define RA_PUSHTO 12 #define RA_PUSHTOACT 13 #define RA_PUSHPKTTO 14 #define RA_PUSHPKTTOACT 15 #define RA_POPTO 16 #define RA_POPTOACT 17 #define RS_NULL 0 /* Rule Selector dummy value */ #define FTFLOWINDEX 1 /* Flow table attribute values */ #define FTFLOWTIMEMARK 2 /* Added in 'Experimental RTFM' MIB */ /* Following attribs move up by 1 */ #define FTFLOWSTATUS 3 #define FTLOWINTERFACE 4 #define FTLOWADJACENTTYPE 5 #define FTLOWADJACENTADDRESS 6 #define FTLOWADJACENTMASK 7 #define FTLOWPEERTYPE 8 #define FTLOWPEERADDRESS 9 #define FTLOWPEERMASK 10 #define FTLOWTRANSTYPE 11 #define FTLOWTRANSADDRESS 12 #define FTLOWTRANSMASK 13 #define FTHIINTERFACE 14 #define FTHIADJACENTTYPE 15 #define FTHIADJACENTADDRESS 16 #define FTHIADJACENTMASK 17 #define FTHIPEERTYPE 18 #define FTHIPEERADDRESS 19 #define FTHIPEERMASK 20 #define FTHITRANSTYPE 21 #define FTHITRANSADDRESS 22 #define FTHITRANSMASK 23 #define FTPDUSCALE 24 #define FTOCTETSCALE 25 #define FTRULESET 26 #define FTUPOCTETS 27 #define FTUPPDUS 28 #define FTDOWNOCTETS 29 #define FTDOWNPDUS 30 #define FTFIRSTTIME 31 #define FTLASTTIME 32 #define FTLOWSUBSCRIBERID 33 #define FTHISUBSCRIBERID 34 #define FTSESSIONID 35 #define FTSOURCECLASS 36 #define FTDESTCLASS 37 #define FTFLOWCLASS 38 #define FTSOURCEKIND 39 #define FTDESTKIND 40 #define FTFLOWKIND 41 #define FTDSCODEPOINT 118 #if !NEW_ATR #define N_OLD_ATRS (FTFLOWKIND + 1) /* 1 DS attribute */ #define LASTATTRIB FTHIDSCODEPOINT /* May be redefined below */ #else #define FTTOLOSTPDUS 121 #define FTFROMLOSTPDUS 122 #define FTTOPQOVERFLOWS 123 /* PQOF */ #define FTFROMPQOVERFLOWS 124 #define N_OLD_ATRS (FTFLOWKIND + 1 + 4) /* DSCP + OverflowPDUs */ #define LASTATTRIB FTFROMPQOVERFLOWS /* May be redefined below */ #endif #define FTFORWARD 50 #define FTV1 51 #define FTV2 52 #define FTV3 53 #define FTV4 54 #define FTV5 55 #define USER_ATTRIB(a) (a >= FTV1 && a <= FTV5) #define N_METER_ATRS (FTV5+1 - FTFORWARD) #define N_VBLS (FTV5+1 - FTV1) /* Nbr of user variables */ #if !NEW_ATR #define N_DIST_ATRS 0 #else #define FTDISTRIBUTIONS 65 /* Bit set for each distribution in flow */ #define FTTOPACKETSIZE 66 #define FTFROMPACKETSIZE 67 #define FTTOINTERARRIVALTIME 68 #define FTFROMINTERARRIVALTIME 69 #define FTTOBITRATE 72 #define FTFROMBITRATE 73 #define FTTOPDURATE 74 #define FTFROMPDURATE 75 #define FTTOTCPTIME 76 #define FTFROMTCPTIME 77 #define FTTOTCPSIZE 78 #define FTFROMTCPSIZE 79 #define FTTOTCPRATE1 80 #define FTFROMTCPRATE1 81 #define FTTOTCPRATE2 82 #define FTFROMTCPRATE2 83 #define FTTOTURNAROUNDTIME1 70 #define FTFROMTURNAROUNDTIME1 71 #define FTTOTURNAROUNDTIME2 84 #define FTFROMTURNAROUNDTIME2 85 #define FTTOTURNAROUNDTIME3 86 #define FTFROMTURNAROUNDTIME3 87 #define FTTOTURNAROUNDTIME4 88 #define FTFROMTURNAROUNDTIME4 89 #if 0 #define FTTOTRAINLENGTH 88 #define FTFROMTRAINLENGTH 89 #endif #define FTTOFLOWOCTETS 90 #define FTFROMFLOWOCTETS 91 #define FTTOFLOWPDUS 92 #define FTFROMFLOWPDUS 93 #define FTFLOWTIME 94 #define LAST_DISTRIB FTFLOWTIME #define DISTRIB_ATTRIB(a) (a >= FTTOPACKETSIZE && a <= LAST_DISTRIB) #define N_DIST_ATRS (LAST_DISTRIB+1 - FTDISTRIBUTIONS) # if LASTATTRIB < LAST_DISTRIB # undef LASTATTRIB # define LASTATTRIB LAST_DISTRIB /* max(basic, dist) */ # endif #define TURNAROUND_ATTRIB(a) ( \ a == FTTOTURNAROUNDTIME || a == FTFROMTURNAROUNDTIME || \ (a >= FTTOTURNAROUNDTIME2 && a <= FTFROMTURNAROUNDTIME5) ) #endif #if NF_ASN_ATT || NF_OTHER_ATT #define FTMETERID 112 #define FTLOWROUTEASN 113 #define FTLOWROUTEPREFIX 114 #define FTHIROUTEASN 115 #define FTHIROUTEPREFIX 116 #define NF_ATTRIB(a) (a >= FTMETERID && a <= FTHIASWIDTH) #define N_NF_ATRS (FTHIASPREFIX+1 - FTMETERID) #else #define N_NF_ATRS 0 #endif #if !NEW_ATR # define N_TCP_ATRS 0 #else # define FTTCPDATA 125 # define N_TCP_ATRS 1 # if LASTATTRIB < FTTCPDATA # undef LASTATTRIB # define LASTATTRIB FTTCPDATA /* max(basic, dist, nf, tcp) */ # endif #endif /* NEW_ATR */ #define N_ATTRIBS (N_OLD_ATRS + N_METER_ATRS + N_DIST_ATRS \ + N_NF_ATRS + N_TCP_ATRS) EXTFLOW Bit8 dist_atr[LASTATTRIB+1], /* Distribution-valued */ stream_atr[LASTATTRIB+1]; /* Needs to handle streams */ struct attrib_info { Bit8 attr, /* Attribute number */ distrib, stream; }; EXTFLOW struct attrib_info attribs[] #if DECLARE = { #if defined(NEW_ATR) FTTOPACKETSIZE, 1, 0, FTFROMPACKETSIZE, 1, 0, FTTOBITRATE, 1, 0, FTFROMBITRATE, 1, 0, FTTOPDURATE, 1, 0, FTFROMPDURATE, 1, 0, FTTOINTERARRIVALTIME, 1, 1, FTFROMINTERARRIVALTIME, 1, 1, FTTOTURNAROUNDTIME1, 1, 1, FTFROMTURNAROUNDTIME1, 1, 1, FTTOTURNAROUNDTIME2, 1, 1, FTFROMTURNAROUNDTIME2, 1, 1, FTTOTURNAROUNDTIME3, 1, 1, FTFROMTURNAROUNDTIME3, 1, 1, FTTOTURNAROUNDTIME4, 1, 1, FTFROMTURNAROUNDTIME4, 1, 1, FTTOTCPTIME, 1, 1, FTFROMTCPTIME, 1, 1, FTTOTCPSIZE, 1, 1, FTFROMTCPSIZE, 1, 1, FTTOTCPRATE1, 1, 1, FTFROMTCPRATE1, 1, 1, FTTOTCPRATE2, 1, 1, FTFROMTCPRATE2, 1, 1, FTTOFLOWOCTETS, 1, 1, FTFROMFLOWOCTETS, 1, 1, FTTOFLOWPDUS, 1, 1, FTFROMFLOWPDUS, 1, 1, FTFLOWTIME, 1, 1, FTTCPDATA, 0, 1, /* Not a distrib, but uses streams */ # endif 0, 0, 0 /* End marker */ } #endif ; /* Global Variables */ EXTFLOW int /* Performance statistics */ n_hash_ents INIT(0), n_matches INIT(0), n_hash_compares INIT(0), n_hash_searches INIT(0); EXTFLOW int kb_enabled; EXTFLOW int display_enabled; /* Signed comparisons of Bit32 a and Bit32 b */ #define scmp32(a,b) (a == b ? 0 : ((Bit32)(a-b) <= 0x80000000 ? +1 : -1)) #define scmp32_ge(a,b) ((Bit32)(a-b) <= 0x80000000) /* True if a >= b */ #define scmp32_lt(a,b) ((Bit32)(a-b) > 0x80000000) /* True if a < b */ /* counter64 declared in snmplib\asn1.h */ #if SIZEOF_LONG_LONG == 8 || SIZEOF_LONG == 8 #define add_Bit32_to_counter64(c,u) { \ c += (Bit32)(u); \ } #define incr_counter64(c) { \ ++c; \ } #define subtr64(r64, c64,x64) { \ r64 = c64 - x64; \ } #define assign64(x64,y64) { \ x64 = y64; \ } #define c64geint(x64,i) (x64 >= i) #define doublefrom64(x64) (double)(x64) #define setzero64(x64) x64 = 0 #elif SIZEOF_LONG == 4 #define add_Bit32_to_counter64(c,u) { \ c64arg = c.low; if ((c.low += (Bit32)(u)) < c64arg) ++c.high; \ } #define incr_counter64(c) { \ c64arg = c.low; if (++c.low < c64arg) ++c.high; \ } #define subtr64(r64, c64,x64) { \ if ((r64.low = c64.low - x64.low) > c64.low) \ r64.high = c64.high -1 - x64.high; \ else r64.high = c64.high - x64.high; \ } #define assign64(x64,y64) { \ x64.high = y64.high; x64.low = y64.low; \ } #define c64geint(x64,i) (x64.high != 0 ? 1 : (x64.low >= i)) #define doublefrom64(x64) (double)(x64.low) /* CAUTION: this assumes x64 fits in 32 bits */ #define setzero64(x64) x64.high = x64.low = 0 #else #error sizeof(long) not 4 or 8 <<<<<<<< #endif EXTFLOW unsigned long c64arg; /* Work variable for defines above */ #define TV_TRUE 1 /* TruthValues (SNMP, from RFC 1903) */ #define TV_FALSE 2 #define RS_ACTIVE 1 /* RowStatus (ditto) */ #define RS_NOTINSERVICE 2 #define RS_NOTREADY 3 #define RS_CREATEANDGO 4 #define RS_CREATEANDWAIT 5 #define RS_DESTROY 6 #define RS_UNUSED 0 /* Row not yet created by a manager */ #define RS_SET_CREATE 9 /* Set by RESERVE2 while creating a row */ /* MIB variables */ EXTFLOW int InactivityTimeout INIT(600L); /* 10 minutes */ EXTFLOW int HighWaterMark INIT(65); /* 65 % */ EXTFLOW int FloodMark INIT(95); /* 95 % */ EXTFLOW int FloodMode INIT(TV_FALSE); struct rdr_rec { int ci_Timeout; char ci_Owner[NAMESZ+1]; Bit32 ci_LastTime; Bit32 ci_PrevTime; int ci_Status; int ci_RuleSet; Bit32 ci_MinPDUs, ci_TimeMark; /* For nifty */ int ci_old_status; struct rdr_rec *ci_rs_next; /* rs_rdr chains */ }; EXTFLOW struct rdr_rec ci[MXCLCTRS]; EXTFLOW struct rdr_rec *rs_rdr[MXRTBLS]; /* Ruleset -> cip (for nifty) */ EXTFLOW unsigned long pcap_LostPackets INIT(0); EXTFLOW unsigned long noflowpackets INIT(0); struct mgr_rec { /* v4 */ int mi_CurrentRuleSet; int mi_StandbyRuleSet; int mi_HighWaterMark; char mi_Owner[NAMESZ+1]; Bit32 mi_TimeStamp; int mi_Status; int mi_RunningStandby; int mi_old_status; }; EXTFLOW struct mgr_rec mi[MXMANAGERS]; /* Meter outer block functions */ void startup_screen(void); void show_meter_time(void); void one_second_process(void); void bump_noflowpkts(int if_nbr); unsigned long iface_info(int if_nbr, int which); /* Flowhash functions */ void pkt_extract(struct pkt *bp, const int type, const Bit8 *hdrp, const int hl); void other_extract(struct pkt *bp, const Bit16 ethertype, const Bit16 lsap); int handle_pkt(struct pkt *pp, const Bit16 ether_type, const Bit16 lsap, const Bit8 *ethp, const Bit8 *p, const int pl); void free_flow(struct flow *q); #if NEW_ATR struct distribution *get_dist(void); void free_dist(struct distribution *d); struct event *get_event(void); void free_event(struct event *e); void check_rates(Bit32 now); void unlink_distrib_from_event(struct distribution *d); struct pktdata *get_pktdata(void); void free_pktdata(struct pktdata *pd); struct stream *get_stream(void); void free_stream(struct stream *sf); struct stream_data *get_st_data(void); void free_st_data(struct stream_data *sdp); void terminate_all_streams(struct flow *fp, struct stream_data *sdp); void terminate_stream(struct stream_data *sdp, struct stream *sp); void tcp_stream_stats(struct flow *fp, struct stream_data *sdp, struct stream *sp); void check_tcp_idle_streams(struct flow *fp, int gc_call); int tcp_stream_update(struct flow *fp, struct stream *sp, const struct pktdata *pd); int tcp_turnaround(int *pp_type, double *delta_us, struct flow *fp, struct stream *sp, struct pktdata *tp); void flow_stream_stats(struct flow *fp, struct stream_data *std, struct stream *sp); void check_other_idle_streams(struct flow huge *fp); void other_stream_update(struct flow *fp, struct stream *sp, struct pktdata *tp); struct stream *find_stream(struct flow *fp, int *flow_order, struct pkt *bp, double at_us); #endif int optimise_rule_table(int rs); void empty_hash_chain(int rs); void open_rule_set(int n, int open_rs); Bit32 number_flow(void); int garbage_collect(int incremental); void more_garbage(void); Bit32 active_flows(void); struct flow *find_flow(Bit32 x); void pkt_monitor(struct pkt *bp); void show_stats(void); void show_time(void); void init_monitor(int n_interfaces); void show_help(void); void handle_kb(int ch); void unpack_at_node(Bit8 *ap, const Bit8 *at_net, const Bit8 at_node); void unpack_dn_node(Bit8 *ap, const Bit8 *dn_addr); void save_time(void); void zero_stats(int show_msg); void open_log(void); /* Debug functions */ void quack(int x); /* Functions in met_vars.c */ void log_msg(int priority, int die, char *fmt, ...); int alloc_rulespace(int rs, int rules, Bit16 size); int free_rulespace(int rs);