#ifndef FLOWDATA_H
#define FLOWDATA_H

/*------------------------------------------------------------------
 *
 * contains definitions of structs used to send/receive NetFlow data
 * 
 * Original, May 1996, Ajay Dankar
 * Modified, June 1997, Anders Fung
 *
 * Copyright (c) 1996 by Cisco Systems, Inc.
 * All rights reserved.
 *------------------------------------------------------------------
 */

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define FLOW_VERSION_1		1
#define V1FLOWS_PER_PAK		24
#define FLOW_VERSION_5		5
#define V5FLOWS_PER_PAK		30

#define ulong      Bit32
   /* ulong is usually declared in sys/types.h.
      On 32-bit machines it provides a 32-bit object, but on
      64-bit machines (like the Alpha) it doesn't!
      We can't redeclare it, so we define it instead. */
#define ushort     Bit16
#define uchar      Bit8
#define ipaddrtype Bit32

#ifndef MAX
#define MAX(a,b) ((a) >= (b) ? (a) : (b))
#endif

typedef struct {
    ushort version;         /* 1 for now. */
    ushort count;           /* The number of records in PDU. */
    ulong  SysUptime;       /* Current time in millisecs since router booted */
    ulong  unix_secs;       /* Current seconds since 0000 UTC 1970 */
    ulong  unix_nsecs;      /* Residual nanoseconds since 0000 UTC 1970 */
} Flow1StatHdr;

typedef struct {
    ipaddrtype srcaddr;    /* Source IP Address */
    ipaddrtype dstaddr;    /* Destination IP Address */
    ipaddrtype nexthop;    /* Next hop router's IP Address */
    ushort input;          /* Input interface index */
    ushort output;         /* Output interface index */
    
    ulong dPkts;           /* Packets sent in Duration */
    ulong dOctets;         /* Octets sent in Duration. */
    ulong First;           /* SysUptime at start of flow */
    ulong Last;            /* and of last packet of flow */

    ushort srcport;        /* TCP/UDP source port number or equivalent */    
    ushort dstport;        /* TCP/UDP destination port number or equivalent */
    ushort pad;
    uchar  prot;           /* IP protocol, e.g., 6=TCP, 17=UDP, ... */
    uchar  tos;            /* IP Type-of-Service */
    
    uchar  flags;          /* Reason flow was discarded, etc...  */
    uchar  tcp_retx_cnt;   /* Number of mis-seq with delay > 1sec */
    uchar  tcp_retx_secs;  /* Cumulative seconds between mis-sequenced pkts */
    uchar  tcp_misseq_cnt; /* Number of mis-sequenced tcp pkts seen */
    ulong  reserved;
} IPFlow1Stat;

typedef struct {
    Flow1StatHdr header;
    IPFlow1Stat  records[V1FLOWS_PER_PAK];
} IPStat1Msg;

typedef struct {
    ushort version;         
    ushort count;           /* The number of records in PDU. */
    ulong  SysUptime;       /* Current time in millisecs since router booted */
    ulong  unix_secs;       /* Current seconds since 0000 UTC 1970 */
    ulong  unix_nsecs;      /* Residual nanoseconds since 0000 UTC 1970 */
    ulong  flow_sequence;   /* Seq counter of total flows seen */
    ulong  reserved;
} Flow5StatHdr;


typedef struct {
    ipaddrtype srcaddr;    /* Source IP Address */
    ipaddrtype dstaddr;    /* Destination IP Address */
    ipaddrtype nexthop;    /* Next hop router's IP Address */
    ushort input;          /* Input interface index */
    ushort output;         /* Output interface index */
    
    ulong dPkts;           /* Packets sent in Duration */
    ulong dOctets;         /* Octets sent in Duration. */
    ulong First;           /* SysUptime at start of flow */
    ulong Last;            /* and of last packet of flow */
    
    ushort srcport;        /* TCP/UDP source port number or equivalent */
    ushort dstport;        /* TCP/UDP destination port number or equivalent */
    uchar  pad;
    uchar  tcp_flags;      /* Cumulative OR of tcp flags */
    uchar  prot;           /* IP protocol, e.g., 6=TCP, 17=UDP, ... */
    uchar  tos;            /* IP Type-of-Service */
    ushort src_as;         /* originating AS of source address */
    ushort dst_as;         /* originating AS of destination address */
    uchar  src_mask;       /* source address prefix mask bits */
    uchar  dst_mask;       /* destination address prefix mask bits */
    ushort reserved;
} IPFlow5Stat;

typedef struct {
    Flow5StatHdr header;
    IPFlow5Stat  records[V5FLOWS_PER_PAK];
} IPStat5Msg;

#define MAX_V1_FLOW_PAK_SIZE (sizeof(Flow1StatHdr) + \
                              sizeof(IPFlow1Stat) * V1FLOWS_PER_PAK)
 
#define MAX_V5_FLOW_PAK_SIZE (sizeof(Flow5StatHdr) + \
                              sizeof(IPFlow5Stat) * V5FLOWS_PER_PAK)
 
#define MAX_FLOW_PAK_SIZE MAX(MAX_V1_FLOW_PAK_SIZE,  \
                                  MAX_V5_FLOW_PAK_SIZE)

ushort getVersionNumber(flow) 
char* flow;
{
  return *((ushort*)flow);
}

#undef ulong  /* Don't leave these lying around! */
#undef ushort
#undef uchar
#undef ipaddrtype

#endif  /* FLOWDATA_H */
