#include "TcpDissector.h"
#include "Logger/Logger.h"
#ifdef WIN32
#include <Winsock2.h>
#else
#include <netinet/in.h>
#endif

TcpDissector::TcpDissector() :
  m_tcpHdr(0)
{
}

TcpDissector::~TcpDissector() 
{
	delete m_tcpHdr;
}

TcpDissector * TcpDissector::Clone() const 
{
  return new TcpDissector();
}

bool TcpDissector::Dissect(const unsigned char * pData, const ssize_t nDataLen) 
{
  if (!m_tcpHdr)
    m_tcpHdr = new TcpHeader;
  memcpy(m_tcpHdr, pData, sizeof(TcpHeader));
#if BYTE_ORDER == LITTLE_ENDIAN
  m_tcpHdr->destPort = ntohs(m_tcpHdr->destPort);
  m_tcpHdr->srcPort = ntohs(m_tcpHdr->srcPort);
#endif
  int nOffset = m_tcpHdr->dataOffset;
  nOffset *= 4;
  pData += nOffset;

  ssize_t nLen = nDataLen - nOffset;
  if (nLen > 0)
  {
	SavePayload(pData, nLen);
	SaveLayerInfo();
  }
  if (nLen == 0)
	  Logger::Instance().LogDebug("TCP control packet discarded");
  return nLen > 0;
  // TODO: This implementation is not sufficient for all cases. It doesn't handle
  // out-of-order messages and packet loss issues.
}

bool TcpDissector::NeedReassembly() const {
  return false;
}

bool TcpDissector::Reassemble(Dissector * pDissector, ProtocolInfo * pProtocolInfo) {
  // Fragmentation has to be solved in application layere protocols
  return Dissector::Reassemble(pDissector, pProtocolInfo);
}

const EProtocolType TcpDissector::GetUpperLayerType() const {
	return EProtocolType_Sip;
}

ProtocolInfoElement * TcpDissector::CreateLayerInfo()
{
	TcpInfo * pRes = new TcpInfo();
	pRes->SetSourcePort(m_tcpHdr->srcPort);
	pRes->SetDestinationPort(m_tcpHdr->destPort);
	return pRes;
}
