libtins  4.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Pages
ip_reassembler.h
1 /*
2  * Copyright (c) 2017, Matias Fontanini
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above
12  * copyright notice, this list of conditions and the following disclaimer
13  * in the documentation and/or other materials provided with the
14  * distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  */
29 
30 #ifndef TINS_IP_REASSEMBLER_H
31 #define TINS_IP_REASSEMBLER_H
32 
33 #include <vector>
34 #include <map>
35 #include <tins/pdu.h>
36 #include <tins/macros.h>
37 #include <tins/ip_address.h>
38 #include <tins/ip.h>
39 
40 namespace Tins {
41 
45 namespace Internals {
46 class IPv4Fragment {
47 public:
48  typedef PDU::serialization_type payload_type;
49 
50  IPv4Fragment() : offset_() { }
51 
52  template<typename T>
53  IPv4Fragment(T* pdu, uint16_t offset)
54  : payload_(pdu->serialize()), offset_(offset) {
55 
56  }
57 
58  const payload_type& payload() const {
59  return payload_;
60  }
61 
62  uint16_t offset() const {
63  return offset_;
64  }
65 private:
66  payload_type payload_;
67  uint16_t offset_;
68 };
69 
70 class TINS_API IPv4Stream {
71 public:
72  IPv4Stream();
73 
74  void add_fragment(IP* ip);
75  bool is_complete() const;
76  PDU* allocate_pdu() const;
77  const IP& first_fragment() const;
78 private:
79  typedef std::vector<IPv4Fragment> fragments_type;
80 
81  uint16_t extract_offset(const IP* ip);
82  bool extract_more_frag(const IP* ip);
83 
84  fragments_type fragments_;
85  size_t received_size_;
86  size_t total_size_;
87  IP first_fragment_;
88  bool received_end_;
89 };
90 } // namespace Internals
91 
120 class TINS_API IPv4Reassembler {
121 public:
128  REASSEMBLED
129  };
130 
131  TINS_DEPRECATED(typedef PacketStatus packet_status);
132 
138  NONE
139  };
140 
144  IPv4Reassembler();
145 
152  IPv4Reassembler(OverlappingTechnique technique);
153 
168  PacketStatus process(PDU& pdu);
169 
173  void clear_streams();
174 
185  void remove_stream(uint16_t id, IPv4Address addr1, IPv4Address addr2);
186 private:
187  typedef std::pair<IPv4Address, IPv4Address> address_pair;
188  typedef std::pair<uint16_t, address_pair> key_type;
189  typedef std::map<key_type, Internals::IPv4Stream> streams_type;
190 
191  key_type make_key(const IP* ip) const;
192  address_pair make_address_pair(IPv4Address addr1, IPv4Address addr2) const;
193 
194  streams_type streams_;
195  OverlappingTechnique technique_;
196 };
197 
201 template<typename Functor>
203 public:
209  IPv4ReassemblerProxy(Functor func)
210  : functor_(func) {
211 
212  }
213 
222  bool operator()(PDU& pdu) {
223  // Forward it unless it's fragmented.
224  if (reassembler_.process(pdu) != IPv4Reassembler::FRAGMENTED) {
225  return functor_(pdu);
226  }
227  else {
228  return true;
229  }
230  }
231 private:
232  IPv4Reassembler reassembler_;
233  Functor functor_;
234 };
235 
242 template<typename Functor>
244  return IPv4ReassemblerProxy<Functor>(func);
245 }
246 
247 } // Tins
248 
249 #endif // TINS_IP_REASSEMBLER_H
Class that represents an IP PDU.
Definition: ip.h:63
OverlappingTechnique
Definition: ip_reassembler.h:137
PacketStatus
Definition: ip_reassembler.h:125
IPv4ReassemblerProxy(Functor func)
Definition: ip_reassembler.h:209
bool operator()(PDU &pdu)
Tries to reassemble the packet and forwards it to the functor.
Definition: ip_reassembler.h:222
Definition: ip_reassembler.h:202
IPv4ReassemblerProxy< Functor > make_ipv4_reassembler_proxy(Functor func)
Definition: ip_reassembler.h:243
The given packet is not fragmented.
Definition: ip_reassembler.h:126
Abstraction of an IPv4 address.
Definition: ip_address.h:45
PacketStatus process(PDU &pdu)
Processes a PDU and tries to reassemble it.
Definition: ip_reassembler.cpp:119
byte_array serialization_type
Definition: pdu.h:112
The given packet is fragmented and can't be reassembled yet.
Definition: ip_reassembler.h:127
Base class for protocol data units.
Definition: pdu.h:107
Reassembles fragmented IP packets.
Definition: ip_reassembler.h:120