mirror of
https://github.com/mfontanini/libtins
synced 2026-01-23 02:35:57 +01:00
PacketSender now throws on error. Fixed the documentation on several header files.
This commit is contained in:
@@ -19,7 +19,7 @@ portscan:
|
||||
$(CXX) portscan.cpp -o portscan $(CXXFLAGS) $(LDFLAGS) -lpthread
|
||||
|
||||
traceroute:
|
||||
$(CXX) traceroute.cpp -o traceroute -std=c++0x $(CXXFLAGS) $(LDFLAGS)
|
||||
$(CXX) traceroute.cpp -o traceroute -std=c++0x $(CXXFLAGS) $(LDFLAGS) -lpthread
|
||||
|
||||
.cpp.o:
|
||||
$(CXX) $(CXXFLAGS) $(INCLUDE) $< -o $@
|
||||
|
||||
@@ -80,8 +80,8 @@ int do_arp_spoofing(NetworkInterface iface, IPv4Address gw, IPv4Address victim,
|
||||
EthernetII to_victim(iface, victim_hw, info.hw_addr, victim_arp);
|
||||
while(true) {
|
||||
// Just send them once every 5 seconds.
|
||||
if(!sender.send(to_gw) || !sender.send(to_victim))
|
||||
return 7;
|
||||
sender.send(to_gw);
|
||||
sender.send(to_victim);
|
||||
sleep(5);
|
||||
}
|
||||
}
|
||||
@@ -114,6 +114,12 @@ int main(int argc, char *argv[]) {
|
||||
cout << ex.what() << endl;
|
||||
return 3;
|
||||
}
|
||||
return do_arp_spoofing(iface, gw, victim, info);
|
||||
try {
|
||||
return do_arp_spoofing(iface, gw, victim, info);
|
||||
}
|
||||
catch(std::runtime_error &ex) {
|
||||
std::cout << "Runtime error: " << ex.what() << std::endl;
|
||||
return 7;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -76,6 +76,7 @@ private:
|
||||
// ICMPs are icmp-requests by default
|
||||
IP ip(addr, iface.addresses().ip_addr, new ICMP());
|
||||
// We'll find at most 10 hops.
|
||||
|
||||
for(auto i = 1; i <= 10; ++i) {
|
||||
// Set this "unique" id
|
||||
ip.id(i);
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
|
||||
namespace Tins {
|
||||
class NetworkInterface;
|
||||
class EthernetII;
|
||||
|
||||
/**
|
||||
* \brief Class that represents an ARP PDU.
|
||||
@@ -91,63 +92,63 @@ namespace Tins {
|
||||
/**
|
||||
* \brief Getter for the sender's hardware address.
|
||||
*
|
||||
* \return Returns the sender's hardware address in an uint8_t*.
|
||||
* \return The sender hardware address.
|
||||
*/
|
||||
hwaddress_type sender_hw_addr() const { return _arp.ar_sha; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the sender's IP address.
|
||||
*
|
||||
* \return Returns the sender's IP address in an uint32_t.
|
||||
* \return The sender IP address.
|
||||
*/
|
||||
ipaddress_type sender_ip_addr() const { return ipaddress_type(_arp.ar_sip); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the target's hardware address.
|
||||
*
|
||||
* \return Returns the target's hardware address in an uint8_t*.
|
||||
* \return The target hardware address.
|
||||
*/
|
||||
hwaddress_type target_hw_addr() const { return _arp.ar_tha; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the target's IP address.
|
||||
*
|
||||
* \return Returns the target's IP address in an uint32_t.
|
||||
* \return The target IP address.
|
||||
*/
|
||||
ipaddress_type target_ip_addr() const { return ipaddress_type(_arp.ar_tip); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the hardware address format.
|
||||
*
|
||||
* \return Returns the hardware address' format in an uint16_t.
|
||||
* \return The hardware address format.
|
||||
*/
|
||||
uint16_t hw_addr_format() const { return Endian::be_to_host(_arp.ar_hrd); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the protocol address format.
|
||||
*
|
||||
* \return Returns the protocol address' format in an uint16_t.
|
||||
* \return The protocol address format.
|
||||
*/
|
||||
uint16_t prot_addr_format() const { return Endian::be_to_host(_arp.ar_pro); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the hardware address length.
|
||||
*
|
||||
* \return Returns the hardware address' length in an uint8_t.
|
||||
* \return The hardware address length.
|
||||
*/
|
||||
uint8_t hw_addr_length() const { return _arp.ar_hln; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the protocol address length.
|
||||
*
|
||||
* \return Returns the protocol address' length in an uint8_t.
|
||||
* \return The protocol address length.
|
||||
*/
|
||||
uint8_t prot_addr_length() const { return _arp.ar_pln; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the ARP opcode.
|
||||
*
|
||||
* \return Returns the ARP opcode in an uint16_t.
|
||||
* \return The ARP opcode.
|
||||
*/
|
||||
uint16_t opcode() const { return Endian::be_to_host(_arp.ar_op); }
|
||||
|
||||
@@ -161,56 +162,56 @@ namespace Tins {
|
||||
/**
|
||||
* \brief Setter for the sender's hardware address.
|
||||
*
|
||||
* \param new_snd_hw_addr uint8_t array containing the new sender's hardware address.
|
||||
* \param new_snd_hw_addr The new sender hardware address.
|
||||
*/
|
||||
void sender_hw_addr(const hwaddress_type &new_snd_hw_addr);
|
||||
|
||||
/**
|
||||
* \brief Setter for the sender's IP address.
|
||||
*
|
||||
* \param new_snd_ip_addr IPv4Address containing the new sender's IP address.
|
||||
* \param new_snd_ip_addr The new sender IP address.
|
||||
*/
|
||||
void sender_ip_addr(ipaddress_type new_snd_ip_addr);
|
||||
|
||||
/**
|
||||
* \brief Setter for the target's hardware address.
|
||||
*
|
||||
* \param new_tgt_hw_addr uint8_t array containing the new target's hardware address.
|
||||
* \param new_tgt_hw_addr The new target hardware address.
|
||||
*/
|
||||
void target_hw_addr(const hwaddress_type &new_tgt_hw_addr);
|
||||
|
||||
/**
|
||||
* \brief Setter for the target's IP address.
|
||||
*
|
||||
* \param new_tgt_ip_addr IPv4Address containing the new target's IP address.
|
||||
* \param new_tgt_ip_addr The new target IP address.
|
||||
*/
|
||||
void target_ip_addr(ipaddress_type new_tgt_ip_addr);
|
||||
|
||||
/**
|
||||
* \brief Setter for the hardware address format.
|
||||
*
|
||||
* \param new_hw_addr_fmt uint16_t with the new hardware address' format.
|
||||
* \param new_hw_addr_fmt The new hardware address format.
|
||||
*/
|
||||
void hw_addr_format(uint16_t new_hw_addr_fmt);
|
||||
|
||||
/**
|
||||
* \brief Setter for the protocol address format.
|
||||
*
|
||||
* \param new_prot_addr_fmt uint16_t with the new protocol address' format.
|
||||
* \param new_prot_addr_fmt The new protocol address format.
|
||||
*/
|
||||
void prot_addr_format(uint16_t new_prot_addr_fmt);
|
||||
|
||||
/**
|
||||
* \brief Setter for the hardware address length.
|
||||
*
|
||||
* \param new_hw_addr_len uint8_t with the new hardware address' length.
|
||||
* \param new_hw_addr_len The new hardware address length.
|
||||
*/
|
||||
void hw_addr_length(uint8_t new_hw_addr_len);
|
||||
|
||||
/**
|
||||
* \brief Setter for the protocol address length.
|
||||
*
|
||||
* \param new_prot_addr_len uint8_t with the new protocol address' length.
|
||||
* \param new_prot_addr_len The new protocol address length.
|
||||
*/
|
||||
void prot_addr_length(uint8_t new_prot_addr_len);
|
||||
|
||||
@@ -237,9 +238,9 @@ namespace Tins {
|
||||
* \param target IPv4Address with the target's IP.
|
||||
* \param sender IPv4Address with the sender's IP.
|
||||
* \param hw_snd uint8_t array of 6 bytes containing the sender's hardware address.
|
||||
* \return Returns a PDU* to the new Layer 2 PDU containing the ARP Request.
|
||||
* \return Returns a EthernetII containing the ARP Request.
|
||||
*/
|
||||
static PDU* make_arp_request(const NetworkInterface& iface, ipaddress_type target,
|
||||
static EthernetII make_arp_request(const NetworkInterface& iface, ipaddress_type target,
|
||||
ipaddress_type sender, const hwaddress_type &hw_snd = hwaddress_type());
|
||||
|
||||
/**
|
||||
@@ -253,9 +254,9 @@ namespace Tins {
|
||||
* \param sender IPv4Address with the sender's IP.
|
||||
* \param hw_tgt uint8_t array of 6 bytes containing the target's hardware address.
|
||||
* \param hw_snd uint8_t array of 6 bytes containing the sender's hardware address.
|
||||
* \return Returns a PDU* to the new Layer 2 PDU containing the ARP Replay.
|
||||
* \return Returns an EthetnetII containing the ARP Replay.
|
||||
*/
|
||||
static PDU* make_arp_reply(const NetworkInterface& iface, ipaddress_type target,
|
||||
static EthernetII make_arp_reply(const NetworkInterface& iface, ipaddress_type target,
|
||||
ipaddress_type sender, const hwaddress_type &hw_tgt = hwaddress_type(),
|
||||
const hwaddress_type &hw_snd = hwaddress_type());
|
||||
|
||||
|
||||
@@ -386,7 +386,7 @@ namespace Tins {
|
||||
/**
|
||||
* \sa PDU::send()
|
||||
*/
|
||||
bool send(PacketSender &sender);
|
||||
void send(PacketSender &sender);
|
||||
#endif // WIN32
|
||||
|
||||
/**
|
||||
|
||||
@@ -157,7 +157,7 @@ namespace Tins {
|
||||
/**
|
||||
* \sa PDU::send()
|
||||
*/
|
||||
bool send(PacketSender &sender);
|
||||
void send(PacketSender &sender);
|
||||
#endif // WIN32
|
||||
|
||||
/** \brief Check wether ptr points to a valid response for this PDU.
|
||||
|
||||
@@ -66,11 +66,11 @@ namespace Tins {
|
||||
* destination's and source's MAC.
|
||||
*
|
||||
* \param iface string containing the interface's name from where to send the packet.
|
||||
* \param dst_hw_addr uint8_t array of 6 bytes containing the destination's MAC(optional).
|
||||
* \param src_hw_addr uint8_t array of 6 bytes containing the source's MAC(optional).
|
||||
* \param child PDU* with the PDU contained by the ethernet PDU (optional).
|
||||
* \param dst_hw_addr The destination hardware address.
|
||||
* \param src_hw_addr The source hardware address.
|
||||
* \param child The PDU which will be set as the inner PDU.
|
||||
*/
|
||||
IEEE802_3(const NetworkInterface& iface,
|
||||
IEEE802_3(const NetworkInterface& iface = NetworkInterface(),
|
||||
const address_type &dst_hw_addr = address_type(),
|
||||
const address_type &src_hw_addr = address_type(),
|
||||
PDU* child = 0);
|
||||
@@ -85,23 +85,23 @@ namespace Tins {
|
||||
|
||||
/* Getters */
|
||||
/**
|
||||
* \brief Getter for the destination's mac address.
|
||||
* \brief Getter for the destination hardware address.
|
||||
*
|
||||
* \return Returns the destination's mac address as a constant uint8_t pointer.
|
||||
* \return The destination hardware address.
|
||||
*/
|
||||
address_type dst_addr() const { return _eth.dst_mac; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the source's mac address.
|
||||
* \brief Getter for the source hardware address.
|
||||
*
|
||||
* \return Returns the source's mac address as a constant uint8_t pointer.
|
||||
* \return The source hardware address.
|
||||
*/
|
||||
address_type src_addr() const { return _eth.src_mac; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the interface.
|
||||
*
|
||||
* \return Returns the interface's index as an uint32_t.
|
||||
* \return The network interface.
|
||||
*/
|
||||
const NetworkInterface &iface() const { return this->_iface; }
|
||||
|
||||
@@ -114,25 +114,25 @@ namespace Tins {
|
||||
/* Setters */
|
||||
|
||||
/**
|
||||
* \brief Setter for the destination's MAC.
|
||||
* \brief Setter for the destination hardware address.
|
||||
*
|
||||
* \param new_dst_mac uint8_t array of 6 bytes containing the new destination's MAC.
|
||||
* \param new_dst_mac The new destination hardware address.
|
||||
*/
|
||||
void dst_addr(const address_type &new_dst_mac);
|
||||
|
||||
/**
|
||||
* \brief Setter for the source's MAC.
|
||||
* \brief Setter for the source hardware address.
|
||||
*
|
||||
* \param new_src_mac uint8_t array of 6 bytes containing the new source's MAC.
|
||||
* \param new_src_mac The new source hardware address.
|
||||
*/
|
||||
void src_addr(const address_type &new_src_mac);
|
||||
|
||||
/**
|
||||
* \brief Setter for the interface.
|
||||
*
|
||||
* \param new_iface_index uint32_t containing the new interface index.
|
||||
* \param new_iface The interface in which to send this PDU.
|
||||
*/
|
||||
void iface(const NetworkInterface &new_iface_index);
|
||||
void iface(const NetworkInterface &new_iface);
|
||||
|
||||
/**
|
||||
* \brief Setter for the length field.
|
||||
@@ -154,7 +154,7 @@ namespace Tins {
|
||||
/**
|
||||
* \sa PDU::send()
|
||||
*/
|
||||
bool send(PacketSender &sender);
|
||||
void send(PacketSender &sender);
|
||||
#endif // WIN32
|
||||
|
||||
/** \brief Check wether ptr points to a valid response for this PDU.
|
||||
@@ -180,7 +180,8 @@ namespace Tins {
|
||||
*/
|
||||
PDUType pdu_type() const { return PDU::IEEE802_3; }
|
||||
|
||||
/** \brief Clones this pdu, filling the corresponding header with data
|
||||
/**
|
||||
* \brief Clones this pdu, filling the corresponding header with data
|
||||
* extracted from a buffer.
|
||||
*
|
||||
* \param ptr The pointer to the from from which the data will be extracted.
|
||||
|
||||
@@ -318,7 +318,7 @@ namespace Tins {
|
||||
/**
|
||||
* \brief Setter for the header length field.
|
||||
*
|
||||
* \param new_head_len uint8_t with the new header length.
|
||||
* \param new_head_len The new header length.
|
||||
*/
|
||||
void head_len(small_uint<4> new_head_len);
|
||||
|
||||
@@ -533,7 +533,7 @@ namespace Tins {
|
||||
/**
|
||||
* \sa PDU::send()
|
||||
*/
|
||||
bool send(PacketSender &sender);
|
||||
void send(PacketSender &sender);
|
||||
|
||||
/**
|
||||
* \brief Check wether ptr points to a valid response for this PDU.
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
#define TINS_PACKET_SENDER_H
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
#include <map>
|
||||
@@ -48,11 +50,13 @@ namespace Tins {
|
||||
*/
|
||||
class PacketSender {
|
||||
public:
|
||||
/** \brief The default timeout for receive actions.
|
||||
/**
|
||||
* The default timeout for receive actions.
|
||||
*/
|
||||
static const uint32_t DEFAULT_TIMEOUT;
|
||||
|
||||
/** \brief Flags to indicate the socket type.
|
||||
/**
|
||||
* Flags to indicate the socket type.
|
||||
*/
|
||||
enum SocketType {
|
||||
ETHER_SOCKET,
|
||||
@@ -69,46 +73,62 @@ namespace Tins {
|
||||
*/
|
||||
PacketSender(uint32_t recv_timeout = DEFAULT_TIMEOUT, uint32_t usec = 0);
|
||||
|
||||
/** \brief PacketSender destructor.
|
||||
/**
|
||||
* \brief PacketSender destructor.
|
||||
*
|
||||
* This gracefully closes all open sockets.
|
||||
*/
|
||||
~PacketSender();
|
||||
|
||||
#ifndef WIN32
|
||||
/** \brief Opens a layer y socket.
|
||||
/**
|
||||
* \brief Opens a layer 2 socket.
|
||||
*
|
||||
* \return Returns true if the socket was open successfully, false otherwise.
|
||||
* If this operation fails, then a SocketOpenError will be thrown.
|
||||
*/
|
||||
bool open_l2_socket();
|
||||
void open_l2_socket();
|
||||
#endif // WIN32
|
||||
|
||||
/** \brief Opens a layer 3 socket, using the corresponding protocol
|
||||
/**
|
||||
* \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.
|
||||
*
|
||||
* \param type The type of socket which will be used to pick the protocol flag
|
||||
* for this socket.
|
||||
* \return Returns true if the socket was open successfully, false otherwise.
|
||||
*/
|
||||
bool open_l3_socket(SocketType type);
|
||||
void open_l3_socket(SocketType type);
|
||||
|
||||
/** \brief Closes the socket associated with the given flag.
|
||||
/**
|
||||
* \brief Closes the socket associated with the given flag.
|
||||
*
|
||||
* \param flag
|
||||
* \return Returns true if the socket was closed successfully, false otherwise.
|
||||
* If the provided type is invalid, meaning no such open socket
|
||||
* exists, a InvalidSocketTypeError is thrown.
|
||||
*
|
||||
* If any socket close errors are encountered, a SocketCloseError
|
||||
* is thrown.
|
||||
*
|
||||
* \param type The type of the socket to be closed.
|
||||
*/
|
||||
bool close_socket(uint32_t flag);
|
||||
void close_socket(SocketType type);
|
||||
|
||||
/** \brief Sends a PDU.
|
||||
/**
|
||||
* \brief Sends a PDU.
|
||||
*
|
||||
* This method is used to send PDUs. It opens the required socket(if it's not open yet).
|
||||
* This method opens the appropriate socket, if it's not open yet,
|
||||
* and sends the PDU on the open socket.
|
||||
*
|
||||
* \param pdu The PDU to send.
|
||||
* \return Returns true if the PDU is sent successfully, false otherwise.
|
||||
* If any send error occurs, then a SocketWriteError is thrown.
|
||||
*
|
||||
* \param pdu The PDU to be sent.
|
||||
*/
|
||||
bool send(PDU &pdu);
|
||||
void send(PDU &pdu);
|
||||
|
||||
/** \brief Sends a PDU and waits for its response.
|
||||
/**
|
||||
* \brief Sends a PDU and waits for its response.
|
||||
*
|
||||
* This method is used to send PDUs and receive their response.
|
||||
* It opens the required socket(if it's not open yet). This can be used
|
||||
@@ -121,7 +141,8 @@ namespace Tins {
|
||||
PDU *send_recv(PDU &pdu);
|
||||
|
||||
#ifndef WIN32
|
||||
/** \brief Receives a layer 2 PDU response to a previously sent PDU.
|
||||
/**
|
||||
* \brief Receives a layer 2 PDU response to a previously sent PDU.
|
||||
*
|
||||
* This PacketSender will receive data from a raw socket, open using the corresponding flag,
|
||||
* according to the given type of protocol, until a match for the given PDU is received.
|
||||
@@ -133,20 +154,24 @@ namespace Tins {
|
||||
*/
|
||||
PDU *recv_l2(PDU &pdu, struct sockaddr *link_addr, uint32_t len_addr);
|
||||
|
||||
/** \brief Sends a level 2 PDU.
|
||||
/**
|
||||
* \brief Sends a level 2 PDU.
|
||||
*
|
||||
* This method sends a layer 2 PDU, using a raw socket, open using the corresponding flag,
|
||||
* according to the given type of protocol.
|
||||
* This method sends a layer 2 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.
|
||||
*
|
||||
* \param pdu The PDU to send.
|
||||
* \param link_addr The sockaddr struct which will be used to send the PDU.
|
||||
* \param len_addr The sockaddr struct length.
|
||||
* \return Returns true if the PDU was successfully sent, false otherwise.
|
||||
*/
|
||||
bool send_l2(PDU &pdu, struct sockaddr* link_addr, uint32_t len_addr);
|
||||
void send_l2(PDU &pdu, struct sockaddr* link_addr, uint32_t len_addr);
|
||||
#endif // WIN32
|
||||
|
||||
/** \brief Receives a layer 3 PDU response to a previously sent PDU.
|
||||
/**
|
||||
* \brief Receives a layer 3 PDU response to a previously sent PDU.
|
||||
*
|
||||
* This PacketSender will receive data from a raw socket, open using the corresponding flag,
|
||||
* according to the given type of protocol, until a match for the given PDU is received.
|
||||
@@ -159,18 +184,20 @@ namespace Tins {
|
||||
*/
|
||||
PDU *recv_l3(PDU &pdu, struct sockaddr *link_addr, uint32_t len_addr, SocketType type);
|
||||
|
||||
/** \brief Sends a level 3 PDU.
|
||||
/**
|
||||
* \brief Sends a level 3 PDU.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* \param pdu The PDU to send.
|
||||
* \param link_addr The sockaddr struct which will be used to send the PDU.
|
||||
* \param len_addr The sockaddr struct length.
|
||||
* \param type The socket protocol type.
|
||||
* \return Returns true if the PDU was successfully sent, false otherwise.
|
||||
*/
|
||||
bool send_l3(PDU &pdu, struct sockaddr *link_addr, uint32_t len_addr, SocketType type);
|
||||
void send_l3(PDU &pdu, struct sockaddr *link_addr, uint32_t len_addr, SocketType type);
|
||||
private:
|
||||
static const int INVALID_RAW_SOCKET;
|
||||
|
||||
@@ -185,6 +212,32 @@ namespace Tins {
|
||||
SocketTypeMap _types;
|
||||
uint32_t _timeout, _timeout_usec;
|
||||
};
|
||||
|
||||
|
||||
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
|
||||
|
||||
@@ -215,7 +215,7 @@ namespace Tins {
|
||||
* those methods.
|
||||
* \param sender The PacketSender which will send the packet.
|
||||
*/
|
||||
virtual bool send(PacketSender &sender);
|
||||
virtual void send(PacketSender &sender);
|
||||
|
||||
/** \brief Receives a matching response for this packet.
|
||||
*
|
||||
|
||||
@@ -127,7 +127,7 @@ namespace Tins {
|
||||
/**
|
||||
* \sa PDU::send()
|
||||
*/
|
||||
bool send(PacketSender &sender);
|
||||
void send(PacketSender &sender);
|
||||
|
||||
/**
|
||||
* \brief Setter for the version field.
|
||||
@@ -280,12 +280,14 @@ namespace Tins {
|
||||
* \brief Getter for the present bit fields.
|
||||
*
|
||||
* Use this method and masks created from the values taken from
|
||||
* the PresentFlags enum to find out which fields are set. If any
|
||||
* getter is used for a non-initialized field, the return value
|
||||
* the PresentFlags enum to find out which fields are set.
|
||||
* Accessing non-initialized fields, the behaviour is undefined
|
||||
* will be undefined. It is only safe to use the getter of a field
|
||||
* if its corresponding bit flag is set in the present field.
|
||||
*/
|
||||
PresentFlags present() const { return (PresentFlags)*(uint32_t*)(&_radio.it_len + 1); }
|
||||
PresentFlags present() const {
|
||||
return (PresentFlags)*(uint32_t*)(&_radio.it_len + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the RadioTap frame's header length.
|
||||
|
||||
13
src/arp.cpp
13
src/arp.cpp
@@ -132,8 +132,8 @@ PDU *ARP::clone_packet(const uint8_t *ptr, uint32_t total_sz) {
|
||||
return cloned;
|
||||
}
|
||||
|
||||
PDU* ARP::make_arp_request(const NetworkInterface& iface, ipaddress_type target,
|
||||
ipaddress_type sender, const hwaddress_type &hw_snd)
|
||||
EthernetII ARP::make_arp_request(const NetworkInterface& iface,
|
||||
ipaddress_type target, ipaddress_type sender, const hwaddress_type &hw_snd)
|
||||
{
|
||||
/* Create ARP packet and set its attributes */
|
||||
ARP* arp = new ARP();
|
||||
@@ -143,11 +143,11 @@ PDU* ARP::make_arp_request(const NetworkInterface& iface, ipaddress_type target,
|
||||
arp->opcode(REQUEST);
|
||||
|
||||
/* Create the EthernetII PDU with the ARP PDU as its inner PDU */
|
||||
return new EthernetII(iface, EthernetII::BROADCAST, hw_snd, arp);
|
||||
return EthernetII(iface, EthernetII::BROADCAST, hw_snd, arp);
|
||||
}
|
||||
|
||||
PDU* ARP::make_arp_reply(const NetworkInterface& iface, ipaddress_type target,
|
||||
ipaddress_type sender, const hwaddress_type &hw_tgt,
|
||||
EthernetII ARP::make_arp_reply(const NetworkInterface& iface,
|
||||
ipaddress_type target, ipaddress_type sender, const hwaddress_type &hw_tgt,
|
||||
const hwaddress_type &hw_snd)
|
||||
{
|
||||
/* Create ARP packet and set its attributes */
|
||||
@@ -155,7 +155,6 @@ PDU* ARP::make_arp_reply(const NetworkInterface& iface, ipaddress_type target,
|
||||
arp->opcode(REPLY);
|
||||
|
||||
/* Create the EthernetII PDU with the ARP PDU as its inner PDU */
|
||||
EthernetII* eth = new EthernetII(iface, hw_tgt, hw_snd, arp);
|
||||
return eth;
|
||||
return EthernetII(iface, hw_tgt, hw_snd, arp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,7 +166,10 @@ uint32_t Dot11::header_size() const {
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
bool Dot11::send(PacketSender &sender) {
|
||||
void Dot11::send(PacketSender &sender) {
|
||||
if(!_iface)
|
||||
throw std::runtime_error("Interface has not been set");
|
||||
|
||||
struct sockaddr_ll addr;
|
||||
|
||||
memset(&addr, 0, sizeof(struct sockaddr_ll));
|
||||
@@ -177,7 +180,7 @@ bool Dot11::send(PacketSender &sender) {
|
||||
addr.sll_ifindex = _iface.id();
|
||||
memcpy(&(addr.sll_addr), _header.addr1, 6);
|
||||
|
||||
return sender.send_l2(*this, (struct sockaddr*)&addr, (uint32_t)sizeof(addr));
|
||||
sender.send_l2(*this, (struct sockaddr*)&addr, (uint32_t)sizeof(addr));
|
||||
}
|
||||
#endif // WIN32
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ uint32_t EthernetII::header_size() const {
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
bool EthernetII::send(PacketSender &sender) {
|
||||
void EthernetII::send(PacketSender &sender) {
|
||||
if(!_iface)
|
||||
throw std::runtime_error("Interface has not been set");
|
||||
struct sockaddr_ll addr;
|
||||
@@ -117,7 +117,7 @@ bool EthernetII::send(PacketSender &sender) {
|
||||
addr.sll_ifindex = _iface.id();
|
||||
memcpy(&(addr.sll_addr), _eth.dst_mac, address_type::address_size);
|
||||
|
||||
return sender.send_l2(*this, (struct sockaddr*)&addr, (uint32_t)sizeof(addr));
|
||||
sender.send_l2(*this, (struct sockaddr*)&addr, (uint32_t)sizeof(addr));
|
||||
}
|
||||
#endif // WIN32
|
||||
|
||||
|
||||
@@ -88,7 +88,10 @@ uint32_t IEEE802_3::header_size() const {
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
bool IEEE802_3::send(PacketSender &sender) {
|
||||
void IEEE802_3::send(PacketSender &sender) {
|
||||
if(!_iface)
|
||||
throw std::runtime_error("Interface has not been set");
|
||||
|
||||
struct sockaddr_ll addr;
|
||||
|
||||
memset(&addr, 0, sizeof(struct sockaddr_ll));
|
||||
@@ -99,7 +102,7 @@ bool IEEE802_3::send(PacketSender &sender) {
|
||||
addr.sll_ifindex = _iface.id();
|
||||
memcpy(&(addr.sll_addr), _eth.dst_mac, sizeof(_eth.dst_mac));
|
||||
|
||||
return sender.send_l2(*this, (struct sockaddr*)&addr, (uint32_t)sizeof(addr));
|
||||
sender.send_l2(*this, (struct sockaddr*)&addr, (uint32_t)sizeof(addr));
|
||||
}
|
||||
#endif // WIN32
|
||||
|
||||
|
||||
@@ -332,7 +332,7 @@ uint32_t IP::header_size() const {
|
||||
return sizeof(iphdr) + _padded_options_size;
|
||||
}
|
||||
|
||||
bool IP::send(PacketSender& sender) {
|
||||
void IP::send(PacketSender& sender) {
|
||||
struct sockaddr_in link_addr;
|
||||
PacketSender::SocketType type = PacketSender::IP_SOCKET;
|
||||
link_addr.sin_family = AF_INET;
|
||||
@@ -341,7 +341,7 @@ bool IP::send(PacketSender& sender) {
|
||||
if(inner_pdu() && inner_pdu()->pdu_type() == PDU::ICMP)
|
||||
type = PacketSender::ICMP_SOCKET;
|
||||
|
||||
return sender.send_l3(*this, (struct sockaddr*)&link_addr, sizeof(link_addr), type);
|
||||
sender.send_l3(*this, (struct sockaddr*)&link_addr, sizeof(link_addr), type);
|
||||
}
|
||||
|
||||
PDU *IP::recv_response(PacketSender &sender) {
|
||||
|
||||
@@ -37,28 +37,39 @@
|
||||
#include <linux/if_packet.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <errno.h>
|
||||
#else
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
#include <cassert>
|
||||
#include <errno.h>
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include "pdu.h"
|
||||
#include "packet_sender.h"
|
||||
|
||||
|
||||
const int Tins::PacketSender::INVALID_RAW_SOCKET = -1;
|
||||
const uint32_t Tins::PacketSender::DEFAULT_TIMEOUT = 2;
|
||||
namespace Tins {
|
||||
const int PacketSender::INVALID_RAW_SOCKET = -1;
|
||||
const uint32_t PacketSender::DEFAULT_TIMEOUT = 2;
|
||||
|
||||
Tins::PacketSender::PacketSender(uint32_t recv_timeout, uint32_t usec) :
|
||||
_sockets(SOCKETS_END, INVALID_RAW_SOCKET), _timeout(recv_timeout), _timeout_usec(usec) {
|
||||
#ifndef WIN32
|
||||
const char *make_error_string() {
|
||||
return strerror(errno);
|
||||
}
|
||||
#else
|
||||
|
||||
#endif
|
||||
|
||||
PacketSender::PacketSender(uint32_t recv_timeout, uint32_t usec) :
|
||||
_sockets(SOCKETS_END, INVALID_RAW_SOCKET), _timeout(recv_timeout),
|
||||
_timeout_usec(usec)
|
||||
{
|
||||
_types[IP_SOCKET] = IPPROTO_RAW;
|
||||
_types[ICMP_SOCKET] = IPPROTO_ICMP;
|
||||
}
|
||||
|
||||
Tins::PacketSender::~PacketSender() {
|
||||
PacketSender::~PacketSender() {
|
||||
for(unsigned i(0); i < _sockets.size(); ++i) {
|
||||
if(_sockets[i] != INVALID_RAW_SOCKET)
|
||||
#ifndef WIN32
|
||||
@@ -70,101 +81,95 @@ Tins::PacketSender::~PacketSender() {
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
bool Tins::PacketSender::open_l2_socket() {
|
||||
if (_sockets[ETHER_SOCKET] != INVALID_RAW_SOCKET)
|
||||
return true;
|
||||
int sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
|
||||
if (sock == -1)
|
||||
return false;
|
||||
_sockets[ETHER_SOCKET] = sock;
|
||||
return true;
|
||||
void PacketSender::open_l2_socket() {
|
||||
if (_sockets[ETHER_SOCKET] == INVALID_RAW_SOCKET) {
|
||||
int sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
|
||||
if (sock == -1)
|
||||
throw SocketOpenError(make_error_string());
|
||||
_sockets[ETHER_SOCKET] = sock;
|
||||
}
|
||||
}
|
||||
#endif // WIN32
|
||||
|
||||
bool Tins::PacketSender::open_l3_socket(SocketType type) {
|
||||
void PacketSender::open_l3_socket(SocketType type) {
|
||||
int socktype = find_type(type);
|
||||
if(socktype == -1)
|
||||
return false;
|
||||
if(_sockets[type] != INVALID_RAW_SOCKET)
|
||||
return true;
|
||||
int sockfd;
|
||||
sockfd = socket(AF_INET, SOCK_RAW, socktype);
|
||||
if (sockfd < 0)
|
||||
return false;
|
||||
throw InvalidSocketTypeError();
|
||||
if(_sockets[type] == INVALID_RAW_SOCKET) {
|
||||
int sockfd;
|
||||
sockfd = socket(AF_INET, SOCK_RAW, socktype);
|
||||
if (sockfd < 0)
|
||||
throw SocketOpenError(make_error_string());
|
||||
|
||||
const int on = 1;
|
||||
const int on = 1;
|
||||
#ifndef WIN32
|
||||
typedef const void* option_ptr;
|
||||
#else
|
||||
typedef const char* option_ptr;
|
||||
#endif
|
||||
setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL,(option_ptr)&on,sizeof(on));
|
||||
|
||||
_sockets[type] = sockfd;
|
||||
}
|
||||
}
|
||||
|
||||
void PacketSender::close_socket(SocketType type) {
|
||||
if(type >= SOCKETS_END || _sockets[type] == INVALID_RAW_SOCKET)
|
||||
throw InvalidSocketTypeError();
|
||||
#ifndef WIN32
|
||||
typedef const void* option_ptr;
|
||||
if(close(_sockets[type]) == -1)
|
||||
throw SocketCloseError(make_error_string());
|
||||
#else
|
||||
typedef const char* option_ptr;
|
||||
closesocket(_sockets[type]);
|
||||
#endif
|
||||
setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL,(option_ptr)&on,sizeof(on));
|
||||
|
||||
_sockets[type] = sockfd;
|
||||
return true;
|
||||
_sockets[type] = INVALID_RAW_SOCKET;
|
||||
}
|
||||
|
||||
bool Tins::PacketSender::close_socket(uint32_t flag) {
|
||||
if(flag >= SOCKETS_END || _sockets[flag] == INVALID_RAW_SOCKET)
|
||||
return false;
|
||||
#ifndef WIN32
|
||||
close(_sockets[flag]);
|
||||
#else
|
||||
closesocket(_sockets[flag]);
|
||||
#endif
|
||||
_sockets[flag] = INVALID_RAW_SOCKET;
|
||||
return true;
|
||||
void PacketSender::send(PDU &pdu) {
|
||||
pdu.send(*this);
|
||||
}
|
||||
|
||||
bool Tins::PacketSender::send(PDU &pdu) {
|
||||
return pdu.send(*this);
|
||||
}
|
||||
|
||||
Tins::PDU *Tins::PacketSender::send_recv(PDU &pdu) {
|
||||
if(!pdu.send(*this))
|
||||
PDU *PacketSender::send_recv(PDU &pdu) {
|
||||
try {
|
||||
pdu.send(*this);
|
||||
}
|
||||
catch(std::runtime_error&) {
|
||||
return 0;
|
||||
}
|
||||
return pdu.recv_response(*this);
|
||||
}
|
||||
#ifndef WIN32
|
||||
bool Tins::PacketSender::send_l2(PDU &pdu, struct sockaddr* link_addr, uint32_t len_addr) {
|
||||
if(!open_l2_socket())
|
||||
return false;
|
||||
void PacketSender::send_l2(PDU &pdu, struct sockaddr* link_addr, uint32_t len_addr) {
|
||||
open_l2_socket();
|
||||
|
||||
int sock = _sockets[ETHER_SOCKET];
|
||||
PDU::serialization_type buffer = pdu.serialize();
|
||||
if(buffer.size() == 0)
|
||||
return false;
|
||||
bool ret_val = (sendto(sock, &buffer[0], buffer.size(), 0, link_addr, len_addr) != -1);
|
||||
|
||||
return ret_val;
|
||||
if(!buffer.empty()) {
|
||||
if(sendto(sock, &buffer[0], buffer.size(), 0, link_addr, len_addr) == -1)
|
||||
throw SocketWriteError(make_error_string());
|
||||
}
|
||||
}
|
||||
|
||||
Tins::PDU *Tins::PacketSender::recv_l2(PDU &pdu, struct sockaddr *link_addr, uint32_t len_addr) {
|
||||
if(!open_l2_socket())
|
||||
return 0;
|
||||
PDU *PacketSender::recv_l2(PDU &pdu, struct sockaddr *link_addr, uint32_t len_addr) {
|
||||
open_l2_socket();
|
||||
return recv_match_loop(_sockets[ETHER_SOCKET], pdu, link_addr, len_addr);
|
||||
}
|
||||
#endif // WIN32
|
||||
|
||||
Tins::PDU *Tins::PacketSender::recv_l3(PDU &pdu, struct sockaddr* link_addr, uint32_t len_addr, SocketType type) {
|
||||
if(!open_l3_socket(type))
|
||||
return 0;
|
||||
PDU *PacketSender::recv_l3(PDU &pdu, struct sockaddr* link_addr, uint32_t len_addr, SocketType type) {
|
||||
open_l3_socket(type);
|
||||
return recv_match_loop(_sockets[type], pdu, link_addr, len_addr);
|
||||
}
|
||||
|
||||
bool Tins::PacketSender::send_l3(PDU &pdu, struct sockaddr* link_addr, uint32_t len_addr, SocketType type) {
|
||||
bool ret_val = true;
|
||||
if(!open_l3_socket(type))
|
||||
ret_val = false;
|
||||
if (ret_val) {
|
||||
int sock = _sockets[type];
|
||||
PDU::serialization_type buffer = pdu.serialize();
|
||||
ret_val = (sendto(sock, (const char*)&buffer[0], buffer.size(), 0, link_addr, len_addr) != -1);
|
||||
}
|
||||
return ret_val;
|
||||
void PacketSender::send_l3(PDU &pdu, struct sockaddr* link_addr, uint32_t len_addr, SocketType type) {
|
||||
open_l3_socket(type);
|
||||
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());
|
||||
}
|
||||
|
||||
Tins::PDU *Tins::PacketSender::recv_match_loop(int sock, PDU &pdu, struct sockaddr* link_addr, uint32_t addrlen) {
|
||||
PDU *PacketSender::recv_match_loop(int sock, PDU &pdu, struct sockaddr* link_addr, uint32_t addrlen) {
|
||||
fd_set readfds;
|
||||
struct timeval timeout, end_time;
|
||||
int read;
|
||||
@@ -195,7 +200,7 @@ Tins::PDU *Tins::PacketSender::recv_match_loop(int sock, PDU &pdu, struct sockad
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Tins::PacketSender::timeval_subtract (struct timeval *result, struct timeval *x, struct timeval *y) {
|
||||
int PacketSender::timeval_subtract (struct timeval *result, struct timeval *x, struct timeval *y) {
|
||||
/* Perform the carry for the later subtraction by updating y. */
|
||||
if (x->tv_usec < y->tv_usec) {
|
||||
int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
|
||||
@@ -218,10 +223,11 @@ int Tins::PacketSender::timeval_subtract (struct timeval *result, struct timeval
|
||||
return x->tv_sec < y->tv_sec;
|
||||
}
|
||||
|
||||
int Tins::PacketSender::find_type(SocketType type) {
|
||||
int PacketSender::find_type(SocketType type) {
|
||||
SocketTypeMap::iterator it = _types.find(type);
|
||||
if(it == _types.end())
|
||||
return -1;
|
||||
else
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,8 +66,8 @@ uint32_t PDU::size() const {
|
||||
return sz;
|
||||
}
|
||||
|
||||
bool PDU::send(PacketSender &) {
|
||||
return false;
|
||||
void PDU::send(PacketSender &) {
|
||||
|
||||
}
|
||||
|
||||
PDU *PDU::recv_response(PacketSender &) {
|
||||
|
||||
@@ -222,7 +222,7 @@ uint32_t RadioTap::trailer_size() const {
|
||||
return ((_flags & 0x10) != 0) ? sizeof(uint32_t) : 0;
|
||||
}
|
||||
|
||||
bool RadioTap::send(PacketSender &sender) {
|
||||
void RadioTap::send(PacketSender &sender) {
|
||||
if(!_iface)
|
||||
throw std::runtime_error("Interface has not been set");
|
||||
|
||||
@@ -241,7 +241,7 @@ bool RadioTap::send(PacketSender &sender) {
|
||||
std::copy(dot11_addr.begin(), dot11_addr.end(), addr.sll_addr);
|
||||
}
|
||||
|
||||
return sender.send_l2(*this, (struct sockaddr*)&addr, (uint32_t)sizeof(addr));
|
||||
sender.send_l2(*this, (struct sockaddr*)&addr, (uint32_t)sizeof(addr));
|
||||
}
|
||||
|
||||
void RadioTap::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) {
|
||||
|
||||
@@ -39,8 +39,8 @@
|
||||
#endif
|
||||
#include "utils.h"
|
||||
#include "pdu.h"
|
||||
#include "ip.h"
|
||||
#include "arp.h"
|
||||
#include "ethernetII.h"
|
||||
#include "endianness.h"
|
||||
#include "network_interface.h"
|
||||
#include "packet_sender.h"
|
||||
@@ -114,8 +114,8 @@ bool Utils::resolve_hwaddr(const NetworkInterface &iface, IPv4Address ip,
|
||||
{
|
||||
IPv4Address my_ip;
|
||||
NetworkInterface::Info info(iface.addresses());
|
||||
std::auto_ptr<PDU> packet(ARP::make_arp_request(iface, ip, info.ip_addr, info.hw_addr));
|
||||
std::auto_ptr<PDU> response(sender.send_recv(*packet));
|
||||
EthernetII packet = ARP::make_arp_request(iface, ip, info.ip_addr, info.hw_addr);
|
||||
std::auto_ptr<PDU> response(sender.send_recv(packet));
|
||||
if(response.get()) {
|
||||
ARP *arp_resp = response->find_pdu<ARP>();
|
||||
if(arp_resp)
|
||||
@@ -130,8 +130,8 @@ HWAddress<6> Utils::resolve_hwaddr(const NetworkInterface &iface, IPv4Address ip
|
||||
{
|
||||
IPv4Address my_ip;
|
||||
NetworkInterface::Info info(iface.addresses());
|
||||
std::auto_ptr<PDU> packet(ARP::make_arp_request(iface, ip, info.ip_addr, info.hw_addr));
|
||||
std::auto_ptr<PDU> response(sender.send_recv(*packet));
|
||||
EthernetII packet = ARP::make_arp_request(iface, ip, info.ip_addr, info.hw_addr);
|
||||
std::auto_ptr<PDU> response(sender.send_recv(packet));
|
||||
if(response.get()) {
|
||||
const ARP *arp_resp = response->find_pdu<ARP>();
|
||||
if(arp_resp)
|
||||
|
||||
Reference in New Issue
Block a user