/* 1547, Sat 19 May 01 (PST)

   NMC.H:  Global declarations for the NeTraMet Manager/Collector

   Copyright (C) 1992-2002 by Nevil Brownlee,
   CAIDA | University of Auckland */

/*
 * $Log: nmc.h,v $
 * Revision 1.1.1.2.2.12  2002/02/23 01:57:20  nevil
 * Moving srl examples to examples/ directory.  Modified examples/Makefile.in
 *
 * Revision 1.1.1.2.2.10  2001/05/24 02:19:43  nevil
 * LfapMet implemented by Remco Poortinga.
 * MinPDUs implemented by Nevil.
 *
 * Revision 1.1.1.2.2.7  2000/11/29 21:40:09  nevil
 * Bug fixes for stream / packet queue handling
 *
 * Revision 1.1.1.2.2.6  2000/08/08 19:44:45  nevil
 * 44b8 release
 *
 * Revision 1.1.1.2.2.4  2000/06/06 03:38:11  nevil
 * Combine NEW_ATR with TCP_ATR, various bug fixes
 *
 * Revision 1.1.1.2.2.1  2000/01/12 02:57:04  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  1999/10/03 21:06:17  nevil
 * *** empty log message ***
 *
 * Revision 1.1.1.1.2.11  1999/09/24 02:58:36  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.10  1999/09/22 05:38:36  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.9  1999/09/14 00:46:46  nevil
 * 4.3 Release ..
 *  - Implement -D option to run NeMaC as a daemon
 *  - Tidy up the on-line help displays
 *  - Make IPv4 the default PeerType for sfmt_attribute()
 *
 * Revision 1.1.1.1.2.8  1999/05/25 22:30:50  nevil
 * Make sure IPv6 managers interwork properly with IPv4 meters
 * - Determine meter's RULE_ADDR_SIZE by reading mask from rule 1
 *   of default ruleset.
 * - Print warning if meter rulesize < manager rulesize.
 * - Use smaller of these when downloading rules.
 *
 * Revision 1.1.1.1.2.7  1999/05/18 03:36:25  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.6  1999/02/03 04:41:42  nevil
 * Implementation of TCP attributes, part 5
 *
 * Revision 1.1.1.1.2.5  1999/01/27 04:26:13  nevil
 * Minor corrections to fix compiler warnings
 *
 * Revision 1.1.1.1.2.4  1999/01/20 04:01:33  nevil
 * Implementation of TCP attributes, part 4
 *
 * Revision 1.1.1.1.2.3  1999/01/08 01:38:30  nevil
 * Distribution file for 4.3b7
 *
 * Revision 1.1.1.1.2.2  1998/11/25 03:33:23  nevil
 * Implement tcpdata (part 2)
 *
 * Revision 1.1.1.1.2.1  1998/11/17 23:28:18  nevil
 * Implement DS attributes SourceDScodepoint(118), DestDScodepoint(119)
 * and (experimental) TCP attribute TCPdata(121)
 *
 * Revision 1.1.1.1  1998/11/16 03:22:00  nevil
 * Import of release 4.3b3
 *
 * Revision 1.1.1.1  1998/10/28 20:31:24  nevil
 * Import of NeTraMet 4.3b1
 *
 * Revision 1.1.3.2  1998/10/18 23:44:09  nevil
 * Added Nicolai's patches, some 'tidying up' of the source
 *
 * Revision 1.1.3.1  1998/10/13 02:48:22  nevil
 * Import of Nicolai's 4.2.2
 *
 * Revision 1.1.1.1  1998/08/24 12:09:28  nguba
 * NetraMet 4.2 Original Distribution
 *
 * Revision 1.8  1998/07/21 00:43:57  rtfm
 * Change attrib numbers for 'New Attribs' I-D
 * First release version of SRL
 */

#ifndef EXTERN
#define EXTERN  extern
#define DECLARE  0
#define INIT(v)
#else
#define EXTERN
#define DECLARE  1
#define INIT(v)  = v
#endif

#define CFGFILE  "NeMaC.cfg"
#define RULEFILE "rules.txt"
#define LOGFILE  "NeMaC.log"
#define FLAGFILE "NeMaC.flag"

#define MXRIROWS 20  /* NeTraMet: max rows in info tables */
#define MXCIROWS 20
#define MXMIROWS 10

extern int errno;

EXTERN int snmp_dump_packet INIT(0);

EXTERN int verbose, testing, listrules, standard, utc_time;

#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
EXTERN int trace_state INIT(CT_WAIT_RULES);  /* Interlock with NeTraMet -T */

#define MAC_ADDR_LEN     6  /* Address lengths */

#define IP4_ADDR_LEN     4
#define IP6_ADDR_LEN    16
#define DN_ADDR_LEN      3
#define ET_ADDR_LEN      3
#ifdef FULL_IPX
#define IPX_ADDR_LEN    10
#else
#define IPX_ADDR_LEN     4
#endif
#define NSAP_ADDR_LEN   20

#define TRANS_ADDR_LEN  2

#if CLNS
# define PEER_ADDR_LEN  NSAP_ADDR_LEN
# define RULE_ADDR_LEN  NSAP_ADDR_LEN
#elif V6 || FULL_IPX
# define PEER_ADDR_LEN   IP6_ADDR_LEN
# define RULE_ADDR_LEN   IP6_ADDR_LEN
#else  /* v4 */
# define PEER_ADDR_LEN   IP4_ADDR_LEN
# define RULE_ADDR_LEN   MAC_ADDR_LEN
#endif

EXTERN char addr_len[]  /* Lengths for each address type */
#if DECLARE
   = {
      IP4_ADDR_LEN,     /*  0 'Didn't save PerType' 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
   ;

EXTERN char addr_len3[]  /* Lengths for each address type */
#if DECLARE
   = {
      PEER_ADDR_LEN,   /*  0 Default */
      MAC_ADDR_LEN,    /*  1 Adjacent */
      IP4_ADDR_LEN,    /*  2 IP */
      NSAP_ADDR_LEN,   /*  3 CLNS */
      4,               /*  4 IDPR */
      DN_ADDR_LEN,     /*  5 DECnet */
      IPX_ADDR_LEN,    /*  6 Novell IPX */
      ET_ADDR_LEN,     /*  7 EtherTalk */
      TRANS_ADDR_LEN,  /*  8 Detail */
      MAC_ADDR_LEN,    /*  9 */
      MAC_ADDR_LEN,    /* 10 */
      IP4_ADDR_LEN,    /* 11 IP fragments */
      TRANS_ADDR_LEN   /* 12 Other */
      }
#endif
   ;

EXTERN char old_addr_type[]  /* v4 to v3 AddressType translation */
#if DECLARE
   = {
      0,                /*  0 */
      2,                /*  1 IP4 */
      0,                /*  2 IP6 */
      3,                /*  3 CLNS */
      0,                /*  4 */
      0,                /*  5 */
      12,               /*  6 Other */
      0,                /*  7 */
      0,                /*  8 */
      0,                /*  9 */
      0,                /* 10 */
      6,                /* 11 Novell IPX */
      7,                /* 12 EtherTalk */
      5,                /* 13 DECnet */
      }
#endif
   ;

EXTERN char new_addr_type[]  /* v3 to v4 AddressType translation */
#if DECLARE
   = {
      0,               /*  0 Default */
      0,               /*  1 Adjacent */
      1,               /*  2 IP */
      3,               /*  3 CLNS */
      0,               /*  4 IDPR */
      13,              /*  5 DECnet */
      11,              /*  6 Novell IPX */
      12,              /*  7 EtherTalk */
      0,               /*  8 Detail */
      0,               /*  9 */
      0,               /* 10 */
      1,               /* 11 IP fragments */
      6,               /* 12 Other */
      }
#endif
   ;

#if NEW_ATR
#define DIST_PARAM_LEN  6
#define MXBUCKETS     100
struct distribution {
   unsigned char selector,  /* Attribute number */
      mask_params[DIST_PARAM_LEN], value_params[DIST_PARAM_LEN];
   unsigned int counts[MXBUCKETS+1];

   unsigned char Transform, ScaleFactor; /* 'mask' parameters */
   unsigned int LowerLimit, UpperLimit;
   unsigned char Buckets, Parameter1;  /* 'value' parameters */
   unsigned int Parameter2, Parameter3;

   struct distribution *next;
   };
#define DS_NULL     0  /* Distribution transform type values */
#define DS_LIN      1
#define DS_LOG      2
#define DS_DYN_REQ  4  /* Dynamic: request */
#define DS_DYN_PTS  5  /* Dynamic: values (Buckets = nbr of values) */
#define DS_DYN_BKT  6  /* Dynaynmic: bucket counts (limits set from data */

struct subflow_data {
   int valid;  /* Set by asn_parse_tcp_data */
   Bit32
      n_subflows, mx_active_subflows,
      ToTCPDecrSeq, FromTCPDecrSeq;
   counter64
      ToTCPLenOctets, FromTCPLenOctets,
      ToTCPSeqOctets, FromTCPSeqOctets,
      ToTCPAckOctets, FromTCPAckOctets;
   };
#endif  /* NEW_ATR */

#define ADJ_ADDR    1  /* Address attribute types */
#define PEER_ADDR   2
#define TRANS_ADDR  3

struct flow_info {  /* Accounting flow as viewed by NeMaC */
   unsigned int FlowIndex;
   unsigned char LowInterface, HighInterface;
   unsigned char LowAdjType, HighAdjType,
      LowAdjAddress[MAC_ADDR_LEN], LowAdjMask[MAC_ADDR_LEN],
      HighAdjAddress[MAC_ADDR_LEN], HighAdjMask[MAC_ADDR_LEN];
   unsigned char 
      LowPeerType, HighPeerType,
      LowPeerAddress[NSAP_ADDR_LEN], LowPeerMask[NSAP_ADDR_LEN],
      HighPeerAddress[NSAP_ADDR_LEN], HighPeerMask[NSAP_ADDR_LEN];
   unsigned char 
      LowTransType, HighTransType,
      LowTransAddress[TRANS_ADDR_LEN], LowTransMask[TRANS_ADDR_LEN],
      HighTransAddress[TRANS_ADDR_LEN], HighTransMask[TRANS_ADDR_LEN];
   unsigned char
      SourceClass, DestClass, SourceKind, DestKind;
   unsigned char FlowStatus, FlowRuleSet, FlowClass, FlowKind;
   unsigned int DSCodePoint;
#if defined(NETFLOW)
   unsigned char 
      LowRouteASN[TRANS_ADDR_LEN], HighRouteASN[TRANS_ADDR_LEN],
      LowRoutePrefix, HighRoutePrefix,  MeterId;
#endif
   counter64
      FwdPackets,FwdBytes,  BackPackets,BackBytes;
   unsigned long
      FirstTime,LastTime;
#ifdef NEW_ATR
   Bit32 distrib_bits;  /* One bit set for each attribute counted */
   struct distribution *distrib_list;
   Bit32 ToLostPDUs, FromLostPDUs,
      ToPQOverflows, FromPQOverflows;
   struct subflow_data *sfd;
#endif  /* NEW_ATR */
   };

struct rule_info {
   int RuleSet, RuleNbr;
   int RuleSelector;
   unsigned char
      RuleMask[RULE_ADDR_LEN], RuleMatchedValue[RULE_ADDR_LEN];
   int RuleAction;
   int RuleJumpIndex;  /* NB, 22 Oct 93:  Was unsigned char! */
   };

#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  /* 'generic' 802 address family */
#define AT_ETHERNET    7  /* ifType medium */
#define AT_TOKENRING   9  /* ifType medium */
#define AT_NOVELL     11
#define AT_ETHERTALK  12
#define AT_DECNET     13
#define AT_FDDI       15  /* ifType medium */
#define AT_AAL5       49  /* ifType AAL5 over ATM */

#define MX_PROTOCOLS  AT_DECNET

#define AT3_IGNORE     0  /* Addr_type values */
#define AT3_DUMMY      1
#define AT3_ADJACENT   1
#define AT3_IP         2
#define AT3_CLNS       3
#define AT3_IDPR       4
#define AT3_DECNET     5
#define AT3_NOVELL     6
#define AT3_ETHERTALK  7
#define AT3_TRANS      8
#define AT3_IP_FRAG   11
#define AT3_OTHER     12

#define PT_ICMP       1  /* IP protocol type values */
#define PT_TCP        6
#define PT_UDP       17
#define PT_OSPF      89  /* OSPF IGP */

#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_GOPHER   70
#define WNP_WWW      80
#define WNP_NNTP    119
#define WNP_NTP     123
#define WNP_SNMP    161

#define RA_SUCCEED       0  /* Ignore */
#define RA_IGNORE        1
#define RA_FAIL          2  /* Retry */
#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 RA_AGGREGATE    98  /* Allow parser to handle old rule files */
#define RA_TALLY        99

#define RF_SET       -2  /* -1 is EOF !!! */
#define RF_RULES     -3
#define RF_ACTIONS   -4
#define RF_FORMAT    -5
#define RF_STATS     -6
#define RF_SYMBOL    -7
#define RF_NEXT      -8
#define RF_INCLUDE   -9


#define FTFLOWINDEX		1  /* Flow table attribute values */
#define FTFLOWTIMEMARK          2
#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 !defined(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 FTTOTURNAROUNDTIME     70
#define FTFROMTURNAROUNDTIME   71
#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

#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 DISTRIB_BASE  FTTOPACKETSIZE
#define N_DIST_ATRS   (LAST_DISTRIB+1 - FTDISTRIBUTIONS) 
# if LASTATTRIB < LAST_DISTRIB
#  undef LASTATTRIB
#  define LASTATTRIB      LAST_DISTRIB  /* max(basic, dist) */
# endif
#endif

#if !defined(NETFLOW)
#define N_NF_ATRS               0
#else
#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     (FTHIROUTEPREFIX+1 - FTMETERID)
# if LASTATTRIB < FTHIROUTEPREFIX
#  undef LASTATTRIB
#  define LASTATTRIB  FTHIROUTEPREFIX  /* max(basic, dist, nf) */
# endif
#endif

#if !defined(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

#define N_ATTRIBS  (N_OLD_ATRS + N_METER_ATRS + N_NF_ATRS \
                      + N_DIST_ATRS + N_TCP_ATRS)

struct attrib_info {
   char *name;
   unsigned char index;
   int len;
   };

#define N_SYNONYMS   3
     /* Synonyms: Forward, To/From TurnaroundTime */

#define SZ_ATTRIBS  (1 + N_OLD_ATRS + N_METER_ATRS + \
                         N_NF_ATRS + N_DIST_ATRS + N_TCP_ATRS + \
                         N_SYNONYMS)
     /* 1: 'null,' */
EXTERN struct attrib_info attribs[SZ_ATTRIBS]
#if DECLARE
   = {
      /* Serial search -> longest names first! */
   "null",                   0,                       0,
   "flowindex",              FTFLOWINDEX,             4,
   "flowtimemark",           FTFLOWTIMEMARK,          4,
   "flowstatus",             FTFLOWSTATUS,            1,
   "sourceinterface",        FTLOWINTERFACE,          1,
   "sourceadjacenttype",     FTLOWADJACENTTYPE,       1,
   "sourceadjacentaddress",  FTLOWADJACENTADDRESS,    MAC_ADDR_LEN,
   "sourceadjacentmask",     FTLOWADJACENTMASK,       MAC_ADDR_LEN,
   "sourcepeertype",         FTLOWPEERTYPE,           1,
   "sourcepeeraddress",      FTLOWPEERADDRESS,        PEER_ADDR_LEN,
   "sourcepeermask",         FTLOWPEERMASK,           PEER_ADDR_LEN,
   "sourcetranstype",        FTLOWTRANSTYPE,          1,
   "sourcetransaddress",     FTLOWTRANSADDRESS,       TRANS_ADDR_LEN,
   "sourcetransmask",        FTLOWTRANSMASK,          TRANS_ADDR_LEN,

   "destinterface",          FTHIINTERFACE,           1,
   "destadjacenttype",       FTHIADJACENTTYPE,        1,
   "destadjacentaddress",    FTHIADJACENTADDRESS,     MAC_ADDR_LEN,
   "destadjacentmask",       FTHIADJACENTMASK,        MAC_ADDR_LEN,
   "destpeertype",           FTHIPEERTYPE,            1,
   "destpeeraddress",        FTHIPEERADDRESS,         PEER_ADDR_LEN,
   "destpeermask",           FTHIPEERMASK,            PEER_ADDR_LEN,
   "desttranstype",          FTHITRANSTYPE,           1,
   "desttransaddress",       FTHITRANSADDRESS,        TRANS_ADDR_LEN,
   "desttransmask",          FTHITRANSMASK,           TRANS_ADDR_LEN,

   "pduscale",               FTPDUSCALE,              0,
   "octetscale",             FTOCTETSCALE,            0,
   "flowruleset",            FTRULESET,               1,
   "tooctets",               FTUPOCTETS,              8,
   "topdus",                 FTUPPDUS,                8,
   "fromoctets",             FTDOWNOCTETS,            8,
   "frompdus",               FTDOWNPDUS,              8,
   "firsttime",              FTFIRSTTIME,             4,
   "lasttime",               FTLASTTIME,              4,

   "sourcesubscriberid",     FTLOWSUBSCRIBERID,       0,
   "destsubscriberid",       FTHISUBSCRIBERID,        0,
   "sessionid",              FTSESSIONID,             0,

   "sourceclass",            FTSOURCECLASS,           1,
   "destclass",              FTDESTCLASS,             1,
   "flowclass",              FTFLOWCLASS,             1,
   "sourcekind",             FTSOURCEKIND,            1,
   "destkind",               FTDESTKIND,              1,
   "flowkind",               FTFLOWKIND,              1,

   "dscodepoint",            FTDSCODEPOINT,           1,

   "tolostpdus",             FTTOLOSTPDUS,            1,
   "fromlostpdus",           FTFROMLOSTPDUS,          1,
   "topqoverflows",          FTTOPQOVERFLOWS,         1,
   "frompqoverflows",        FTFROMPQOVERFLOWS,       1,

   "matchingstod",           FTFORWARD,               1,
   "forward",                FTFORWARD,               1,
   "v1",                     FTV1,                    1,
   "v2",                     FTV2,                    1,
   "v3",                     FTV3,                    1,
   "v4",                     FTV4,                    1,
   "v5",                     FTV5,                    1

#if defined(NEW_ATR)
   ,
   "distributions",          FTDISTRIBUTIONS,         0,
   "topacketsize",           FTTOPACKETSIZE,          DIST_PARAM_LEN,
   "frompacketsize",         FTFROMPACKETSIZE,        DIST_PARAM_LEN,
   "tointerarrivaltime",     FTTOINTERARRIVALTIME,    DIST_PARAM_LEN,
   "frominterarrivaltime",   FTFROMINTERARRIVALTIME,  DIST_PARAM_LEN,
   "toturnaroundtime1",      FTTOTURNAROUNDTIME,      DIST_PARAM_LEN,
   "fromturnaroundtime1",    FTFROMTURNAROUNDTIME,    DIST_PARAM_LEN,
   "tobitrate",              FTTOBITRATE,             DIST_PARAM_LEN,
   "frombitrate",            FTFROMBITRATE,           DIST_PARAM_LEN,
   "topdurate",              FTTOPDURATE,             DIST_PARAM_LEN,
   "frompdurate",            FTFROMPDURATE,           DIST_PARAM_LEN,
   "totcptime",              FTTOTCPTIME,             DIST_PARAM_LEN,
   "fromtcptime",            FTFROMTCPTIME,           DIST_PARAM_LEN,
   "totcpsize",              FTTOTCPSIZE,             DIST_PARAM_LEN,
   "fromtcpsize",            FTFROMTCPSIZE,           DIST_PARAM_LEN,
   "totcprate1",             FTTOTCPRATE1,            DIST_PARAM_LEN,
   "fromtcprate1",           FTFROMTCPRATE1,          DIST_PARAM_LEN,
   "totcprate2",             FTTOTCPRATE2,            DIST_PARAM_LEN,
   "fromtcprate2",           FTFROMTCPRATE2,          DIST_PARAM_LEN,

   "toturnaroundtime",       FTTOTURNAROUNDTIME1,     DIST_PARAM_LEN,
   "fromturnaroundtime" ,    FTFROMTURNAROUNDTIME1,   DIST_PARAM_LEN,
   "toturnaroundtime2",      FTTOTURNAROUNDTIME2,     DIST_PARAM_LEN,
   "fromturnaroundtime2",    FTFROMTURNAROUNDTIME2,   DIST_PARAM_LEN,
   "toturnaroundtime3",      FTTOTURNAROUNDTIME3,     DIST_PARAM_LEN,
   "fromturnaroundtime3",    FTFROMTURNAROUNDTIME3,   DIST_PARAM_LEN,
   "toturnaroundtime4",      FTTOTURNAROUNDTIME4,     DIST_PARAM_LEN,
   "fromturnaroundtime4",    FTFROMTURNAROUNDTIME4,   DIST_PARAM_LEN,

   "toflowoctets",          FTTOFLOWOCTETS,           DIST_PARAM_LEN,
   "fromflowoctets",        FTFROMFLOWOCTETS,         DIST_PARAM_LEN,
   "toflowpdus",            FTTOFLOWPDUS,             DIST_PARAM_LEN,
   "fromflowpdus",          FTFROMFLOWPDUS,           DIST_PARAM_LEN,
   "flowtime",              FTFLOWTIME,               DIST_PARAM_LEN
#endif

#if defined(NETFLOW)
   ,
   "meterid",                FTMETERID,               1,
   "sourceasn",              FTLOWROUTEASN,           TRANS_ADDR_LEN,
   "sourceprefix",           FTLOWROUTEPREFIX,        1,
   "destasn",                FTHIROUTEASN,            TRANS_ADDR_LEN,
   "destprefix",             FTHIROUTEPREFIX,         1
#endif

#if defined(NEW_ATR)
   ,
   "tcpdata",                FTTCPDATA,               1
#endif
   }
#endif
   ;

EXTERN unsigned char col_order[1+N_ATTRIBS]  /* In descending-length order */
#if DECLARE                                 /* Only used in get_colblob_data (v3) */
   = {
   FTLOWADJACENTADDRESS,FTLOWADJACENTMASK,
   FTHIADJACENTADDRESS,FTHIADJACENTMASK,
   
   FTLOWPEERADDRESS,FTLOWPEERMASK,
   FTHIPEERADDRESS,FTHIPEERMASK,
   FTUPOCTETS,FTDOWNOCTETS, FTUPPDUS,FTDOWNPDUS,
   FTFIRSTTIME,FTLASTTIME,
   
   FTLOWTRANSADDRESS,FTLOWTRANSMASK,
   FTHITRANSADDRESS,FTHITRANSMASK,
   
   FTFLOWSTATUS,
   FTLOWINTERFACE,FTLOWADJACENTTYPE,
   FTLOWPEERTYPE,FTLOWTRANSTYPE,
   FTHIINTERFACE,FTHIADJACENTTYPE,
   FTHIPEERTYPE,FTHITRANSTYPE,
   FTRULESET,
   FTSOURCECLASS,FTDESTCLASS,FTFLOWCLASS,
   FTSOURCEKIND,FTDESTKIND,FTFLOWKIND,
   
   0,  /* Marks end of implemented attributes */
   
   FTPDUSCALE,FTOCTETSCALE,
   FTLOWSUBSCRIBERID,FTHISUBSCRIBERID,FTSESSIONID,

   FTFLOWINDEX }  /* Never retrieve FlowIndex explicitly! */
#endif
   ;

#define FLOWBLOBSZ  55

#define FB_OBJECT_SZ  (2+1+MAC_ADDR_LEN)
#define FB_DATA_SZ    FLOWBLOBSZ*FB_OBJECT_SZ

EXTERN unsigned char column_blob[
   FB_DATA_SZ + 2*(2+1+RULE_ADDR_LEN)];

#define MX_BLOB_FLOWS  sizeof(column_blob)/(2+1)
EXTERN struct flow_info flows[MX_BLOB_FLOWS+1];

#define NAME_LN  64
#define NAMESZ   16  /* Names in meter control tables */

struct meter_rule_info {
   int ri_Index;
   int ri_Size;
   int ri_Status;
   char ri_Name[NAMESZ+1];
   int ri_RulesReady;
   int ri_FlowRecords;
   char filename[NAME_LN];
   };

struct meter_status {
   struct meter_status *next;

   char name[NAME_LN];  /* Meter name (DNS name or IP address) */
   char owner_name[NAMESZ+1];  /* For meter control tables */
   unsigned char community[NAME_LN],  /* Write-access SNMP community */
      MIBver,  /* 4 = 'new' MIB, 3 = 'old' MIB */
      meter_MinPDUs,  /* Meter has MinPDU (and TimeMark) in reader rows */
      meter_ra_len,  /* Meter's RULE_ADDR_LEN */
      write_OK,  /* We really do have write access */
      no_write_warned,  /* 'No write' warning logged */
      no_write_meter;  /* Don't write CollectTime to meter */
   unsigned int sample_interval,  /* Seconds between samples */
      keepalive_interval,  /* Seconds between keepalives. 0 = no keepalives */
      lag_seconds;  /* Time lag for samples */
   time_t next_keepalive, next_sample,  /* Time events are to happen */
      next_event;
   int restarting,  /* Haven't written #Ruleset records yet */ 
      synchronised, 
      download_level,  /* Specifies when to download rules sets:   */
                       /*    0 = initially and after meter restart */
                       /*    1 = only after meter restart          */
                       /*    2 = never                             */
      use_meter_rows,  /* Use manager/ruleset rows from meter */
      download_only;   /* Don't collect any flow data */

   struct meter_rule_info c_ruleset, s_ruleset, d_ruleset;

   int mi_Index;  /* This meter's manager info entry */
   int mi_RunningStandby;
   int mi_u_Index;  /* Task parameter for TU_DESTROY */

   int ci_Timeout;  /* For this meter's reader info entry */
   int ci_MinPDUs;  /* For nifty */
   unsigned long ci_TimeMark;  /* Associates Timefilter with MinPDUs */

   int ci_c_Index, ci_s_Index, ci_d_Index, ci_u_Index;

   int HighWaterMark;
   unsigned long ActiveFlows;
   int ActivePercent;  /* Active flows as % of max flows */

   struct snmp_session *ss;

   short status;

   char descr[NAME_LN];  /* From meter_info() */
   oid versionid[20];  char version[10];
   char interface[NAME_LN];
   unsigned long uptime;
   unsigned long OurLastCollectTime;

   int CurrentRuleSet, StandbyRuleSet, /* From meter */
      ruleset, nrules, ncounts;  /* From rule file */

   unsigned char format[1+LASTATTRIB];
   char *separator[1+LASTATTRIB];
   unsigned char required[1+LASTATTRIB];

   unsigned long LastCollectTime;
   int flows_per_getbulk;

   unsigned int snmp_delay;  /* ms to wait after snmp requests */

   int statsreqd;

   int InactivityTime, SamplingRate;  /* Meter control variables */
   int FloodMark, GCIntervalReqd;

   int  /* Meter Statistics variables */
      GCInterval,
      MaxPktRate,MaxPktBacklog,
      TotalHashSize,NbrHashEntries,
      NbrFlows,MaxFlows,
      AvIdle1000,MinIdle1000;
   unsigned long
      StatsTime,NbrPackets,TotPktBacklog,LostPackets,
      RuleMatches,HashSearches,HashCompares,
      FlowsRecovered;

   char flowdatafile[NAME_LN],
      user_flowdatafile,  /* User specified flow data file name */
      append_flowdata;    /* Don't keep flow data file open */
   FILE *flows;

   char *crl_info;  /* Null if not a trace-reading meter */
   int trace_interval;  /* Collection interval for CoralReef trace file */
   time_t trt;  /* Unix seconds from last packet timestamp */

   int mx_one_pkg_pdu_sz;  /* Max packet size for 'only one package' PDUs */
   };

#define meter_maj(ms)  ms->versionid[8]  /* Meter version number */
#define meter_min(ms)  ms->versionid[9]


struct row_info {
   int tr_Index, tr_Status;
   char tr_Owner[NAMESZ+1], tr_Name[NAMESZ+1];
   int tr_Current, tr_Standby;
   int tr_RuleSize;
   };


struct calendar_entry {
   struct calendar_entry *next;
   time_t next_event;
   struct meter_status *ms;
   };

EXTERN char append_log, logfile[NAME_LN], user_logfile[NAME_LN],
	    syslog_name[NAME_LN];
EXTERN FILE *logfl;  /* logf(3) is a FreeBSD function */

EXTERN struct meter_status *first_meter;
EXTERN int nmeters;

EXTERN struct calendar_entry *calendar;

/* Values for status */

#define	MT_MANAGE    0x0001  /* Manage this meter */
#define	MT_INFO	     0x0002  /* Have basic info */
#define	MT_UP	     0x0004  /* Meter is running */
#define	MT_REPORTED  0x0008  /* Current status reported */

EXTERN FILE *rfp;  /* Scanner globals */
EXTERN char scan_rfname[NAME_LN];
EXTERN char inbuf[256], *ibp;
EXTERN int lic, ic,  /* Last input char, current input char */
   toktype, toklen,
   iblisted, rule_line, rferrors, rfwarnings,
   MIBver;
EXTERN char err_msg[60];

#define TOK_OTHER   0  /* Token types.  Returned by getnbr() */
#define TOK_INT     1
#define TOK_WORD    2
#define TOK_ACTION  3
#define TOK_ATTRIB  4
#define TOK_SYMBOL  5
#define TOK_LABEL   6
#define TOK_RSVWD   7

struct incl_ent {
   FILE *fp;
   char rfname[NAME_LN], buf[256], *bp;
   int lic,ic, line_nbr,iblisted;
   };

#define MXINCL   5
EXTERN struct incl_ent incl_stack[MXINCL];
EXTERN int incl_depth;

#define SYMBOLSZ  32
struct symbol {
   int next;  /* For making hash chains */
   char id[SYMBOLSZ+1];
   int type;  /* From TOK_ defines above */
   int size;  /* Data size (bytes) */
   int value;  /* 0 = undefined, RF_RULES = rule label */
   unsigned int target;  /* Jumpindex of rule */
   int action;  /* Action type of rule (also used to make label lists) */
   int comefrom, comefromAct;  /* Action of statements going to this rule */
   };

#define MXSYMBOLS   400
#define STHASHBASE  256  /* Must be a power of 2 */
#define STHASHMASK  (STHASHBASE-1)
#define STSIZE      (STHASHBASE+MXSYMBOLS)

EXTERN struct symbol symbol_table[STSIZE];
EXTERN int st_top,st_index, pass;


/* Forward procedure declarations .. */

int create_meter(struct meter_status *ms, time_t first_t, char *pn);
void monitor(struct meter_status *ms);
void print_meters();
void meter_print(FILE *f,struct meter_status *ms);

/* Functions declared in nmc_pars.c */

void log_msg(int priority, int die, char *fmt, ...);
void mswait(unsigned int ms);
FILE *wfopen(char *full_fn, char *fn);
char *strmov(char *d, char *s);
char *gnbr(unsigned int *n, char *s);
char *gcstring(char *s, int *len);

char *sfmt_attrib(char *d, struct flow_info *fp, unsigned char col);
char *fmt_time(time_t *t);
char *uptime_string(unsigned long timeticks, char *buf);
char *sfmt_v6addr(char *d,unsigned char *a);
char *sfmt_address(char *d,unsigned char *a,
   unsigned char addrtype,unsigned char addrsz);
#ifdef NEW_ATR
char *sfmt_distrib(char *data, struct distribution *dp);
char *sfmt_tcp_data(char *data, struct subflow_data *sfd);
#endif
void printruleaddress(FILE *F,unsigned char *a);

int parse_open(char *fn);
int nextchar(void);
int trailing_arg(void);
void getarg(char *arg);
int wordis(char *p,char *w);
void p_warn(char *msg);
void p_error(char *msg);
int getword(void);
int getnbr(int maxnbr);
unsigned int getint(unsigned int *base);
void getaddress(unsigned char *a,unsigned char len,
   unsigned char addrsz);
int getattribute(unsigned char col,struct flow_info *fp);

int scan_rulefile(struct meter_status *ms, int doset, 
   int list, int emergency);
int parse_rulefile(struct meter_status *ms,
   int list, int syntax, int standby, int restart);

/* Functions declared in nmc_snmp.c */

int trim(unsigned char *s, int len);
int start_snmp_session(struct meter_status *ms);
int restart_snmp_session(struct meter_status *ms);

int set_meter_params(struct meter_status *ms);

int create_table_row(struct meter_status *ms, oid *r_status);
int search_table(struct meter_status *ms, int which,
   void (*row_handler)(struct meter_status *ms, struct row_info *rip));
#define ST_RULESET  1  /* 'which' values */
#define ST_MANAGER  4
#define ST_READER   3

int ruleset_util(struct meter_status *ms,
   int which, struct meter_rule_info *mri);
#define RU_INIT     0  /* Create row  'which' values */
#define RU_READY    1  /* Set RulesReady */
#define RU_DESTROY  2  /* Destroy row */
int add_rule(struct meter_status *ms, struct rule_info *ri);
int get_rule(struct meter_status *ms, struct rule_info *ri);

int task_util(struct meter_status *ms, int which);
#define TU_INIT       1  /* Create row  'which' values */
#define TU_CURRENT    2  /* Set current rule */
#define TU_STANDBY    3  /* Set standby rule set */
#define TU_NOSTAND    4  /* Switch back from RunningStandby */
#define TU_DESTROY    5  /* Destroy row */

int reader_util(struct meter_status *ms, int which, int flowset);
#define CU_INIT         1  /* Create row  'which' values */
#define CU_SET_TIME     2  /* Set flowset LastTime */
#define CU_DESTROY      3  /* Destroy row */
#define CU_SET_MINPDUS  4  /* Set flowset MinPDUs (for nifty) */

#define CU_CURRENT     11  /* Collect flows from 'current' rule set */
#define CU_STANDBY     12  /* Collect flows from 'standby' rule set */
#define CU_DEFAULT     13  /* Collect flows from 'default' rule set */
#define CU_UTIL        14  /* 'Util' rule set */

int set_manager_info(struct meter_status *ms);
int set_rule_info(struct meter_status *ms, int which);

int TrState_util(struct meter_status *ms,
   int which, int *what);
#define CSU_READ   1  /* Return current value in what */
#define CSU_WRITE  2  /* Write what */

unsigned short getshort(unsigned char *ucp);
unsigned long getlong(unsigned char *ucp);
void getcounter64(counter64 *c, unsigned char *ucp);

void get_colblob_data(struct meter_status *ms, int rs, Bit32 t,
   void (*process_row)(struct flow_info *fp));

int get_package_info(struct meter_status *ms, int rs, Bit32 t,
   void (*process_row)(struct flow_info *fp));

int flow_info(struct meter_status *ms, struct flow_info *fi, unsigned int fn);

int meter_is_current(struct meter_status *ms);
int reset_FloodMode(struct meter_status *ms);
int meter_info(struct meter_status *ms);
int meter_type(struct meter_status *ms);
   
/* Functions declared in nm_display.c */

char *sdisplay_peertype(char *d,
   unsigned int peertype);
char *sdisplay_transtype(char *d,
   unsigned int peertype, unsigned int transtype);
char *sdisplay_transaddr(char *d,
   unsigned int peertype, unsigned char *a);

char *sdisplay_number(char *d, unsigned long x);
char *sdisplay_timeinterval(char *d, unsigned long t);

char *sdisplay_attrib(char *d,
   struct flow_info *fp, unsigned char col,
   struct meter_status *ms);
