libtins  4.4
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 
118 class TINS_API PacketSender {
119 public:
123  static const uint32_t DEFAULT_TIMEOUT;
124 
128  enum SocketType {
129  ETHER_SOCKET,
130  IP_TCP_SOCKET,
131  IP_UDP_SOCKET,
132  IP_RAW_SOCKET,
133  ARP_SOCKET,
134  ICMP_SOCKET,
135  IPV6_SOCKET,
136  ICMPV6_SOCKET,
137  SOCKETS_END
138  };
139 
147  uint32_t recv_timeout = DEFAULT_TIMEOUT,
148  uint32_t usec = 0);
149 
150  #if TINS_IS_CXX11
155  PacketSender(PacketSender &&rhs) TINS_NOEXCEPT {
156  *this = std::move(rhs);
157  }
158 
163  PacketSender& operator=(PacketSender &&rhs) TINS_NOEXCEPT {
164  sockets_ = std::move(rhs.sockets_);
165  rhs.sockets_ = std::vector<int>(SOCKETS_END, INVALID_RAW_SOCKET);
166  #ifndef _WIN32
167  #if defined(BSD) || defined(__FreeBSD_kernel__)
168  ether_socket_ = std::move(rhs.ether_socket_);
169  #else
170  ether_socket_ = rhs.ether_socket_;
171  rhs.ether_socket_ = INVALID_RAW_SOCKET;
172  #endif
173  #endif
174  types_ = rhs.types_; // no move
175  _timeout = rhs._timeout;
176  timeout_usec_ = rhs.timeout_usec_;
177  default_iface_ = rhs.default_iface_;
178  return* this;
179  }
180  #endif
181 
187  ~PacketSender();
188 
189  #if !defined(_WIN32) || defined(TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET)
195  void open_l2_socket(const NetworkInterface& iface = NetworkInterface());
196  #endif // !_WIN32 || defined(TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET)
197 
209  void open_l3_socket(SocketType type);
210 
222  void close_socket(SocketType type, const NetworkInterface& iface = NetworkInterface());
223 
230  void default_interface(const NetworkInterface& iface);
231 
237  const NetworkInterface& default_interface() const;
238 
254  void send(PDU& pdu);
255 
271  void send(PDU& pdu, const NetworkInterface& iface);
272 
294  PDU* send_recv(PDU& pdu);
295 
307  PDU* send_recv(PDU& pdu, const NetworkInterface& iface);
308 
309  #ifndef _WIN32
324  PDU* recv_l2(PDU& pdu, struct sockaddr* link_addr, uint32_t len_addr,
325  const NetworkInterface& iface = NetworkInterface());
326 
327  #endif // _WIN32
328 
329  #if !defined(_WIN32) || defined(TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET)
345  void send_l2(PDU& pdu, struct sockaddr* link_addr, uint32_t len_addr,
346  const NetworkInterface& iface = NetworkInterface());
347  #endif // !_WIN32 || TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET
348 
363  PDU* recv_l3(PDU& pdu, struct sockaddr* link_addr, uint32_t len_addr, SocketType type);
364 
380  void send_l3(PDU& pdu, struct sockaddr* link_addr, uint32_t len_addr, SocketType type);
381 private:
382  static const int INVALID_RAW_SOCKET;
383 
384  typedef std::map<SocketType, int> SocketTypeMap;
385 
386  PacketSender(const PacketSender&);
387  PacketSender& operator=(const PacketSender&);
388  int find_type(SocketType type);
389  #ifndef _WIN32
390  bool ether_socket_initialized(const NetworkInterface& iface = NetworkInterface()) const;
391  int get_ether_socket(const NetworkInterface& iface = NetworkInterface());
392  #endif
393  template<typename T>
394  void send(PDU& pdu, const NetworkInterface& iface) {
395  static_cast<T&>(pdu).send(*this, iface);
396  }
397  #ifdef TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET
398  pcap_t* make_pcap_handle(const NetworkInterface& iface) const;
399  #endif // TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET
400 
401  PDU* recv_match_loop(const std::vector<int>& sockets,
402  PDU& pdu,
403  struct sockaddr* link_addr,
404  uint32_t addrlen,
405  bool is_layer_3);
406 
407  std::vector<int> sockets_;
408  #ifndef _WIN32
409  #if defined(BSD) || defined(__FreeBSD_kernel__)
410  typedef std::map<uint32_t, int> BSDEtherSockets;
411  BSDEtherSockets ether_socket_;
412  #else
413  int ether_socket_;
414  #endif
415  #endif
416  SocketTypeMap types_;
417  uint32_t _timeout, timeout_usec_;
418  NetworkInterface default_iface_;
419  // In BSD we need to store the buffer size, retrieved using BIOCGBLEN
420  #if defined(BSD) || defined(__FreeBSD_kernel__)
421  int buffer_size_;
422  #endif // BSD
423  #ifdef TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET
424  typedef std::map<NetworkInterface, pcap_t*> PcapHandleMap;
425  PcapHandleMap pcap_handles_;
426  #endif // TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET
427 };
428 
429 } // Tins
430 
431 #endif // TINS_PACKET_SENDER_H
Abstraction of a network interface.
Definition: network_interface.h:47
Base class for protocol data units.
Definition: pdu.h:107
Sends packets through a network interface.
Definition: packet_sender.h:118
static const uint32_t DEFAULT_TIMEOUT
Definition: packet_sender.h:123
SocketType
Definition: packet_sender.h:128
PacketSender(PacketSender &&rhs) TINS_NOEXCEPT
Move constructor.
Definition: packet_sender.h:155
PacketSender & operator=(PacketSender &&rhs) TINS_NOEXCEPT
Move assignment operator.
Definition: packet_sender.h:163
The Tins namespace.
Definition: address_range.h:38