mirror of
https://github.com/mfontanini/libtins
synced 2026-01-23 02:35:57 +01:00
PacketSender is not copyable and movable.
This commit is contained in:
@@ -58,8 +58,7 @@ subdir = .
|
||||
DIST_COMMON = README $(am__configure_deps) $(libtins_include_HEADERS) \
|
||||
$(srcdir)/Makefile.am $(srcdir)/Makefile.in \
|
||||
$(srcdir)/libtins.pc.in $(top_srcdir)/configure AUTHORS THANKS \
|
||||
TODO config.guess config.sub depcomp install-sh ltmain.sh \
|
||||
missing
|
||||
config.guess config.sub depcomp install-sh ltmain.sh missing
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
|
||||
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
#define TINS_CXXSTD_GCC_FIX 0
|
||||
#endif // __GXX_EXPERIMENTAL_CXX0X__
|
||||
|
||||
#define TINS_IS_CXX11 (__cplusplus > 199711L || TINS_CXXSTD_GCC_FIX == 1)
|
||||
|
||||
namespace Tins{
|
||||
namespace Internals {
|
||||
template<typename T>
|
||||
@@ -51,6 +53,4 @@ struct smart_ptr {
|
||||
}
|
||||
}
|
||||
|
||||
#define TINS_IS_CXX11 (__cplusplus > 199711L || TINS_CXXSTD_GCC_FIX == 1)
|
||||
|
||||
#endif // TINS_CXXSTD_H
|
||||
|
||||
@@ -86,6 +86,44 @@ public:
|
||||
return "Invalid interface";
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Exception thrown when PacketSender fails to open a socket.
|
||||
*/
|
||||
class socket_open_error : public std::runtime_error {
|
||||
public:
|
||||
socket_open_error(const std::string &msg)
|
||||
: std::runtime_error(msg) { }
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Exception thrown when PacketSender fails to close a socket.
|
||||
*/
|
||||
class socket_close_error : public std::runtime_error {
|
||||
public:
|
||||
socket_close_error(const std::string &msg)
|
||||
: std::runtime_error(msg) { }
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Exception thrown when PacketSender fails to write on a socket.
|
||||
*/
|
||||
class socket_write_error : public std::runtime_error {
|
||||
public:
|
||||
socket_write_error(const std::string &msg)
|
||||
: std::runtime_error(msg) { }
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Exception thrown when an invalid socket type is provided
|
||||
* to PacketSender.
|
||||
*/
|
||||
class invalid_socket_type : public std::exception {
|
||||
public:
|
||||
const char *what() const throw() {
|
||||
return "The provided socket type is invalid";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TINS_EXCEPTIONS_H
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <map>
|
||||
#include "network_interface.h"
|
||||
#include "macros.h"
|
||||
#include "cxxstd.h"
|
||||
|
||||
struct timeval;
|
||||
struct sockaddr;
|
||||
@@ -80,6 +81,20 @@ namespace Tins {
|
||||
PacketSender(const NetworkInterface &iface = NetworkInterface(),
|
||||
uint32_t recv_timeout = DEFAULT_TIMEOUT, uint32_t usec = 0);
|
||||
|
||||
#if TINS_IS_CXX11
|
||||
/**
|
||||
* \brief Move constructor.
|
||||
* \param rhs The sender to be moved.
|
||||
*/
|
||||
PacketSender(PacketSender &&rhs);
|
||||
|
||||
/**
|
||||
* \brief Move assignment operator.
|
||||
* \param rhs The sender to be moved.
|
||||
*/
|
||||
PacketSender& operator=(PacketSender &&rhs);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief PacketSender destructor.
|
||||
*
|
||||
@@ -91,7 +106,7 @@ namespace Tins {
|
||||
/**
|
||||
* \brief Opens a layer 2 socket.
|
||||
*
|
||||
* If this operation fails, then a SocketOpenError will be thrown.
|
||||
* If this operation fails, then a socket_open_error will be thrown.
|
||||
*/
|
||||
void open_l2_socket(const NetworkInterface& iface = NetworkInterface());
|
||||
#endif // WIN32
|
||||
@@ -100,9 +115,9 @@ namespace Tins {
|
||||
* \brief Opens a layer 3 socket, using the corresponding protocol
|
||||
* for the given flag.
|
||||
*
|
||||
* If this operation fails, then a SocketOpenError will be thrown.
|
||||
* If the provided socket type is not valid, a InvalidSocketTypeError
|
||||
* will be throw.
|
||||
* If this operation fails, then a socket_open_error will be thrown.
|
||||
* If the provided socket type is not valid, an invalid_socket_type
|
||||
* exception will be throw.
|
||||
*
|
||||
* \param type The type of socket which will be used to pick the protocol flag
|
||||
* for this socket.
|
||||
@@ -113,9 +128,9 @@ namespace Tins {
|
||||
* \brief Closes the socket associated with the given flag.
|
||||
*
|
||||
* If the provided type is invalid, meaning no such open socket
|
||||
* exists, a InvalidSocketTypeError is thrown.
|
||||
* exists, an invalid_socket_type exception is thrown.
|
||||
*
|
||||
* If any socket close errors are encountered, a SocketCloseError
|
||||
* If any socket close errors are encountered, a socket_close_error
|
||||
* is thrown.
|
||||
*
|
||||
* \param type The type of the socket to be closed.
|
||||
@@ -143,7 +158,7 @@ namespace Tins {
|
||||
* This method opens the appropriate socket, if it's not open yet,
|
||||
* and sends the PDU on the open socket.
|
||||
*
|
||||
* If any send error occurs, then a SocketWriteError is thrown.
|
||||
* If any send error occurs, then a socket_write_error is thrown.
|
||||
*
|
||||
* If the PDU contains a link layer protocol, then default_interface
|
||||
* is used.
|
||||
@@ -220,7 +235,7 @@ namespace Tins {
|
||||
* using the corresponding flag, according to the given type of
|
||||
* protocol.
|
||||
*
|
||||
* If any socket write error occurs, a SocketWriteError is thrown.
|
||||
* If any socket write error occurs, a socket_write_error is thrown.
|
||||
*
|
||||
* \param pdu The PDU to send.
|
||||
* \param link_addr The sockaddr struct which will be used to send the PDU.
|
||||
@@ -250,7 +265,7 @@ namespace Tins {
|
||||
* This method sends a layer 3 PDU, using a raw socket, open using the corresponding flag,
|
||||
* according to the given type of protocol.
|
||||
*
|
||||
* If any socket write error occurs, a SocketWriteError is thrown.
|
||||
* If any socket write error occurs, a socket_write_error is thrown.
|
||||
*
|
||||
* \param pdu The PDU to send.
|
||||
* \param link_addr The sockaddr struct which will be used to send the PDU.
|
||||
@@ -263,6 +278,8 @@ namespace Tins {
|
||||
|
||||
typedef std::map<SocketType, int> SocketTypeMap;
|
||||
|
||||
PacketSender(const PacketSender&);
|
||||
PacketSender& operator=(const PacketSender&);
|
||||
int find_type(SocketType type);
|
||||
int timeval_subtract (struct timeval *result, struct timeval *x, struct timeval *y);
|
||||
#ifndef WIN32
|
||||
@@ -289,32 +306,6 @@ namespace Tins {
|
||||
uint32_t _timeout, _timeout_usec;
|
||||
NetworkInterface default_iface;
|
||||
};
|
||||
|
||||
|
||||
class SocketOpenError : public std::runtime_error {
|
||||
public:
|
||||
SocketOpenError(const std::string &msg)
|
||||
: std::runtime_error(msg) { }
|
||||
};
|
||||
|
||||
class SocketCloseError : public std::runtime_error {
|
||||
public:
|
||||
SocketCloseError(const std::string &msg)
|
||||
: std::runtime_error(msg) { }
|
||||
};
|
||||
|
||||
class SocketWriteError : public std::runtime_error {
|
||||
public:
|
||||
SocketWriteError(const std::string &msg)
|
||||
: std::runtime_error(msg) { }
|
||||
};
|
||||
|
||||
class InvalidSocketTypeError : public std::exception {
|
||||
public:
|
||||
const char *what() const throw() {
|
||||
return "The provided socket type is invalid";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TINS_PACKET_SENDER_H
|
||||
|
||||
@@ -97,6 +97,33 @@ PacketSender::PacketSender(const NetworkInterface &iface, uint32_t recv_timeout,
|
||||
_types[ICMP_SOCKET] = IPPROTO_ICMP;
|
||||
}
|
||||
|
||||
#if TINS_IS_CXX11
|
||||
PacketSender::PacketSender(PacketSender &&rhs)
|
||||
{
|
||||
*this = std::move(rhs);
|
||||
}
|
||||
|
||||
PacketSender& PacketSender::operator=(PacketSender &&rhs)
|
||||
{
|
||||
_sockets = std::move(rhs._sockets);
|
||||
rhs._sockets = std::vector<int>(SOCKETS_END, INVALID_RAW_SOCKET);
|
||||
#ifndef WIN32
|
||||
#if defined(BSD) || defined(__FreeBSD_kernel__)
|
||||
_ether_socket = std::move(rhs._ether_socket);
|
||||
#else
|
||||
_ether_socket = rhs._ether_socket;
|
||||
rhs._ether_socket = INVALID_RAW_SOCKET;
|
||||
#endif
|
||||
#endif
|
||||
_types = rhs._types; // no move
|
||||
_timeout = rhs._timeout;
|
||||
_timeout_usec = rhs._timeout_usec;
|
||||
default_iface = rhs.default_iface;
|
||||
return *this;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
PacketSender::~PacketSender() {
|
||||
for(unsigned i(0); i < _sockets.size(); ++i) {
|
||||
if(_sockets[i] != INVALID_RAW_SOCKET)
|
||||
@@ -153,13 +180,13 @@ void PacketSender::open_l2_socket(const NetworkInterface& iface) {
|
||||
sock = open(oss.str().c_str(), O_RDWR);
|
||||
}
|
||||
if(sock == -1)
|
||||
throw SocketOpenError(make_error_string());
|
||||
throw socket_open_error(make_error_string());
|
||||
|
||||
struct ifreq ifr;
|
||||
strncpy(ifr.ifr_name, iface.name().c_str(), sizeof(ifr.ifr_name) - 1);
|
||||
if(ioctl(sock, BIOCSETIF, (caddr_t)&ifr) < 0) {
|
||||
::close(sock);
|
||||
throw SocketOpenError(make_error_string());
|
||||
throw socket_open_error(make_error_string());
|
||||
}
|
||||
_ether_socket[iface.id()] = sock;
|
||||
#else
|
||||
@@ -167,7 +194,7 @@ void PacketSender::open_l2_socket(const NetworkInterface& iface) {
|
||||
_ether_socket = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
|
||||
|
||||
if (_ether_socket == -1)
|
||||
throw SocketOpenError(make_error_string());
|
||||
throw socket_open_error(make_error_string());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -176,12 +203,12 @@ void PacketSender::open_l2_socket(const NetworkInterface& iface) {
|
||||
void PacketSender::open_l3_socket(SocketType type) {
|
||||
int socktype = find_type(type);
|
||||
if(socktype == -1)
|
||||
throw InvalidSocketTypeError();
|
||||
throw invalid_socket_type();
|
||||
if(_sockets[type] == INVALID_RAW_SOCKET) {
|
||||
int sockfd;
|
||||
sockfd = socket((type == IPV6_SOCKET) ? AF_INET6 : AF_INET, SOCK_RAW, socktype);
|
||||
if (sockfd < 0)
|
||||
throw SocketOpenError(make_error_string());
|
||||
throw socket_open_error(make_error_string());
|
||||
|
||||
const int on = 1;
|
||||
#ifndef WIN32
|
||||
@@ -200,24 +227,24 @@ void PacketSender::close_socket(SocketType type, const NetworkInterface &iface)
|
||||
#if defined(BSD) || defined(__FreeBSD_kernel__)
|
||||
BSDEtherSockets::iterator it = _ether_socket.find(iface.id());
|
||||
if(it == _ether_socket.end())
|
||||
throw InvalidSocketTypeError();
|
||||
throw invalid_socket_type();
|
||||
if(::close(it->second) == -1)
|
||||
throw SocketCloseError(make_error_string());
|
||||
throw socket_close_error(make_error_string());
|
||||
_ether_socket.erase(it);
|
||||
#elif !defined(WIN32)
|
||||
if(_ether_socket == INVALID_RAW_SOCKET)
|
||||
throw InvalidSocketTypeError();
|
||||
throw invalid_socket_type();
|
||||
if(::close(_ether_socket) == -1)
|
||||
throw SocketCloseError(make_error_string());
|
||||
throw socket_close_error(make_error_string());
|
||||
_ether_socket = INVALID_RAW_SOCKET;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
if(type >= SOCKETS_END || _sockets[type] == INVALID_RAW_SOCKET)
|
||||
throw InvalidSocketTypeError();
|
||||
throw invalid_socket_type();
|
||||
#ifndef WIN32
|
||||
if(close(_sockets[type]) == -1)
|
||||
throw SocketCloseError(make_error_string());
|
||||
throw socket_close_error(make_error_string());
|
||||
#else
|
||||
closesocket(_sockets[type]);
|
||||
#endif
|
||||
@@ -275,7 +302,7 @@ void PacketSender::send_l2(PDU &pdu, struct sockaddr* link_addr,
|
||||
#else
|
||||
if(::sendto(sock, &buffer[0], buffer.size(), 0, link_addr, len_addr) == -1)
|
||||
#endif
|
||||
throw SocketWriteError(make_error_string());
|
||||
throw socket_write_error(make_error_string());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,7 +324,7 @@ void PacketSender::send_l3(PDU &pdu, struct sockaddr* link_addr, uint32_t len_ad
|
||||
int sock = _sockets[type];
|
||||
PDU::serialization_type buffer = pdu.serialize();
|
||||
if(sendto(sock, (const char*)&buffer[0], buffer.size(), 0, link_addr, len_addr) == -1)
|
||||
throw SocketWriteError(make_error_string());
|
||||
throw socket_write_error(make_error_string());
|
||||
}
|
||||
|
||||
PDU *PacketSender::recv_match_loop(int sock, PDU &pdu, struct sockaddr* link_addr, uint32_t addrlen) {
|
||||
|
||||
Reference in New Issue
Block a user