#ifndef IPV6_DISSECTOR_H
#define IPV6_DISSECTOR_H

#include "Dissector.h"
#include "Capture/TcpipDefs.h"
#include <map>
#include <list>
#include <string>

class Ipv6Dissector : public Dissector {

	/**
		This is a copy of IPv6 inet_ntop C function
		Warning: encapsulated IPv4 not supported
		http://www.koders.com/c/fid8E3CB9FE9913C1E6C2E8316BAB79203D6241AED9.aspx
	 **/
  const char *InetNtop (const unsigned char *src, char *dst, socklen_t size);

 public:
  Ipv6Dissector();
  virtual ~Ipv6Dissector();
  virtual Ipv6Dissector * Clone() const;
  virtual bool Dissect(const unsigned char * pData, const ssize_t nDataLen);
  virtual bool NeedReassembly() const;
  virtual bool Reassemble(Dissector * pDissector, ProtocolInfo * pProtocolInfo);
  virtual const EProtocolType GetUpperLayerType() const;

 private:
  struct IpHeader {
#if BYTE_ORDER == LITTLE_ENDIAN
  unsigned char msbDS:4,    // 4-bit for MSB DS byte
    						version:4;  // 4-bit IPv6 version, and will thus contain the number 6
  unsigned char msbFlowLabel:4,	 // 4-bit for MSB flow label (i.e. Label for a data flow)
  							lsbDS:4; 	 // 4-bit for LSB DS byte
#else
#if BYTE_ORDER == BIG_ENDIAN
  unsigned char version:4, // 4-bit IPv6 version, and will thus contain the number 6
    						msbDS:4;	 // 4-bit for MSB DS byte
  unsigned char lsbDS:4, 	 			 // 4-bit for LSB DS byte
    						msbFlowLabel:4;	 // 4-bit for MSB flow label (i.e. Label for a data flow)
#endif
#endif
  unsigned short lsbFlowLabel;  // Label for a data flow
  unsigned short payloadLength; // Indicates the length of the packet data field
  unsigned char  tos;           // Identifies the type of header immediately following the IPv6 header
  unsigned char  hopLimit;      // Decremented by one by each node that forwards the packet. When the hop limit field reaches zero, the packet is discarded.
  unsigned char  srcAddr[16];       // The address of the originator of the packet
  unsigned char  destAddr[16];      // Source address
  };

 private:
  IpHeader * m_ipHdr;

 protected:
  ProtocolInfoElement * CreateLayerInfo();
};

#endif
