mirror of
https://github.com/mfontanini/libtins
synced 2026-01-23 02:35:57 +01:00
Added Sniffer class. Added a constructor to eery PDU subclass which creates an instance of the PDU from a byte array.
This commit is contained in:
@@ -52,6 +52,14 @@ namespace Tins {
|
|||||||
*/
|
*/
|
||||||
ARP(uint32_t target_ip = 0, uint32_t sender_ip = 0, const uint8_t *target_hw = 0, const uint8_t *sender_hw = 0);
|
ARP(uint32_t target_ip = 0, uint32_t sender_ip = 0, const uint8_t *target_hw = 0, const uint8_t *sender_hw = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Constructor which creates an TCP object from a buffer and adds all identifiable
|
||||||
|
* PDUs found in the buffer as children of this one.
|
||||||
|
* \param buffer The buffer from which this PDU will be constructed.
|
||||||
|
* \param total_sz The total size of the buffer.
|
||||||
|
*/
|
||||||
|
ARP(const uint8_t *buffer, uint32_t total_sz);
|
||||||
|
|
||||||
/* Getters */
|
/* Getters */
|
||||||
/**
|
/**
|
||||||
* \brief Getter for the sender's hardware address.
|
* \brief Getter for the sender's hardware address.
|
||||||
@@ -305,7 +313,7 @@ namespace Tins {
|
|||||||
* \return The cloned PDU.
|
* \return The cloned PDU.
|
||||||
* \sa PDU::clone_packet
|
* \sa PDU::clone_packet
|
||||||
*/
|
*/
|
||||||
PDU *clone_packet(uint8_t *ptr, uint32_t total_sz);
|
PDU *clone_packet(const uint8_t *ptr, uint32_t total_sz);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct arphdr {
|
struct arphdr {
|
||||||
@@ -325,7 +333,7 @@ namespace Tins {
|
|||||||
*
|
*
|
||||||
* \param arp_ptr The pointer to the arphdr.
|
* \param arp_ptr The pointer to the arphdr.
|
||||||
*/
|
*/
|
||||||
ARP(arphdr *arp_ptr);
|
ARP(const arphdr *arp_ptr);
|
||||||
|
|
||||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||||
|
|
||||||
|
|||||||
@@ -131,9 +131,28 @@ namespace Tins {
|
|||||||
* \brief DHCP options struct.
|
* \brief DHCP options struct.
|
||||||
*/
|
*/
|
||||||
struct DHCPOption {
|
struct DHCPOption {
|
||||||
uint8_t option, length;
|
/**
|
||||||
|
* \brief The option number.
|
||||||
|
*/
|
||||||
|
uint8_t option;
|
||||||
|
/**
|
||||||
|
* \brief The value's length in bytes.
|
||||||
|
*/
|
||||||
|
uint8_t length;
|
||||||
|
/**
|
||||||
|
* \brief The option's value.
|
||||||
|
*/
|
||||||
uint8_t *value;
|
uint8_t *value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Creates an instance of DHCPOption.
|
||||||
|
*
|
||||||
|
* The option's value is copied, therefore the user should
|
||||||
|
* manually free any memory pointed by the "val" parameter.
|
||||||
|
* \param opt The option number.
|
||||||
|
* \param len The length of the option's value in bytes.
|
||||||
|
* \param val The option's value.
|
||||||
|
*/
|
||||||
DHCPOption(uint8_t opt, uint8_t len, const uint8_t *val);
|
DHCPOption(uint8_t opt, uint8_t len, const uint8_t *val);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -201,7 +220,7 @@ namespace Tins {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Adds a domain name servers option.
|
* \brief Adds a domain name servers option.
|
||||||
* \param routers A list of ip addresses in integer notation.
|
* \param dns A list of ip addresses in integer notation.
|
||||||
* \return True if the option was added successfully. \sa DHCP::add_option
|
* \return True if the option was added successfully. \sa DHCP::add_option
|
||||||
*/
|
*/
|
||||||
bool add_dns_options(const std::list<uint32_t> &dns);
|
bool add_dns_options(const std::list<uint32_t> &dns);
|
||||||
|
|||||||
@@ -66,6 +66,14 @@ namespace Tins {
|
|||||||
*/
|
*/
|
||||||
EthernetII(uint32_t iface_index, const uint8_t* mac_dst = 0, const uint8_t* mac_src = 0, PDU* child = 0);
|
EthernetII(uint32_t iface_index, const uint8_t* mac_dst = 0, const uint8_t* mac_src = 0, PDU* child = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Constructor which creates an EthernetII object from a buffer and adds all identifiable
|
||||||
|
* PDUs found in the buffer as children of this one.
|
||||||
|
* \param buffer The buffer from which this PDU will be constructed.
|
||||||
|
* \param total_sz The total size of the buffer.
|
||||||
|
*/
|
||||||
|
EthernetII(const uint8_t *buffer, uint32_t total_sz);
|
||||||
|
|
||||||
/* Getters */
|
/* Getters */
|
||||||
/**
|
/**
|
||||||
* \brief Getter for the destination's mac address.
|
* \brief Getter for the destination's mac address.
|
||||||
@@ -88,7 +96,14 @@ namespace Tins {
|
|||||||
*/
|
*/
|
||||||
inline uint32_t iface() const { return this->_iface_index; }
|
inline uint32_t iface() const { return this->_iface_index; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Getter for the payload_type
|
||||||
|
* \return The payload type.
|
||||||
|
*/
|
||||||
|
uint16_t payload_type() const;
|
||||||
|
|
||||||
/* Setters */
|
/* Setters */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Setter for the destination's MAC.
|
* \brief Setter for the destination's MAC.
|
||||||
*
|
*
|
||||||
@@ -177,11 +192,11 @@ namespace Tins {
|
|||||||
*/
|
*/
|
||||||
EthernetII(ethhdr *eth_ptr);
|
EthernetII(ethhdr *eth_ptr);
|
||||||
|
|
||||||
|
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||||
|
|
||||||
|
|
||||||
ethhdr _eth;
|
ethhdr _eth;
|
||||||
uint32_t _iface_index;
|
uint32_t _iface_index;
|
||||||
|
|
||||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -57,6 +57,14 @@ namespace Tins {
|
|||||||
*/
|
*/
|
||||||
ICMP(Flags flag = ECHO_REQUEST);
|
ICMP(Flags flag = ECHO_REQUEST);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Constructor which creates an ICMP object from a buffer and adds all identifiable
|
||||||
|
* PDUs found in the buffer as children of this one.
|
||||||
|
* \param buffer The buffer from which this PDU will be constructed.
|
||||||
|
* \param total_sz The total size of the buffer.
|
||||||
|
*/
|
||||||
|
ICMP(const uint8_t *buffer, uint32_t total_sz);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Sets the code field.
|
* \brief Sets the code field.
|
||||||
*
|
*
|
||||||
@@ -273,7 +281,7 @@ namespace Tins {
|
|||||||
* \return The cloned PDU.
|
* \return The cloned PDU.
|
||||||
* \sa PDU::clone_packet
|
* \sa PDU::clone_packet
|
||||||
*/
|
*/
|
||||||
PDU *clone_packet(uint8_t *ptr, uint32_t total_sz);
|
PDU *clone_packet(const uint8_t *ptr, uint32_t total_sz);
|
||||||
private:
|
private:
|
||||||
static uint16_t global_id, global_seq;
|
static uint16_t global_id, global_seq;
|
||||||
|
|
||||||
@@ -298,7 +306,7 @@ namespace Tins {
|
|||||||
*
|
*
|
||||||
* \param ptr The icmphdr to clone.
|
* \param ptr The icmphdr to clone.
|
||||||
*/
|
*/
|
||||||
ICMP(icmphdr *ptr);
|
ICMP(const icmphdr *ptr);
|
||||||
|
|
||||||
/** \brief Serialices this ICMP PDU.
|
/** \brief Serialices this ICMP PDU.
|
||||||
* \param buffer The buffer in which the PDU will be serialized.
|
* \param buffer The buffer in which the PDU will be serialized.
|
||||||
|
|||||||
10
include/ip.h
10
include/ip.h
@@ -100,6 +100,14 @@ namespace Tins {
|
|||||||
*/
|
*/
|
||||||
IP(uint32_t ip_dst = 0, uint32_t ip_src = 0, PDU *child = 0);
|
IP(uint32_t ip_dst = 0, uint32_t ip_src = 0, PDU *child = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Constructor which creates an IP object from a buffer and adds all identifiable
|
||||||
|
* PDUs found in the buffer as children of this one.
|
||||||
|
* \param buffer The buffer from which this PDU will be constructed.
|
||||||
|
* \param total_sz The total size of the buffer.
|
||||||
|
*/
|
||||||
|
IP(const uint8_t *buffer, uint32_t total_sz);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Destructor for IP objects.
|
* \brief Destructor for IP objects.
|
||||||
*
|
*
|
||||||
@@ -340,7 +348,7 @@ namespace Tins {
|
|||||||
* \return The cloned PDU.
|
* \return The cloned PDU.
|
||||||
* \sa PDU::clone_packet
|
* \sa PDU::clone_packet
|
||||||
*/
|
*/
|
||||||
PDU *clone_packet(uint8_t *ptr, uint32_t total_sz);
|
PDU *clone_packet(const uint8_t *ptr, uint32_t total_sz);
|
||||||
private:
|
private:
|
||||||
static const uint8_t DEFAULT_TTL;
|
static const uint8_t DEFAULT_TTL;
|
||||||
|
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ namespace Tins {
|
|||||||
* \param total_sz The size of the buffer.
|
* \param total_sz The size of the buffer.
|
||||||
* \return The cloned PDU.
|
* \return The cloned PDU.
|
||||||
*/
|
*/
|
||||||
virtual PDU *clone_packet(uint8_t *ptr, uint32_t total_sz) { return 0; }
|
virtual PDU *clone_packet(const uint8_t *ptr, uint32_t total_sz) { return 0; }
|
||||||
protected:
|
protected:
|
||||||
/** \brief Serializes this PDU and propagates this action to child PDUs.
|
/** \brief Serializes this PDU and propagates this action to child PDUs.
|
||||||
*
|
*
|
||||||
@@ -181,7 +181,7 @@ namespace Tins {
|
|||||||
* \param total_sz The total size of the buffer.
|
* \param total_sz The total size of the buffer.
|
||||||
* \return Returns the cloned PDU. Will be 0 if cloning failed.
|
* \return Returns the cloned PDU. Will be 0 if cloning failed.
|
||||||
*/
|
*/
|
||||||
PDU *clone_inner_pdu(uint8_t *ptr, uint32_t total_sz);
|
PDU *clone_inner_pdu(const uint8_t *ptr, uint32_t total_sz);
|
||||||
|
|
||||||
/** \brief Serializes this TCP PDU.
|
/** \brief Serializes this TCP PDU.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -37,14 +37,21 @@ namespace Tins {
|
|||||||
public:
|
public:
|
||||||
/** \brief Creates an instance of RawPDU.
|
/** \brief Creates an instance of RawPDU.
|
||||||
*
|
*
|
||||||
* The payload is not copied by default, therefore it must be
|
* The payload is copied, therefore the original payload's memory
|
||||||
* manually freed by the user. If the payload was to be copied,
|
* must be freed by the user.
|
||||||
* then the copy flag must be set to true.
|
|
||||||
* \param pload The payload which the RawPDU will contain.
|
* \param pload The payload which the RawPDU will contain.
|
||||||
* \param size The size of the payload.
|
* \param size The size of the payload.
|
||||||
* \param copy Flag indicating wether to copy the payload.
|
|
||||||
*/
|
*/
|
||||||
RawPDU(uint8_t *pload, uint32_t size, bool copy = false);
|
RawPDU(const uint8_t *pload, uint32_t size);
|
||||||
|
|
||||||
|
/** \brief Creates an instance of RawPDU.
|
||||||
|
*
|
||||||
|
* The payload is not copied in this constructor, therefore
|
||||||
|
* it must be manually freed by the user.
|
||||||
|
* \param pload The payload which the RawPDU will contain.
|
||||||
|
* \param size The size of the payload.
|
||||||
|
*/
|
||||||
|
RawPDU(uint8_t *pload, uint32_t size);
|
||||||
|
|
||||||
/** \brief RawPDU destructor.
|
/** \brief RawPDU destructor.
|
||||||
*
|
*
|
||||||
|
|||||||
111
include/sniffer.h
Normal file
111
include/sniffer.h
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
#ifndef __SNIFFER_H
|
||||||
|
#define __SNIFFER_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <pcap.h>
|
||||||
|
#include <string>
|
||||||
|
#include "pdu.h"
|
||||||
|
|
||||||
|
namespace Tins {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Abstract sniffed packet handler.
|
||||||
|
*
|
||||||
|
* Base class to handle sniffed packets when using Sniffer::sniff_loop.
|
||||||
|
* Users should either inherit this class, or use the template class
|
||||||
|
* SnifferHandler to provide their own handlers.
|
||||||
|
*/
|
||||||
|
class AbstractSnifferHandler {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* \brief AbstractSnifferHandler destructor.
|
||||||
|
*/
|
||||||
|
virtual ~AbstractSnifferHandler() { }
|
||||||
|
/**
|
||||||
|
* \brief Handle a captured PDU.
|
||||||
|
* \return Should return false if no more sniffing is required.
|
||||||
|
*/
|
||||||
|
virtual bool handle(PDU *pdu) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Sniffer class can be used to sniff packets using filters.
|
||||||
|
*/
|
||||||
|
class Sniffer {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* \brief Creates an instance of sniffer.
|
||||||
|
* \param device The device which will be sniffed.
|
||||||
|
* \param max_packet_size The maximum packet size to be read.
|
||||||
|
*/
|
||||||
|
Sniffer(const std::string &device, unsigned max_packet_size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Sniffer destructor.
|
||||||
|
* This frees all memory used by the pcap handle.
|
||||||
|
*/
|
||||||
|
~Sniffer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Compiles a filter and uses it to capture one packet.
|
||||||
|
*
|
||||||
|
* This method should be used only when expecting few packets.
|
||||||
|
* It's innefficient since it recompiles the filter every time it
|
||||||
|
* is called. To reuse a filter and sniff more efficiently, use
|
||||||
|
* Sniffer::sniff_loop.
|
||||||
|
* \param filter The filter which will be used while sniffing.
|
||||||
|
* \return The captured packet, matching the given filter, 0 if an
|
||||||
|
* error occured(probably compiling the filter).
|
||||||
|
*/
|
||||||
|
PDU *next_pdu(const std::string &filter);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Starts a sniffing loop, using a callback object for every
|
||||||
|
* sniffed packet.
|
||||||
|
*
|
||||||
|
* Handlers could be user-provided classes which inherit AbstractSnifferHandler,
|
||||||
|
* or it could be a specific SnifferHandler specialization. This method deletes
|
||||||
|
* packets after they are handled, therefore the handlers MUST NOT delete them.
|
||||||
|
* \param filter The filter to use when sniffing.
|
||||||
|
* \param cback_handler The callback handler object which should process packets.
|
||||||
|
* \param max_packets The maximum amount of packets to sniff. 0 == infinite.
|
||||||
|
*/
|
||||||
|
void sniff_loop(const std::string &filter, AbstractSnifferHandler *cback_handler, uint32_t max_packets = 0);
|
||||||
|
private:
|
||||||
|
bool compile_set_filter(const std::string &filter, bpf_program &prog);
|
||||||
|
|
||||||
|
static void callback_handler(u_char *args, const struct pcap_pkthdr *header, const u_char *packet);
|
||||||
|
|
||||||
|
pcap_t *handle;
|
||||||
|
bpf_u_int32 ip, mask;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Concrete implementation of AbstractSnifferHandler.
|
||||||
|
*
|
||||||
|
* This class is instantiated using a pointer to the actual handler.
|
||||||
|
* Every time a packet is sniffed, operator() (PDU*) will be called on
|
||||||
|
* the given pointer. \sa AbstractSnifferHandler
|
||||||
|
*/
|
||||||
|
template<class T> class SnifferHandler : public AbstractSnifferHandler {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Creates an instance of SnifferHandler.
|
||||||
|
* \param ptr The pointer to the actual handler.
|
||||||
|
*/
|
||||||
|
SnifferHandler(T *ptr) : handler(ptr) { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief The overriden AbstractSnifferHandler::handle.
|
||||||
|
* \param pdu The sniffed PDU.
|
||||||
|
* \return False if no more sniffing is required, otherwise true.
|
||||||
|
*/
|
||||||
|
bool handle(PDU *pdu) {
|
||||||
|
return (*handler)(pdu);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
T *handler;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -78,15 +78,21 @@ namespace Tins {
|
|||||||
* \param dport Destination port.
|
* \param dport Destination port.
|
||||||
* \param sport Source port.
|
* \param sport Source port.
|
||||||
* */
|
* */
|
||||||
|
|
||||||
TCP(uint16_t dport = 0, uint16_t sport = 0);
|
TCP(uint16_t dport = 0, uint16_t sport = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Constructor which creates an TCP object from a buffer and adds all identifiable
|
||||||
|
* PDUs found in the buffer as children of this one.
|
||||||
|
* \param buffer The buffer from which this PDU will be constructed.
|
||||||
|
* \param total_sz The total size of the buffer.
|
||||||
|
*/
|
||||||
|
TCP(const uint8_t *buffer, uint32_t total_sz);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief TCP destructor.
|
* \brief TCP destructor.
|
||||||
*
|
*
|
||||||
* Destructs the TCP instance. Does not free the payload.
|
* Destructs the TCP instance. Does not free the payload.
|
||||||
* */
|
* */
|
||||||
|
|
||||||
~TCP();
|
~TCP();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -145,6 +151,16 @@ namespace Tins {
|
|||||||
*/
|
*/
|
||||||
inline uint8_t data_offset() const { return this->_tcp.doff; }
|
inline uint8_t data_offset() const { return this->_tcp.doff; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Gets the value of a flag.
|
||||||
|
*
|
||||||
|
* \param tcp_flag The polled flag.
|
||||||
|
* \return The value of the flag.
|
||||||
|
*/
|
||||||
|
uint8_t get_flag(Flags tcp_flag);
|
||||||
|
|
||||||
|
/* Setters */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Setter for the destination port field.
|
* \brief Setter for the destination port field.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -34,15 +34,24 @@ namespace Tins {
|
|||||||
*/
|
*/
|
||||||
class UDP : public PDU {
|
class UDP : public PDU {
|
||||||
public:
|
public:
|
||||||
/** \brief UDP constructor.
|
/**
|
||||||
|
* \brief UDP constructor.
|
||||||
*
|
*
|
||||||
* Creates an instance of UDP. Destination and source port can
|
* Creates an instance of UDP. Destination and source port can
|
||||||
* be provided, otherwise both will be 0.
|
* be provided, otherwise both will be 0.
|
||||||
* \param dport Destination port.
|
* \param dport Destination port.
|
||||||
* \param sport Source port.
|
* \param sport Source port.
|
||||||
|
* \param child The child PDU(optional).
|
||||||
* */
|
* */
|
||||||
UDP(uint16_t dport = 0, uint16_t sport = 0, PDU *child = 0);
|
UDP(uint16_t dport = 0, uint16_t sport = 0, PDU *child = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Constructor which creates an UDP object from a buffer and adds all identifiable
|
||||||
|
* PDUs found in the buffer as children of this one.
|
||||||
|
* \param buffer The buffer from which this PDU will be constructed.
|
||||||
|
* \param total_sz The total size of the buffer.
|
||||||
|
*/
|
||||||
|
UDP(const uint8_t *buffer, uint32_t total_sz);
|
||||||
|
|
||||||
/** \brief Returns the destination port
|
/** \brief Returns the destination port
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ namespace Tins {
|
|||||||
*
|
*
|
||||||
* If the lookup fails, false will be returned, true otherwise.
|
* If the lookup fails, false will be returned, true otherwise.
|
||||||
* \param iface The interface from which to extract the identifier.
|
* \param iface The interface from which to extract the identifier.
|
||||||
* \param flag The interface id will be returned in this parameter.
|
* \param id The interface id will be returned in this parameter.
|
||||||
*/
|
*/
|
||||||
bool interface_id(const std::string &iface, uint32_t &id);
|
bool interface_id(const std::string &iface, uint32_t &id);
|
||||||
|
|
||||||
|
|||||||
132
src/arp.cpp
132
src/arp.cpp
@@ -31,66 +31,9 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
Tins::PDU* Tins::ARP::make_arp_request(const std::string& iface,
|
|
||||||
const std::string& target,
|
|
||||||
const std::string& sender,
|
|
||||||
const uint8_t* hw_snd) {
|
|
||||||
uint32_t target_ip = Tins::Utils::resolve_ip(target);
|
|
||||||
uint32_t sender_ip = Tins::Utils::resolve_ip(sender);
|
|
||||||
return make_arp_request(iface, target_ip, sender_ip, hw_snd);
|
|
||||||
}
|
|
||||||
|
|
||||||
Tins::PDU* Tins::ARP::make_arp_request(const std::string& iface,
|
|
||||||
uint32_t target,
|
|
||||||
uint32_t sender,
|
|
||||||
const uint8_t* hw_snd) {
|
|
||||||
|
|
||||||
/* Create ARP packet and set its attributes */
|
|
||||||
ARP* arp = new ARP();
|
|
||||||
arp->target_ip_addr(target);
|
|
||||||
arp->sender_ip_addr(sender);
|
|
||||||
if (hw_snd) {
|
|
||||||
arp->sender_hw_addr(hw_snd);
|
|
||||||
}
|
|
||||||
arp->opcode(REQUEST);
|
|
||||||
|
|
||||||
/* Create the EthernetII PDU with the ARP PDU as its inner PDU */
|
|
||||||
EthernetII* eth = new EthernetII(iface, Tins::EthernetII::BROADCAST, hw_snd, arp);
|
|
||||||
return eth;
|
|
||||||
}
|
|
||||||
|
|
||||||
Tins::PDU* Tins::ARP::make_arp_reply(const string& iface,
|
|
||||||
const string& target,
|
|
||||||
const string& sender,
|
|
||||||
const uint8_t* hw_tgt,
|
|
||||||
const uint8_t* hw_snd) {
|
|
||||||
|
|
||||||
uint32_t target_ip = Tins::Utils::resolve_ip(target);
|
|
||||||
uint32_t sender_ip = Tins::Utils::resolve_ip(sender);
|
|
||||||
return make_arp_reply(iface, target_ip, sender_ip, hw_tgt, hw_snd);
|
|
||||||
}
|
|
||||||
|
|
||||||
Tins::PDU* Tins::ARP::make_arp_reply(const string& iface,
|
|
||||||
uint32_t target,
|
|
||||||
uint32_t sender,
|
|
||||||
const uint8_t* hw_tgt,
|
|
||||||
const uint8_t* hw_snd) {
|
|
||||||
|
|
||||||
/* Create ARP packet and set its attributes */
|
|
||||||
ARP* arp = new ARP();
|
|
||||||
arp->target_ip_addr(target);
|
|
||||||
arp->sender_ip_addr(sender);
|
|
||||||
arp->target_hw_addr(hw_tgt);
|
|
||||||
arp->sender_hw_addr(hw_snd);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
Tins::ARP::ARP(uint32_t target_ip, uint32_t sender_ip, const uint8_t *target_hw, const uint8_t *sender_hw) : PDU(0x0608) {
|
Tins::ARP::ARP(uint32_t target_ip, uint32_t sender_ip, const uint8_t *target_hw, const uint8_t *sender_hw) : PDU(0x0608) {
|
||||||
std::memset(&_arp, 0, sizeof(arphdr));
|
memset(&_arp, 0, sizeof(arphdr));
|
||||||
hw_addr_format(1);
|
hw_addr_format(1);
|
||||||
prot_addr_format(0x0800);
|
prot_addr_format(0x0800);
|
||||||
hw_addr_length(6);
|
hw_addr_length(6);
|
||||||
@@ -103,7 +46,16 @@ Tins::ARP::ARP(uint32_t target_ip, uint32_t sender_ip, const uint8_t *target_hw,
|
|||||||
target_hw_addr(target_hw);
|
target_hw_addr(target_hw);
|
||||||
}
|
}
|
||||||
|
|
||||||
Tins::ARP::ARP(arphdr *arp_ptr) : PDU(Utils::net_to_host_s(0x0806)) {
|
Tins::ARP::ARP(const uint8_t *buffer, uint32_t total_sz) : PDU(0x0608) {
|
||||||
|
if(total_sz < sizeof(arphdr))
|
||||||
|
throw std::runtime_error("Not enought size for an ARP header in the buffer.");
|
||||||
|
memcpy(&_arp, buffer, sizeof(arphdr));
|
||||||
|
total_sz -= sizeof(arphdr);
|
||||||
|
if(total_sz)
|
||||||
|
inner_pdu(new RawPDU(buffer + sizeof(arphdr), total_sz));
|
||||||
|
}
|
||||||
|
|
||||||
|
Tins::ARP::ARP(const arphdr *arp_ptr) : PDU(Utils::net_to_host_s(0x0806)) {
|
||||||
memcpy(&_arp, arp_ptr, sizeof(arphdr));
|
memcpy(&_arp, arp_ptr, sizeof(arphdr));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,10 +140,10 @@ bool Tins::ARP::matches_response(uint8_t *ptr, uint32_t total_sz) {
|
|||||||
return arp_ptr->ar_sip == _arp.ar_tip && arp_ptr->ar_tip == _arp.ar_sip;
|
return arp_ptr->ar_sip == _arp.ar_tip && arp_ptr->ar_tip == _arp.ar_sip;
|
||||||
}
|
}
|
||||||
|
|
||||||
Tins::PDU *Tins::ARP::clone_packet(uint8_t *ptr, uint32_t total_sz) {
|
Tins::PDU *Tins::ARP::clone_packet(const uint8_t *ptr, uint32_t total_sz) {
|
||||||
if(total_sz < sizeof(arphdr))
|
if(total_sz < sizeof(arphdr))
|
||||||
return 0;
|
return 0;
|
||||||
arphdr *arp_ptr = (arphdr*)ptr;
|
const arphdr *arp_ptr = (arphdr*)ptr;
|
||||||
PDU *child = 0, *cloned;
|
PDU *child = 0, *cloned;
|
||||||
if(total_sz > sizeof(arphdr)) {
|
if(total_sz > sizeof(arphdr)) {
|
||||||
if((child = PDU::clone_inner_pdu(ptr + sizeof(arphdr), total_sz - sizeof(arphdr))) == 0)
|
if((child = PDU::clone_inner_pdu(ptr + sizeof(arphdr), total_sz - sizeof(arphdr))) == 0)
|
||||||
@@ -201,3 +153,61 @@ Tins::PDU *Tins::ARP::clone_packet(uint8_t *ptr, uint32_t total_sz) {
|
|||||||
cloned->inner_pdu(child);
|
cloned->inner_pdu(child);
|
||||||
return cloned;
|
return cloned;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Tins::PDU* Tins::ARP::make_arp_request(const string& iface,
|
||||||
|
const string& target,
|
||||||
|
const string& sender,
|
||||||
|
const uint8_t* hw_snd) {
|
||||||
|
uint32_t target_ip = Tins::Utils::resolve_ip(target);
|
||||||
|
uint32_t sender_ip = Tins::Utils::resolve_ip(sender);
|
||||||
|
return make_arp_request(iface, target_ip, sender_ip, hw_snd);
|
||||||
|
}
|
||||||
|
|
||||||
|
Tins::PDU* Tins::ARP::make_arp_request(const std::string& iface,
|
||||||
|
uint32_t target,
|
||||||
|
uint32_t sender,
|
||||||
|
const uint8_t* hw_snd) {
|
||||||
|
|
||||||
|
/* Create ARP packet and set its attributes */
|
||||||
|
ARP* arp = new ARP();
|
||||||
|
arp->target_ip_addr(target);
|
||||||
|
arp->sender_ip_addr(sender);
|
||||||
|
if (hw_snd) {
|
||||||
|
arp->sender_hw_addr(hw_snd);
|
||||||
|
}
|
||||||
|
arp->opcode(REQUEST);
|
||||||
|
|
||||||
|
/* Create the EthernetII PDU with the ARP PDU as its inner PDU */
|
||||||
|
EthernetII* eth = new EthernetII(iface, Tins::EthernetII::BROADCAST, hw_snd, arp);
|
||||||
|
return eth;
|
||||||
|
}
|
||||||
|
|
||||||
|
Tins::PDU* Tins::ARP::make_arp_reply(const string& iface,
|
||||||
|
const string& target,
|
||||||
|
const string& sender,
|
||||||
|
const uint8_t* hw_tgt,
|
||||||
|
const uint8_t* hw_snd) {
|
||||||
|
|
||||||
|
uint32_t target_ip = Tins::Utils::resolve_ip(target);
|
||||||
|
uint32_t sender_ip = Tins::Utils::resolve_ip(sender);
|
||||||
|
return make_arp_reply(iface, target_ip, sender_ip, hw_tgt, hw_snd);
|
||||||
|
}
|
||||||
|
|
||||||
|
Tins::PDU* Tins::ARP::make_arp_reply(const string& iface,
|
||||||
|
uint32_t target,
|
||||||
|
uint32_t sender,
|
||||||
|
const uint8_t* hw_tgt,
|
||||||
|
const uint8_t* hw_snd) {
|
||||||
|
|
||||||
|
/* Create ARP packet and set its attributes */
|
||||||
|
ARP* arp = new ARP();
|
||||||
|
arp->target_ip_addr(target);
|
||||||
|
arp->sender_ip_addr(sender);
|
||||||
|
arp->target_hw_addr(hw_tgt);
|
||||||
|
arp->sender_hw_addr(hw_snd);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <iostream> //borrame
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "dhcp.h"
|
#include "dhcp.h"
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <stdexcept>
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
#include <net/ethernet.h>
|
#include <net/ethernet.h>
|
||||||
#include <netpacket/packet.h>
|
#include <netpacket/packet.h>
|
||||||
@@ -29,6 +29,8 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "ethernetII.h"
|
#include "ethernetII.h"
|
||||||
#include "rawpdu.h"
|
#include "rawpdu.h"
|
||||||
|
#include "ip.h"
|
||||||
|
#include "arp.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
const uint8_t* Tins::EthernetII::BROADCAST = (const uint8_t*)"\xff\xff\xff\xff\xff\xff";
|
const uint8_t* Tins::EthernetII::BROADCAST = (const uint8_t*)"\xff\xff\xff\xff\xff\xff";
|
||||||
@@ -54,10 +56,31 @@ Tins::EthernetII::EthernetII(uint32_t iface_index, const uint8_t* mac_dst, const
|
|||||||
this->_eth.payload_type = 0;
|
this->_eth.payload_type = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Tins::EthernetII::EthernetII(const uint8_t *buffer, uint32_t total_sz) : PDU(ETHERTYPE_IP) {
|
||||||
|
if(total_sz < sizeof(ethhdr))
|
||||||
|
throw std::runtime_error("Not enought size for an ethernetII header in the buffer.");
|
||||||
|
memcpy(&_eth, buffer, sizeof(ethhdr));
|
||||||
|
PDU *next = 0;
|
||||||
|
switch(payload_type()) {
|
||||||
|
case ETHERTYPE_IP:
|
||||||
|
next = new Tins::IP(buffer + sizeof(ethhdr), total_sz - sizeof(ethhdr));
|
||||||
|
break;
|
||||||
|
case ETHERTYPE_ARP:
|
||||||
|
next = new Tins::ARP(buffer + sizeof(ethhdr), total_sz - sizeof(ethhdr));
|
||||||
|
break;
|
||||||
|
// Other protos plz
|
||||||
|
}
|
||||||
|
inner_pdu(next);
|
||||||
|
}
|
||||||
|
|
||||||
Tins::EthernetII::EthernetII(ethhdr *eth_ptr) : PDU(ETHERTYPE_IP) {
|
Tins::EthernetII::EthernetII(ethhdr *eth_ptr) : PDU(ETHERTYPE_IP) {
|
||||||
memcpy(&_eth, eth_ptr, sizeof(ethhdr));
|
memcpy(&_eth, eth_ptr, sizeof(ethhdr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t Tins::EthernetII::payload_type() const {
|
||||||
|
return Utils::net_to_host_s(_eth.payload_type);
|
||||||
|
}
|
||||||
|
|
||||||
void Tins::EthernetII::dst_mac(const uint8_t* new_dst_mac) {
|
void Tins::EthernetII::dst_mac(const uint8_t* new_dst_mac) {
|
||||||
memcpy(this->_eth.dst_mac, new_dst_mac, 6);
|
memcpy(this->_eth.dst_mac, new_dst_mac, 6);
|
||||||
}
|
}
|
||||||
|
|||||||
21
src/icmp.cpp
21
src/icmp.cpp
@@ -19,12 +19,12 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <cstring>
|
||||||
|
#include <cassert>
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#endif
|
#endif
|
||||||
#include <cstring>
|
|
||||||
#include <cassert>
|
|
||||||
#include "icmp.h"
|
#include "icmp.h"
|
||||||
#include "rawpdu.h"
|
#include "rawpdu.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
@@ -48,7 +48,16 @@ Tins::ICMP::ICMP(Flags flag) : PDU(IPPROTO_ICMP) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Tins::ICMP::ICMP(icmphdr *ptr) : PDU(IPPROTO_ICMP) {
|
Tins::ICMP::ICMP(const uint8_t *buffer, uint32_t total_sz) : PDU(IPPROTO_ICMP) {
|
||||||
|
if(total_sz < sizeof(icmphdr))
|
||||||
|
throw std::runtime_error("Not enought size for an ICMP header in the buffer.");
|
||||||
|
std::memcpy(&_icmp, buffer, sizeof(icmphdr));
|
||||||
|
total_sz -= sizeof(icmphdr);
|
||||||
|
if(total_sz)
|
||||||
|
inner_pdu(new RawPDU(buffer + sizeof(icmphdr), total_sz));
|
||||||
|
}
|
||||||
|
|
||||||
|
Tins::ICMP::ICMP(const icmphdr *ptr) : PDU(IPPROTO_ICMP) {
|
||||||
std::memcpy(&_icmp, ptr, sizeof(icmphdr));
|
std::memcpy(&_icmp, ptr, sizeof(icmphdr));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,10 +186,10 @@ bool Tins::ICMP::matches_response(uint8_t *ptr, uint32_t total_sz) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Tins::PDU *Tins::ICMP::clone_packet(uint8_t *ptr, uint32_t total_sz) {
|
Tins::PDU *Tins::ICMP::clone_packet(const uint8_t *ptr, uint32_t total_sz) {
|
||||||
if(total_sz < sizeof(icmphdr))
|
if(total_sz < sizeof(icmphdr))
|
||||||
return 0;
|
return 0;
|
||||||
icmphdr *icmp_ptr = (icmphdr*)ptr;
|
const icmphdr *icmp_ptr = (icmphdr*)ptr;
|
||||||
PDU *child = 0, *cloned;
|
PDU *child = 0, *cloned;
|
||||||
if(total_sz > sizeof(icmphdr)) {
|
if(total_sz > sizeof(icmphdr)) {
|
||||||
if((child = PDU::clone_inner_pdu(ptr + sizeof(icmphdr), total_sz - sizeof(icmphdr))) == 0)
|
if((child = PDU::clone_inner_pdu(ptr + sizeof(icmphdr), total_sz - sizeof(icmphdr))) == 0)
|
||||||
|
|||||||
31
src/ip.cpp
31
src/ip.cpp
@@ -19,12 +19,16 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#endif
|
#endif
|
||||||
#include "ip.h"
|
#include "ip.h"
|
||||||
|
#include "tcp.h"
|
||||||
|
#include "udp.h"
|
||||||
|
#include "icmp.h"
|
||||||
#include "rawpdu.h"
|
#include "rawpdu.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
@@ -42,6 +46,29 @@ Tins::IP::IP(const string &ip_dst, const string &ip_src, PDU *child) : PDU(IPPRO
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Tins::IP::IP(const uint8_t *buffer, uint32_t total_sz) : PDU(IPPROTO_IP) {
|
||||||
|
if(total_sz < sizeof(iphdr))
|
||||||
|
throw std::runtime_error("Not enought size for an IP header in the buffer.");
|
||||||
|
std::memcpy(&_ip, buffer, sizeof(iphdr));
|
||||||
|
/* Options... */
|
||||||
|
buffer += head_len() * sizeof(uint32_t);
|
||||||
|
total_sz -= head_len() * sizeof(uint32_t);
|
||||||
|
switch(_ip.protocol) {
|
||||||
|
case IPPROTO_TCP:
|
||||||
|
inner_pdu(new Tins::TCP(buffer, total_sz));
|
||||||
|
break;
|
||||||
|
case IPPROTO_UDP:
|
||||||
|
inner_pdu(new Tins::UDP(buffer, total_sz));
|
||||||
|
break;
|
||||||
|
case IPPROTO_ICMP:
|
||||||
|
inner_pdu(new Tins::ICMP(buffer, total_sz));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
inner_pdu(new Tins::RawPDU(buffer, total_sz));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Tins::IP::IP(const iphdr *ptr) : PDU(IPPROTO_IP) {
|
Tins::IP::IP(const iphdr *ptr) : PDU(IPPROTO_IP) {
|
||||||
std::memcpy(&_ip, ptr, sizeof(iphdr));
|
std::memcpy(&_ip, ptr, sizeof(iphdr));
|
||||||
/* Options... */
|
/* Options... */
|
||||||
@@ -241,10 +268,10 @@ bool Tins::IP::matches_response(uint8_t *ptr, uint32_t total_sz) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Tins::PDU *Tins::IP::clone_packet(uint8_t *ptr, uint32_t total_sz) {
|
Tins::PDU *Tins::IP::clone_packet(const uint8_t *ptr, uint32_t total_sz) {
|
||||||
if(total_sz < sizeof(iphdr))
|
if(total_sz < sizeof(iphdr))
|
||||||
return 0;
|
return 0;
|
||||||
iphdr *ip_ptr = (iphdr*)ptr;
|
const iphdr *ip_ptr = (iphdr*)ptr;
|
||||||
uint32_t sz = ip_ptr->ihl * sizeof(uint32_t);
|
uint32_t sz = ip_ptr->ihl * sizeof(uint32_t);
|
||||||
if(total_sz < sz)
|
if(total_sz < sz)
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <iostream> //borrame
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "pdu.h"
|
#include "pdu.h"
|
||||||
#include "rawpdu.h"
|
#include "rawpdu.h"
|
||||||
@@ -69,7 +68,7 @@ void Tins::PDU::serialize(uint8_t *buffer, uint32_t total_sz, const PDU *parent)
|
|||||||
write_serialization(buffer, total_sz, parent);
|
write_serialization(buffer, total_sz, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
Tins::PDU *Tins::PDU::clone_inner_pdu(uint8_t *ptr, uint32_t total_sz) {
|
Tins::PDU *Tins::PDU::clone_inner_pdu(const uint8_t *ptr, uint32_t total_sz) {
|
||||||
PDU *child = 0;
|
PDU *child = 0;
|
||||||
if(inner_pdu()) {
|
if(inner_pdu()) {
|
||||||
child = inner_pdu()->clone_packet(ptr, total_sz);
|
child = inner_pdu()->clone_packet(ptr, total_sz);
|
||||||
@@ -77,7 +76,7 @@ Tins::PDU *Tins::PDU::clone_inner_pdu(uint8_t *ptr, uint32_t total_sz) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
child = new RawPDU(ptr, total_sz, true);
|
child = new RawPDU(ptr, total_sz);
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,11 +24,13 @@
|
|||||||
#include "rawpdu.h"
|
#include "rawpdu.h"
|
||||||
|
|
||||||
|
|
||||||
Tins::RawPDU::RawPDU(uint8_t *pload, uint32_t size, bool copy) : PDU(255), _payload(pload), _payload_size(size), _owns_payload(copy) {
|
Tins::RawPDU::RawPDU(const uint8_t *pload, uint32_t size) : PDU(255), _payload_size(size), _owns_payload(true) {
|
||||||
if(copy) {
|
_payload = new uint8_t[size];
|
||||||
_payload = new uint8_t[size];
|
std::memcpy(_payload, pload, size);
|
||||||
std::memcpy(_payload, pload, size);
|
}
|
||||||
}
|
|
||||||
|
Tins::RawPDU::RawPDU(uint8_t *pload, uint32_t size) : PDU(255), _payload(pload), _payload_size(size), _owns_payload(false) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Tins::RawPDU::~RawPDU() {
|
Tins::RawPDU::~RawPDU() {
|
||||||
|
|||||||
64
src/sniffer.cpp
Normal file
64
src/sniffer.cpp
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
#include <stdexcept>
|
||||||
|
#include "sniffer.h"
|
||||||
|
#include "ethernetII.h"
|
||||||
|
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
Tins::Sniffer::Sniffer(const string &device, unsigned max_packet_size) {
|
||||||
|
char error[PCAP_ERRBUF_SIZE];
|
||||||
|
if (pcap_lookupnet(device.c_str(), &ip, &mask, error) == -1)
|
||||||
|
throw runtime_error(error);
|
||||||
|
handle = pcap_open_live(device.c_str(), max_packet_size, 0, 0, error);
|
||||||
|
if(!handle)
|
||||||
|
throw runtime_error(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
Tins::Sniffer::~Sniffer() {
|
||||||
|
if(handle)
|
||||||
|
pcap_close(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Tins::Sniffer::compile_set_filter(const string &filter, bpf_program &prog) {
|
||||||
|
return (pcap_compile(handle, &prog, filter.c_str(), 0, ip) != -1 && pcap_setfilter(handle, &prog) != -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Tins::PDU *Tins::Sniffer::next_pdu(const string &filter) {
|
||||||
|
bpf_program prog;
|
||||||
|
if(!compile_set_filter(filter, prog))
|
||||||
|
return 0;
|
||||||
|
pcap_pkthdr header;
|
||||||
|
PDU *ret = 0;
|
||||||
|
while(!ret) {
|
||||||
|
const u_char *content = pcap_next(handle, &header);
|
||||||
|
try {
|
||||||
|
ret = new EthernetII((const uint8_t*)content, header.caplen);
|
||||||
|
}
|
||||||
|
catch(...) {
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pcap_freecode(&prog);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tins::Sniffer::sniff_loop(const std::string &filter, AbstractSnifferHandler *cback_handler, uint32_t max_packets) {
|
||||||
|
bpf_program prog;
|
||||||
|
if(compile_set_filter(filter, prog)) {
|
||||||
|
pcap_loop(handle, max_packets, Sniffer::callback_handler, (u_char*)cback_handler);
|
||||||
|
pcap_freecode(&prog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Static
|
||||||
|
void Tins::Sniffer::callback_handler(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) {
|
||||||
|
try {
|
||||||
|
PDU *pdu = new EthernetII((const uint8_t*)packet, header->caplen);
|
||||||
|
reinterpret_cast<AbstractSnifferHandler*>(args)->handle(pdu);
|
||||||
|
delete pdu;
|
||||||
|
}
|
||||||
|
catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
45
src/tcp.cpp
45
src/tcp.cpp
@@ -19,6 +19,7 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
@@ -41,6 +42,18 @@ Tins::TCP::TCP(uint16_t dport, uint16_t sport) : PDU(IPPROTO_TCP), _options_size
|
|||||||
this->check(0);
|
this->check(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Tins::TCP::TCP(const uint8_t *buffer, uint32_t total_sz) : PDU(IPPROTO_TCP) {
|
||||||
|
if(total_sz < sizeof(tcphdr))
|
||||||
|
throw std::runtime_error("Not enought size for an TCP header in the buffer.");
|
||||||
|
std::memcpy(&_tcp, buffer, sizeof(tcphdr));
|
||||||
|
|
||||||
|
/* Options... */
|
||||||
|
|
||||||
|
total_sz -= sizeof(tcphdr);
|
||||||
|
if(total_sz)
|
||||||
|
inner_pdu(new RawPDU(buffer + sizeof(tcphdr), total_sz));
|
||||||
|
}
|
||||||
|
|
||||||
Tins::TCP::~TCP() {
|
Tins::TCP::~TCP() {
|
||||||
for(unsigned i(0); i < _options.size(); ++i)
|
for(unsigned i(0); i < _options.size(); ++i)
|
||||||
delete[] _options[i].data;
|
delete[] _options[i].data;
|
||||||
@@ -92,6 +105,38 @@ void Tins::TCP::set_timestamp(uint32_t value, uint32_t reply) {
|
|||||||
add_option(TSOPT, 8, (uint8_t*)&buffer);
|
add_option(TSOPT, 8, (uint8_t*)&buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t Tins::TCP::get_flag(Flags tcp_flag) {
|
||||||
|
switch(tcp_flag) {
|
||||||
|
case FIN:
|
||||||
|
return _tcp.fin;
|
||||||
|
break;
|
||||||
|
case SYN:
|
||||||
|
return _tcp.syn;
|
||||||
|
break;
|
||||||
|
case RST:
|
||||||
|
return _tcp.rst;
|
||||||
|
break;
|
||||||
|
case PSH:
|
||||||
|
return _tcp.psh;
|
||||||
|
break;
|
||||||
|
case ACK:
|
||||||
|
return _tcp.ack;
|
||||||
|
break;
|
||||||
|
case URG:
|
||||||
|
return _tcp.urg;
|
||||||
|
break;
|
||||||
|
case ECE:
|
||||||
|
return _tcp.ece;
|
||||||
|
break;
|
||||||
|
case CWR:
|
||||||
|
return _tcp.cwr;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
void Tins::TCP::set_flag(Flags tcp_flag, uint8_t value) {
|
void Tins::TCP::set_flag(Flags tcp_flag, uint8_t value) {
|
||||||
switch(tcp_flag) {
|
switch(tcp_flag) {
|
||||||
case FIN:
|
case FIN:
|
||||||
|
|||||||
14
src/udp.cpp
14
src/udp.cpp
@@ -19,11 +19,12 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#endif
|
#endif
|
||||||
#include <cassert>
|
|
||||||
#include <cstring>
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "udp.h"
|
#include "udp.h"
|
||||||
#include "ip.h"
|
#include "ip.h"
|
||||||
@@ -36,6 +37,15 @@ Tins::UDP::UDP(uint16_t dport, uint16_t sport, PDU *child) : PDU(IPPROTO_UDP, ch
|
|||||||
_udp.len = 0;
|
_udp.len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Tins::UDP::UDP(const uint8_t *buffer, uint32_t total_sz) : PDU(IPPROTO_UDP) {
|
||||||
|
if(total_sz < sizeof(udphdr))
|
||||||
|
throw std::runtime_error("Not enought size for an UDP header in the buffer.");
|
||||||
|
std::memcpy(&_udp, buffer, sizeof(udphdr));
|
||||||
|
total_sz -= sizeof(udphdr);
|
||||||
|
if(total_sz)
|
||||||
|
inner_pdu(new RawPDU(buffer + sizeof(udphdr), total_sz));
|
||||||
|
}
|
||||||
|
|
||||||
void Tins::UDP::payload(uint8_t *new_payload, uint32_t new_payload_size) {
|
void Tins::UDP::payload(uint8_t *new_payload, uint32_t new_payload_size) {
|
||||||
inner_pdu(new RawPDU(new_payload, new_payload_size));
|
inner_pdu(new RawPDU(new_payload, new_payload_size));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user