Commit 3a352af4 authored by garciay's avatar garciay
Browse files

Bug fixed on IPv6 support

parent 3e0e7377
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -45,7 +45,7 @@ bool Dispatcher::Dispatch(DispatchInfo & info, ComponentFilter & filter) {
	  pUnprocessedFilter = new ComponentFilter(filter);
  }

	std::clog << "Dispatcher::Dispatch: Call Dissect method: " <<  info.GetData() << std::endl;
	std::clog << "Dispatcher::Dispatch: Call Dissect method" << std::endl;
  if (!pDissector->Dissect(info.GetData(), info.GetDataSize())) // no information for higher levels
  {
	  delete pDissector;
@@ -118,6 +118,7 @@ bool Dispatcher::Dispatch(DispatchInfo & info, ComponentFilter & filter) {

  // Transfer to upper layer
  const EProtocolType upperLayerType = pDissector->GetUpperLayerType();
	std::clog << "Dispatcher::Dispatch: UpperLayerType: " << upperLayerType << std::endl;
  
  bRes = false;
  if (upperLayerType == EProtocolType_None) // all headers have been removed
@@ -130,7 +131,8 @@ bool Dispatcher::Dispatch(DispatchInfo & info, ComponentFilter & filter) {
  }
  else
  {
	Logger::Instance().LogDebug("Dispatcher::Dispatch: call DispatcherFactory for upperLayerType: " + upperLayerType);
	std::clog << "Dispatcher::Dispatch: call DispatcherFactory for upperLayerType:  " << upperLayerType << std::endl;
	//Logger::Instance().LogDebug("Dispatcher::Dispatch: call DispatcherFactory for upperLayerType: " + upperLayerType);
	Dispatcher * pUpperLayer = DispatcherFactory::Instance().Get(upperLayerType);
	if(pUpperLayer)
		bRes = pUpperLayer->Dispatch(info, filter);
+13 −8
Original line number Diff line number Diff line
@@ -103,9 +103,7 @@ bool FilterSet::Match(const ProtocolInfoElement * pProtocolInfo)
	iterator it = begin();
	bool bEmptyFilterSet = true;

	std::cerr << "FilterSet::Match() "
		  << pProtocolInfo->GetId() << " "
		  << std::endl;
	std::clog << ">>> FilterSet::Match " << pProtocolInfo->ToString() << " - " << pProtocolInfo->GetId() << std::endl;

	while (it != end())
	{
@@ -114,7 +112,7 @@ bool FilterSet::Match(const ProtocolInfoElement * pProtocolInfo)
		{
		  	delete (*it);
		  	it = erase(it);
			std::cerr << "no match" << std::endl;
			std::cerr << "FilterSet::Match: no match" << std::endl;
		}
		else
		{
@@ -122,16 +120,23 @@ bool FilterSet::Match(const ProtocolInfoElement * pProtocolInfo)
			bSenderMatch |= matchType == EFilterMatch_Sender;
			bRcvMatch |= matchType == EFilterMatch_Receiver;
			++it;
			std::cerr << "match " 
				  << bSenderMatch << " "
				  << bRcvMatch << std::endl;
			std::clog << "FilterSet::Match: match: bSenderMatch:" << bSenderMatch << " - bRcvMatch:" << bRcvMatch << std::endl;
		}
	}
	std::clog << "FilterSet::Match: match after loop: bSenderMatch:" << bSenderMatch << " - bRcvMatch:" << bRcvMatch << " - bEmptyFilterSet:" << bEmptyFilterSet << std::endl;
	if( (pProtocolInfo->GetId() == EProtocolType_Udp) 
	    || (pProtocolInfo->GetId() == EProtocolType_Tcp)) {
	    || (pProtocolInfo->GetId() == EProtocolType_Tcp) || (pProtocolInfo->GetId() == EProtocolType_IPv6)) {
	  if ((bSenderMatch || bRcvMatch) || bEmptyFilterSet) // TODO: To be removed
			std::clog << "<<< FilterSet::Match: true" << std::endl;
	  else
			std::clog << "<<< FilterSet::Match: false" << std::endl;
	  return (bSenderMatch || bRcvMatch) || bEmptyFilterSet; 
	}
	
  if ((bSenderMatch && bRcvMatch) || bEmptyFilterSet) // TODO: To be removed
		std::clog << "<<< FilterSet::Match: true" << std::endl;
  else
		std::clog << "<<< FilterSet::Match: false" << std::endl;
	return (bSenderMatch && bRcvMatch) || bEmptyFilterSet; 
}

+1 −1
Original line number Diff line number Diff line
@@ -19,7 +19,7 @@ IpDissector * IpDissector::Clone() const {
}

bool IpDissector::Dissect(const unsigned char * pData, ssize_t nDataLen) {
	std::clog << ">>> IpDissector::Dissect: " << pData << std::endl;
	std::clog << ">>> IpDissector::Dissect: " << nDataLen << std::endl;
	
  if (!m_ipHdr)
	  m_ipHdr = new IpHeader;
+1 −1
Original line number Diff line number Diff line
@@ -40,7 +40,7 @@ bool IpFilter::SetAddress(const std::string sAddr)

bool IpFilter::Match(const ProtocolInfoElement * pProtocolInfo)
{
	std::clog << ">>> Ipv6Filter::Match: " << pProtocolInfo->ToString() << std::endl;
	std::clog << ">>> IpFilter::Match: " << pProtocolInfo->ToString() << std::endl;

	if (pProtocolInfo->GetId() != EProtocolType_IPv4)
		return false;
+123 −10
Original line number Diff line number Diff line
#include "Ipv6Dissector.h"
#ifdef WIN32
#include <Winsock2.h>
#else
#include <netinet/in.h>
#endif

Ipv6Dissector::Ipv6Dissector() :
	m_ipHdr(0)
@@ -19,7 +14,7 @@ Ipv6Dissector * Ipv6Dissector::Clone() const {
}

bool Ipv6Dissector::Dissect(const unsigned char * pData, ssize_t nDataLen) {
	std::clog << ">>> Ipv6Dissector::Dissect: " << pData << std::endl;
	std::clog << ">>> Ipv6Dissector::Dissect: " << nDataLen << std::endl;
	
  if (!m_ipHdr)
	  m_ipHdr = new IpHeader;
@@ -28,6 +23,7 @@ bool Ipv6Dissector::Dissect(const unsigned char * pData, ssize_t nDataLen) {
#if BYTE_ORDER == LITTLE_ENDIAN
  m_ipHdr->payloadLength = ntohs(m_ipHdr->payloadLength);
#endif
	std::clog << "Ipv6Dissector::Dissect: payload length=" << m_ipHdr->payloadLength << std::endl;
  SavePayload(pData, m_ipHdr->payloadLength);
  SaveLayerInfo();
  return true;
@@ -67,13 +63,130 @@ ProtocolInfoElement * Ipv6Dissector::CreateLayerInfo()
	std::clog << ">>> Ipv6Dissector::CreateLayerInfo" << std::endl;
	
	IPv6Info * pRes = new IPv6Info();
	std::vector<unsigned char> nSrcAddr(16), nDstAddr(16);
	/*std::vector<unsigned char> nSrcAddr(16), nDstAddr(16);
	for (int i = 0; i < nSrcAddr.size(); i++)
	{
		nSrcAddr[i] = m_ipHdr->srcAddr[i];
		nDstAddr[i] = m_ipHdr->destAddr[i];
	}
	pRes->SetSourceAddress(nSrcAddr);
	pRes->SetDestinationAddress(nDstAddr);
	}*/
	char buffer[128] = {0};
  InetNtop((const unsigned char *)&m_ipHdr->srcAddr[0], buffer, 128);
	std::clog << "Ipv6Dissector::CreateLayerInfo (src): " << buffer << std::endl;
	pRes->SetSourceAddress(std::string(buffer));
	memset(buffer, 0x00, 128);
  InetNtop((const unsigned char *)m_ipHdr->srcAddr, buffer, 128);
	std::clog << "Ipv6Dissector::CreateLayerInfo (dest): " << buffer << std::endl;
	pRes->SetDestinationAddress(std::string(buffer));
	return pRes;
}

/**
	This is a copy of IPv6 inet_ntop C function
	Warning: encapsulated IPv4 not supported
	http://www.koders.com/c/fid8E3CB9FE9913C1E6C2E8316BAB79203D6241AED9.aspx
  **/
#define NS_IN6ADDRSZ 16
#define NS_INT16SZ 2
const char *Ipv6Dissector::InetNtop (const unsigned char *src, char *dst, socklen_t size)
{
  /*
   * Note that int32_t and int16_t need only be "at least" large enough
   * to contain a value of the specified size.  On some systems, like
   * Crays, there is no such thing as an integer variable with 16 bits.
   * Keep this in mind if you think this function should have been coded
   * to use pointer overlays.  All the world's not a VAX.
   */
  char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
  struct
  {
    int base, len;
  } best, cur;
  unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ];
  int i;

  /*
   * Preprocess:
   *      Copy the input (bytewise) array into a wordwise array.
   *      Find the longest run of 0x00's in src[] for :: shorthanding.
   */
  memset (words, '\0', sizeof words);
  for (i = 0; i < NS_IN6ADDRSZ; i += 2)
    words[i / 2] = (src[i] << 8) | src[i + 1];
  best.base = -1;
  cur.base = -1;
  for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++)
    {
      if (words[i] == 0)
	{
	  if (cur.base == -1)
	    cur.base = i, cur.len = 1;
	  else
	    cur.len++;
	}
      else
	{
	  if (cur.base != -1)
	    {
	      if (best.base == -1 || cur.len > best.len)
		best = cur;
	      cur.base = -1;
	    }
	}
    }
  if (cur.base != -1)
    {
      if (best.base == -1 || cur.len > best.len)
	best = cur;
    }
  if (best.base != -1 && best.len < 2)
    best.base = -1;

  /*
   * Format the result.
   */
  tp = tmp;
  for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++)
    {
      /* Are we inside the best run of 0x00's? */
      if (best.base != -1 && i >= best.base && i < (best.base + best.len))
	{
	  if (i == best.base)
	    *tp++ = ':';
	  continue;
	}
      /* Are we following an initial run of 0x00s or any real hex? */
      if (i != 0)
	*tp++ = ':';
      /* Is this address an encapsulated IPv4? */
      if (i == 6 && best.base == 0 &&
	  (best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
	{
	  //if (!inet_ntop4 (src + 12, tp, sizeof tmp - (tp - tmp)))
	    return (NULL);
	  //tp += strlen (tp);
	  //break;
	}
      {
	int len = sprintf (tp, "%x", words[i]);
	if (len < 0)
	  return NULL;
	tp += len;
      }
    }
  /* Was it a trailing run of 0x00's? */
  if (best.base != -1 && (best.base + best.len) ==
      (NS_IN6ADDRSZ / NS_INT16SZ))
    *tp++ = ':';
  *tp++ = '\0';

  /*
   * Check for overflow, copy, and we're done.
   */
  if ((socklen_t) (tp - tmp) > size)
    {
      errno = ENOSPC;
      return NULL;
    }

  return strcpy (dst, tmp);
}
Loading