libtins  4.0
packet_sender.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_PACKET_SENDER_H
31 #define TINS_PACKET_SENDER_H
32 
33 
34 #include <string>
35 #include <vector>
36 #include <stdint.h>
37 #include <map>
38 #include <tins/config.h>
39 #ifdef TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET
40  #include <pcap.h>
41 #endif // TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET
42 #include <tins/network_interface.h>
43 #include <tins/macros.h>
44 #include <tins/cxxstd.h>
45 
46 struct timeval;
47 struct sockaddr;
48 
49 namespace Tins {
50 
51 class PDU;
52 
116 class TINS_API PacketSender {
117 public:
121  static const uint32_t DEFAULT_TIMEOUT;
122 
126  enum SocketType {
127  ETHER_SOCKET,
128  IP_TCP_SOCKET,
129  IP_UDP_SOCKET,
130  IP_RAW_SOCKET,
131  ARP_SOCKET,
132  ICMP_SOCKET,
133  IPV6_SOCKET,
134  ICMPV6_SOCKET,
135  SOCKETS_END
136  };
137 
145  uint32_t recv_timeout = DEFAULT_TIMEOUT,
146  uint32_t usec = 0);
147 
148  #if TINS_IS_CXX11
149 
153  PacketSender(PacketSender &&rhs) TINS_NOEXCEPT {
154  *this = std::move(rhs);
155  }
156 
161  PacketSender& operator=(PacketSender &&rhs) TINS_NOEXCEPT {
162  sockets_ = std::move(rhs.sockets_);
163  rhs.sockets_ = std::vector<int>(SOCKETS_END, INVALID_RAW_SOCKET);
164  #ifndef _WIN32
165  #if defined(BSD) || defined(__FreeBSD_kernel__)
166  ether_socket_ = std::move(rhs.ether_socket_);
167  #else
168  ether_socket_ = rhs.ether_socket_;
169  rhs.ether_socket_ = INVALID_RAW_SOCKET;
170  #endif
171  #endif
172  types_ = rhs.types_; // no move
173  _timeout = rhs._timeout;
174  timeout_usec_ = rhs.timeout_usec_;
175  default_iface_ = rhs.default_iface_;
176  return* this;
177  }
178  #endif
179 
185  ~PacketSender();
186 
187  #if !defined(_WIN32) || defined(TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET)
188 
193  void open_l2_socket(const NetworkInterface& iface = NetworkInterface());
194  #endif // !_WIN32 || defined(TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET)
195 
207  void open_l3_socket(SocketType type);
208 
220  void close_socket(SocketType type, const NetworkInterface& iface = NetworkInterface());
221 
228  void default_interface(const NetworkInterface& iface);
229 
235  const NetworkInterface& default_interface() const;
236 
252  void send(PDU& pdu);
253 
269  void send(PDU& pdu, const NetworkInterface& iface);
270 
292  PDU* send_recv(PDU& pdu);
293 
305  PDU* send_recv(PDU& pdu, const NetworkInterface& iface);
306 
307  #ifndef _WIN32
308 
322  PDU* recv_l2(PDU& pdu, struct sockaddr* link_addr, uint32_t len_addr,
323  const NetworkInterface& iface = NetworkInterface());
324 
325  #endif // _WIN32
326 
327  #if !defined(_WIN32) || defined(TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET)
328 
343  void send_l2(PDU& pdu, struct sockaddr* link_addr, uint32_t len_addr,
344  const NetworkInterface& iface = NetworkInterface());
345  #endif // !_WIN32 || TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET
346 
361  PDU* recv_l3(PDU& pdu, struct sockaddr* link_addr, uint32_t len_addr, SocketType type);
362 
378  void send_l3(PDU& pdu, struct sockaddr* link_addr, uint32_t len_addr, SocketType type);
379 private:
380  static const int INVALID_RAW_SOCKET;
381 
382  typedef std::map<SocketType, int> SocketTypeMap;
383 
384  PacketSender(const PacketSender&);
385  PacketSender& operator=(const PacketSender&);
386  int find_type(SocketType type);
387  #ifndef _WIN32
388  bool ether_socket_initialized(const NetworkInterface& iface = NetworkInterface()) const;
389  int get_ether_socket(const NetworkInterface& iface = NetworkInterface());
390  #endif
391  template<typename T>
392  void send(PDU& pdu, const NetworkInterface& iface) {
393  static_cast<T&>(pdu).send(*this, iface);
394  }
395  #ifdef TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET
396  pcap_t* make_pcap_handle(const NetworkInterface& iface) const;
397  #endif // TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET
398 
399  PDU* recv_match_loop(const std::vector<int>& sockets,
400  PDU& pdu,
401  struct sockaddr* link_addr,
402  uint32_t addrlen,
403  bool is_layer_3);
404 
405  std::vector<int> sockets_;
406  #ifndef _WIN32
407  #if defined(BSD) || defined(__FreeBSD_kernel__)
408  typedef std::map<uint32_t, int> BSDEtherSockets;
409  BSDEtherSockets ether_socket_;
410  #else
411  int ether_socket_;
412  #endif
413  #endif
414  SocketTypeMap types_;
415  uint32_t _timeout, timeout_usec_;
416  NetworkInterface default_iface_;
417  // In BSD we need to store the buffer size, retrieved using BIOCGBLEN
418  #if defined(BSD) || defined(__FreeBSD_kernel__)
419  int buffer_size_;
420  #endif // BSD
421  #ifdef TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET
422  typedef std::map<NetworkInterface, pcap_t*> PcapHandleMap;
423  PcapHandleMap pcap_handles_;
424  #endif // TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET
425 };
426 
427 } // Tins
428 
429 #endif // TINS_PACKET_SENDER_H
SocketType
Definition: packet_sender.h:126
PacketSender & operator=(PacketSender &&rhs) TINS_NOEXCEPT
Move assignment operator.
Definition: packet_sender.h:161
Sends packets through a network interface.
Definition: packet_sender.h:116
static const uint32_t DEFAULT_TIMEOUT
Definition: packet_sender.h:121
The Tins namespace.
Definition: address_range.h:38
PacketSender(PacketSender &&rhs) TINS_NOEXCEPT
Move constructor.
Definition: packet_sender.h:153
Abstraction of a network interface.
Definition: network_interface.h:47
Base class for protocol data units.
Definition: pdu.h:107