//===========================================================================
//  @(#) $Name: cflowd-2-1-b1 $
//  @(#) $Id: CflowdRawFlowConverter.hh,v 1.4 1998/09/25 05:27:08 dwm Exp $
//===========================================================================
//  CAIDA Copyright Notice
//
//  By accessing this software, cflowd++, you are duly informed
//  of and agree to be bound by the conditions described below in this
//  notice:
//
//  This software product, cflowd++, is developed by Daniel W. McRobb, and
//  copyrighted(C) 1998 by the University of California, San Diego
//  (UCSD), with all rights reserved.  UCSD administers the CAIDA grant,
//  NCR-9711092, under which part of this code was developed.
//
//  There is no charge for cflowd++ software. You can redistribute it
//  and/or modify it under the terms of the GNU General Public License,
//  v.  2 dated June 1991 which is incorporated by reference herein.
//  cflowd++ is distributed WITHOUT ANY WARRANTY, IMPLIED OR EXPRESS, OF
//  MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE or that the use
//  of it will not infringe on any third party's intellectual property
//  rights.
//
//  You should have received a copy of the GNU GPL along with cflowd++.
//  Copies can also be obtained from:
//
//    http://www.gnu.org/copyleft/gpl.html
//
//  or by writing to:
//
//    University of California, San Diego
//
//    SDSC/CAIDA
//    9500 Gilman Dr., MS-0505
//    La Jolla, CA 92093 - 0505  USA
//
//  Or contact:
//
//    info@caida.org
//===========================================================================

#ifndef _CFLOWDRAWFLOWCONVERTER_HH_
#define _CFLOWDRAWFLOWCONVERTER_HH_

extern "C" {
#include <sys/types.h>
  
#include "caida_t.h"
}

#include <vector>

#include "CflowdRawFlow.hh"

//---------------------------------------------------------------------------
//  class CflowdRawFlowConverter
//---------------------------------------------------------------------------
//  This class is used to convert from a UDP flow packet from a Cisco
//  into a form more suitable for general use.  The normal way to do
//  this would be to read the packet with recv(), look at the first
//  two bytes for the version number, then pass some pointers into
//  one of our ToFlowVector() members.
//
//  Note we have no data members in ths class, only member functions
//  for converting flow-export packets to CflowdRawFlow vectors.
//---------------------------------------------------------------------------
class CflowdRawFlowConverter
{
public:
  //-------------------------------------------------------------------------
  //          vector<CflowdRawFlow> *                         
  //          ToFlowVector(ipv4addr_t ciscoIpAddr,            
  //                       const CiscoFlowHeaderV1_t * flowHeader, 
  //                       const CiscoFlowEntryV1_t * flowEntry)
  //.........................................................................
  //  Given the IP address of the Cisco that sent a v1 flow-export
  //  packet, a pointer to the header of the v1 flow-export packet,
  //  and a pointer to the first flow entry in the flow-export packet,
  //  returns a pointer to a new vector of raw flows.
  //-------------------------------------------------------------------------
  vector<CflowdRawFlow> *
  ToFlowVector(ipv4addr_t ciscoIpAddr,
               const CiscoFlowHeaderV1_t * flowHeader,
               const CiscoFlowEntryV1_t * flowEntry);

  //-------------------------------------------------------------------------
  //      void AddToFlowVector(vector<CflowdRawFlow> & flowVector,         
  //                           ipv4addr_t ciscoIpAddr,                    
  //                           const CiscoFlowHeaderV1_t * flowHeader,    
  //                           const CiscoFlowEntryV1_t * flowEntry)
  //.........................................................................
  //  Given the IP address of the Cisco that sent a v1 flow-export
  //  packet, a pointer to the header of the v1 flow-export packet,
  //  and a pointer to the first flow entry in the flow-export packet,
  //  appends raw flows to a vector of CflowdRawFlow objects.
  //-------------------------------------------------------------------------
  void AddToFlowVector(vector<CflowdRawFlow> & flowVector,
                       ipv4addr_t ciscoIpAddr,
                       const CiscoFlowHeaderV1_t * flowHeader,
                       const CiscoFlowEntryV1_t * flowEntry);
  
  //-------------------------------------------------------------------------
  //          vector<CflowdRawFlow> *                         
  //          ToFlowVector(ipv4addr_t ciscoIpAddr,            
  //                       const CiscoFlowHeaderV5_t * flowHeader, 
  //                       const CiscoFlowEntryV5_t * flowEntry)
  //.........................................................................
  //  Given the IP address of the Cisco that sent a v5 flow-export
  //  packet, a pointer to the header of the v5 flow-export packet,
  //  and a pointer to the first flow entry in the flow-export packet,
  //  returns a pointer to a new vector of raw flows.
  //-------------------------------------------------------------------------
  vector<CflowdRawFlow> *
  ToFlowVector(ipv4addr_t ciscoIpAddr,
               const CiscoFlowHeaderV5_t * flowHeader,
               const CiscoFlowEntryV5_t * flowEntry);
  

  //-------------------------------------------------------------------------
  //      void AddToFlowVector(vector<CflowdRawFlow> & flowVector,         
  //                           ipv4addr_t ciscoIpAddr,                    
  //                           const CiscoFlowHeaderV5_t * flowHeader,    
  //                           const CiscoFlowEntryV5_t * flowEntry)
  //.........................................................................
  //  Given the IP address of the Cisco that sent a v5 flow-export
  //  packet, a pointer to the header of the v5 flow-export packet,
  //  and a pointer to the first flow entry in the flow-export packet,
  //  appends raw flows to a vector of CflowdRawFlow objects.
  //-------------------------------------------------------------------------
  inline void AddToFlowVector(vector<CflowdRawFlow> & flowVector,
                              ipv4addr_t ciscoIpAddr,
                              const CiscoFlowHeaderV5_t * flowHeader,
                              const CiscoFlowEntryV5_t * flowEntry)
  {
    uint16_t       flowNum;
    CflowdRawFlow  newFlow;
    
    // flowVector.reserve(flowVector.size() + ntohs(flowHeader->count));
    
    for (flowNum = 0; flowNum < ntohs(flowHeader->count); flowNum++) {
      newFlow = CflowdRawFlow(ciscoIpAddr,flowHeader,flowEntry);
      flowVector.push_back(newFlow);
    }
    return;
  }
  
  //-------------------------------------------------------------------------
  //          vector<CflowdRawFlow> *                         
  //          ToFlowVector(ipv4addr_t ciscoIpAddr,            
  //                       const CiscoFlowHeaderV6_t * flowHeader, 
  //                       const CiscoFlowEntryV6_t * flowEntry)
  //.........................................................................
  //  Given the IP address of the Cisco that sent a v6 flow-export
  //  packet, a pointer to the header of the v6 flow-export packet,
  //  and a pointer to the first flow entry in the flow-export packet,
  //  returns a pointer to a new vector of raw flows.
  //-------------------------------------------------------------------------
  vector<CflowdRawFlow> *
  ToFlowVector(ipv4addr_t ciscoIpAddr,
               const CiscoFlowHeaderV6_t * flowHeader,
               const CiscoFlowEntryV6_t * flowEntry);

  //-------------------------------------------------------------------------
  //      void AddToFlowVector(vector<CflowdRawFlow> & flowVector,        
  //                           ipv4addr_t ciscoIpAddr,                    
  //                           const CiscoFlowHeaderV6_t * flowHeader,    
  //                           const CiscoFlowEntryV6_t * flowEntry);     
  //.........................................................................
  //  Given the IP address of the Cisco that sent a v6 flow-export
  //  packet, a pointer to the header of the v6 flow-export packet,
  //  and a pointer to the first flow entry in the flow-export packet,
  //  appends raw flows to a vector of CflowdRawFlow objects.
  //-------------------------------------------------------------------------
  void AddToFlowVector(vector<CflowdRawFlow> & flowVector,
                       ipv4addr_t ciscoIpAddr,
                       const CiscoFlowHeaderV6_t * flowHeader,
                       const CiscoFlowEntryV6_t * flowEntry);
  

  //  vector<CflowdRawFlow> * ToFlowVector(ipv4addr_t ciscoIpAddr,
  //                                    const CiscoFlowHeaderV8_t * flowHeader,
  //                                    const CiscoFlowEntryV8_t * flowEntry);

private:
  
};

#endif  // _CFLOWDRAWFLOWCONVERTER_HH_
