//-----------------------------------------------------------------------------
// File:  arp.hh 
// Date:  Thu Jun 12 15:33:38 PDT 2003  
// Author: Martin Casado
// 
//  Model ArpHardwareType
//
// - uint8_t  ADDRLEN - length of the hardware address
// - uint16_t ARPTYPE - ARP specification for hardware type
// - typename ADDRType type used for addressing
//
// Model ArpProtocolType
//
// - uint8_t  ADDRLEN
// - uint16_t ARPTYPE
// - typename ADDRTYPE
//
// I know these are the same, but somehow... really it makes sense..
// no really...
//
// TODO:
//
//   Use static type checking to ensure that the template parameters
//   are of type arp_hardware and arp_protocol.
//
// ----------------------------------------------------------------------------
//
//    Copyright 2003. The Regents of the University of California.
//    All rights reserved.
//
//    This work was produced at the University of California, Lawrence Livermore
//    National Laboratory (UC LLNL) under contract no. W-7405-ENG-48 (Contract
//    48) between the U.S. Department of Energy (DOE) and The Regents of the
//    University of California (University) for the operation of UC LLNL.
//    Copyright is reserved to the University for purposes of controlled
//    dissemination, commercialization through formal licensing, or other
//    disposition under terms of Contract 48; DOE policies, regulations and
//    orders; and U.S. statutes. The rights of the Federal Government are
//    reserved under Contract 48 subject to the restrictions agreed upon by the
//    DOE and University as allowed under DOE Acquisition Letter 91-7.
//
//    DISCLAIMER
//    This software was prepared as an account of work sponsored by an
//    agency of the United States Government. Neither the United States
//    Government nor the University of California nor any of their employees,
//    makes any warranty, express or implied, or assumes any liability or
//    responsibility for the accuracy, completeness, or usefulness of any
//    information, apparatus, product, or process disclosed, or represents that
//    its use would not infringe protectedly-owned rights. Reference herein to any
//    specific commercial products, process, or service by trade name, trademark,
//    manufacturer, or otherwise, does not necessarily constitute or imply its
//    endorsement, recommendation, or favoring by the United States Government or
//    the University of California. The views and opinions of authors expressed
//    herein do not necessarily represent those of the United States
//    Government or the University of California, and shall not be used for
//    advertising or product endorsement purposes.
//
//-----------------------------------------------------------------------------

#ifndef ARP_HH
#define ARP_HH

#include "static_type_inference.hh"
#include "ethernet.hh"

namespace pacman
{

template <typename O, typename T> struct ip;    

template <uint16_t proto = htons_<1>::val, 
           typename hardware_type = ethernet<_>,
           typename protocol_type = ip<_,_> >
struct arp : public ether_type
{
    // -- Conform to model of Ethernet_type
    static const uint16_t ETHTYPE = ethernet<>::ARP;

    //-------------------------------------------------------------------------
    // STATIC CONST
    //-------------------------------------------------------------------------

    // ARP types
    static const uint16_t REQUEST   =      htons_<1>::val;
    static const uint16_t REPLY     =      htons_<2>::val;
    static const uint16_t REVERSEREQUEST = htons_<3>::val;
    static const uint16_t REVERSEREPLY   = htons_<4>::val;


    // ARP protocol HARDWARE identifiers. 
    static const uint16_t NETROM   =  htons_<0>::val; // From KA9Q: NET/ROM pseudo. 
    static const uint16_t ETHER    =  htons_<1>::val; // Ethernet 10/100Mbps.  
    static const uint16_t EETHER   =  htons_<2>::val; // Experimental Ethernet.  
    static const uint16_t AX25     =  htons_<3>::val; // AX.25 Level 2.  
    static const uint16_t PRONET   =  htons_<4>::val; // PROnet token ring.  
    static const uint16_t CHAOS    =  htons_<5>::val; // Chaosnet.  
    static const uint16_t IEEE802  =  htons_<6>::val; // IEEE 802.2 Ethernet/TR/TB.  
    static const uint16_t ARCNET   =  htons_<7>::val; // ARCnet.  
    static const uint16_t APPLETLK =  htons_<8>::val; // APPLEtalk.  
    static const uint16_t DLCI     =  htons_<15>::val; // Frame Relay DLCI.  
    static const uint16_t ATM      =  htons_<19>::val; // ATM.  
    static const uint16_t METRICOM =  htons_<23>::val; // Metricom STRIP (new IANA id).  
    static const uint16_t IEEE995    = htons_<24>::val; // IEEE 1394.1995.
    static const uint16_t MAPOS      = htons_<25>::val; // MAPOS.
    static const uint16_t TWINAXIAL  = htons_<26>::val; // Twinaxial.
    static const uint16_t EUI64      = htons_<27>::val; // EUI-64.
    static const uint16_t HIPARP     = htons_<28>::val; // HIPARP.
    static const uint16_t ISO78163   = htons_<29>::val; // IP and ARP over ISO 7816-3.
    static const uint16_t ARPSEC     = htons_<30>::val; // ARPSec.
    static const uint16_t IPSEC      = htons_<31>::val; // IPsec tunnel.
    static const uint16_t INFINIBAND = htons_<32>::val; // Infiniband./ Last Modified

    // Dummy types for non ARP hardware 
    static const uint16_t SLIP    = htons_<256>::val;
    static const uint16_t CSLIP   = htons_<257>::val;
    static const uint16_t SLIP6   = htons_<258>::val;
    static const uint16_t CSLIP6  = htons_<259>::val;
    static const uint16_t RSRVD   = htons_<260>::val; // Notional KISS type.  
    static const uint16_t ADAPT   = htons_<264>::val;
    static const uint16_t ROSE    = htons_<270>::val;
    static const uint16_t X25     = htons_<271>::val; // CCITT X.25.  
    static const uint16_t HWX25   = htons_<272>::val; // Boards with X.25 in firmware.  
    static const uint16_t PPP     = htons_<512>::val;
    static const uint16_t CISCO   = htons_<513>::val; // Cisco HDLC.  
    static const uint16_t HDLC    = htons_<513>::val;
    static const uint16_t LAPB    = htons_<516>::val; // LAPB.  
    static const uint16_t DDCMP   = htons_<517>::val; // Digital's DDCMP.  
    static const uint16_t RAWHDLC = htons_<518>::val; // Raw HDLC.  
    
    static const uint16_t TUNNEL     =  htons_<768>::val; // IPIP tunnel.  
    static const uint16_t TUNNEL6    =  htons_<769>::val; // IPIP6 tunnel.  
    static const uint16_t FRAD       =  htons_<770>::val; // Frame Relay Access Device.  
    static const uint16_t SKIP       =  htons_<771>::val; // SKIP vif.  
    static const uint16_t LOOPBACK   =  htons_<772>::val; // Loopback device.  
    static const uint16_t LOCALTLK   =  htons_<773>::val; // Localtalk device.  
    static const uint16_t FDDI       =  htons_<774>::val; // Fiber Distributed Data Interface. 
    static const uint16_t BIF        =  htons_<775>::val; // AP1000 BIF.  
    static const uint16_t SIT        =  htons_<776>::val; // sit0 device - IPv6-in-IPv4.  
    static const uint16_t IPDDP      =  htons_<777>::val; // IP-in-DDP tunnel.  
    static const uint16_t IPGRE      =  htons_<778>::val; // GRE over IP.  
    static const uint16_t PIMREG     =  htons_<779>::val; // PIMSM register interface.  
    static const uint16_t HIPPI      =  htons_<780>::val; // High Performance Parallel I'face. 
    static const uint16_t ASH        =  htons_<781>::val; // (Nexus Electronics) Ash.  
    static const uint16_t ECONET     =  htons_<782>::val; // Acorn Econet.  
    static const uint16_t IRDA       =  htons_<783>::val; // Linux-IrDA.  
    static const uint16_t FCPP       =  htons_<784>::val; // Point to point fibrechanel.  
    static const uint16_t FCAL       =  htons_<785>::val; // Fibrechanel arbitrated loop.  
    static const uint16_t FCPL       =  htons_<786>::val; // Fibrechanel public loop.  
    static const uint16_t FCPFABRIC  =  htons_<787>::val; // Fibrechanel fabric.  
    static const uint16_t IEEE802_TR =  htons_<800>::val; // Magic type ident for TR.  
    static const uint16_t IEEE80211  =  htons_<801>::val; // IEEE 802.11.  

    uint16_t  hrd;  // -- format of hardware address.  
    uint16_t  pro;  // -- format of protocol address. 
    uint8_t   hln;  // -- length of hardware address.  
    uint8_t   pln;  // -- length of protocol address.  
    uint16_t  op;   // -- arp opcode (command).  

    typename hardware_type::AddrType sha; // Sender hardware address
    typename protocol_type::AddrType sip; // Sender IP address
    typename hardware_type::AddrType tha; // Target hardware address
    typename protocol_type::AddrType tip; // Target IP address

    arp();

}__attribute__ ((__packed__)); // -- arp
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
template <uint16_t proto, typename hardware_type, typename protocol_type>
inline
arp<proto, hardware_type, protocol_type>::arp():
hrd(hardware_type::ARPTYPE),
pro(protocol_type::ARPTYPE),
hln(hardware_type::ADDRLEN),
pln(protocol_type::ADDRLEN),
op(proto)
{ }
//-----------------------------------------------------------------------------

// -- Some convenience classes to cut down on typing

template < typename hardware_type = ethernet<_>,
           typename protocol_type = ip<_,_> >
struct arpreq : public arp < arp<>::REQUEST, hardware_type, protocol_type >
{ };

template < typename hardware_type = ethernet<_>,
           typename protocol_type = ip<_,_> >
struct arprep : public arp < arp<>::REPLY, hardware_type, protocol_type >
{ };

template < typename hardware_type = ethernet<_>,
           typename protocol_type = ip<_,_> >
struct rarpreq : public arp < arp<>::REVERSEREQUEST, hardware_type, protocol_type >
{ };

template < typename hardware_type = ethernet<_>,
           typename protocol_type = ip<_,_> >
struct rarprep : public arp < arp<>::REVERSEREPLY, hardware_type, protocol_type >
{ };

} // -- namespace pacman

//-----------------------------------------------------------------------------
//                        REFERENCE
//-----------------------------------------------------------------------------

// Hardware type. 16 bits.
// 
//  Value
//                  Description
//   1 Ethernet.
//   2 Experimental Ethernet.
//   3 Amateur Radio AX.25.
//   4 Proteon ProNET Token Ring.
//   5 Chaos.
//   6 IEEE 802.
//   7 ARCNET.
//   8 Hyperchannel.
//   9 Lanstar.
//   10 Autonet Short Address.
//   11 LocalTalk.
//   12 LocalNet (IBM PCNet or SYTEK LocalNET).
//   13 Ultra link.
//   14 SMDS.
//   15 Frame Relay.
//   16 ATM, Asynchronous Transmission Mode.
//   17 HDLC.
//   18 Fibre Channel.
//   19 ATM, Asynchronous Transmission Mode.
//   20 Serial Line.
//   21 ATM, Asynchronous Transmission Mode.
//   22 MIL-STD-188-220.
//   23 Metricom.
//   24 IEEE 1394.1995.
//   25 MAPOS.
//   26 Twinaxial.
//   27 EUI-64.
//   28 HIPARP.
//   29 IP and ARP over ISO 7816-3.
//   30 ARPSec.
//   31 IPsec tunnel.
//   32 Infiniband./ Last Modified: 2002-Apr-13 10:09:57 AM


#endif  // -- ARP_HH
