source: trunk/ETSI-Testsuites/ETSI_auto_IOT/adapter/src/Dispatcher/IpDissector.cpp @ 27

Last change on this file since 27 was 22, checked in by rings, 14 years ago
  • Property svn:executable set to *
File size: 4.1 KB
Line 
1#include "IpDissector.h"
2#ifdef WIN32
3#include <Winsock2.h>
4#else
5#include <netinet/in.h>
6#endif
7
8IpDissector::IpDissector() :
9        m_ipHdr(0)
10{
11}
12
13IpDissector::~IpDissector() {
14  delete m_ipHdr;
15}
16
17IpDissector * IpDissector::Clone() const {
18  return new IpDissector();
19}
20
21bool IpDissector::Dissect(const unsigned char * pData, ssize_t nDataLen) {
22  if (!m_ipHdr)
23          m_ipHdr = new IpHeader;
24  memcpy(m_ipHdr, pData, sizeof(IpHeader));
25  pData += sizeof(IpHeader);
26#if BYTE_ORDER == LITTLE_ENDIAN
27  m_ipHdr->totalLength = ntohs(m_ipHdr->totalLength);
28#endif
29  SavePayload(pData, m_ipHdr->totalLength - m_ipHdr->headerLength*4);
30  SaveLayerInfo();
31  return true;
32}
33
34bool IpDissector::NeedReassembly() const {
35  if(m_ipHdr->moreFragment || m_ipHdr->fragOffset || m_ipHdr->fragOffset1)
36    return true;
37  return false;
38}
39
40bool IpDissector::Reassemble(Dissector * pDissector, ProtocolInfo * pProtocolInfo) {
41  if(!NeedReassembly())
42    return false;
43 
44  if(m_holes.size() == 0)
45    {
46      // No hole defined even thougth reassembly is needed
47      // It means that Reassemble is called for first time
48      // Initialize reassembly structure and add self
49      m_holes.push_back(std::pair<unsigned short, unsigned short>(0, (unsigned short)(- 1)));
50      Reassemble(this, pProtocolInfo);
51    }
52 
53  // Inspect potential fragment
54  IpDissector * pIpDissector = dynamic_cast<IpDissector *>(pDissector);
55  if((pIpDissector->m_ipHdr) && (pIpDissector->m_ipHdr->id == m_ipHdr->id))
56    {
57      // Build First and Last values
58      unsigned short nFirstFragmentByte = pIpDissector->m_ipHdr->fragOffset;
59      nFirstFragmentByte = nFirstFragmentByte << 8;
60      nFirstFragmentByte += pIpDissector->m_ipHdr->fragOffset1;
61      nFirstFragmentByte *= 8;
62
63      unsigned short nLastFragmentByte = nFirstFragmentByte
64        + pIpDissector->m_ipHdr->totalLength
65        - pIpDissector->m_ipHdr->headerLength * 4;
66
67      // Compare to missing data
68      std::list<std::pair<unsigned short, unsigned short> >::iterator it;
69      int nPayloadSize = GetPayloadSize();
70      for(it = m_holes.begin(); it != m_holes.end(); ++it)
71        {
72          if(nFirstFragmentByte > (*it).second)
73            continue;
74          if(nLastFragmentByte < (*it).first)
75            continue;
76          if(!pIpDissector->m_ipHdr->moreFragment)
77            {
78              // Last fragment received
79              (*it).second = nLastFragmentByte;
80              nPayloadSize = nLastFragmentByte;
81            }
82       
83          if(nFirstFragmentByte > (*it).first)
84            m_holes.push_back(std::pair<unsigned short, unsigned short>((*it).first, nFirstFragmentByte - 1));
85          if(nLastFragmentByte < (*it).second)
86            m_holes.push_back(std::pair<unsigned short, unsigned short>(nLastFragmentByte + 1, (*it).second));
87          m_holes.erase(it);
88          std::pair<const unsigned char *, const ssize_t> data = pIpDissector->DetachData();
89          m_fragments[nFirstFragmentByte] = data.first;
90          m_fragmentSizes[nFirstFragmentByte] = data.second;
91
92      // received fragment is not needed anymore
93      if(pIpDissector != this)
94            delete pIpDissector;
95
96      // check if packet is now complete
97      if(m_holes.size() == 0)
98          {
99        m_ipHdr->moreFragment = 0;
100            m_ipHdr->fragOffset = 0;
101            m_ipHdr->fragOffset1 = 0;   
102         
103            // Reassembly !
104            ssize_t nOffset = 0;
105            AllocPayload(nPayloadSize); // payloadSize is valid since last fragment has been received
106            while((nOffset != nPayloadSize) && (m_fragments.find(nOffset) != m_fragments.end()))
107              {
108                SetPayloadAt(m_fragments[nOffset], m_fragmentSizes[nOffset], nOffset);
109                // Clean up
110                delete m_fragments[nOffset];
111                nOffset += m_fragmentSizes[nOffset];
112              }
113            m_fragments.clear();
114            m_fragmentSizes.clear();
115          }
116          return true;
117        }
118    }
119  return false;
120}
121
122const EProtocolType IpDissector::GetUpperLayerType() const
123{
124        EProtocolType res = EProtocolType_Unknown;
125        switch(m_ipHdr->protocol)
126        {
127        case 6:
128                res = EProtocolType_Tcp;
129                break;
130        case 17:
131                res = EProtocolType_Udp;
132                break;
133        }
134        return res;
135}
136
137ProtocolInfoElement * IpDissector::CreateLayerInfo()
138{
139        IPv4Info * pRes = new IPv4Info();
140        unsigned int nSrcAddr, nDstAddr;
141        memcpy(&nSrcAddr, m_ipHdr->srcAddr, sizeof(int));
142        memcpy(&nDstAddr, m_ipHdr->destAddr, sizeof(int));
143        pRes->SetSourceAddress(nSrcAddr);
144        pRes->SetDestinationAddress(nDstAddr);
145        return pRes;
146}
Note: See TracBrowser for help on using the repository browser.