mirror of
https://github.com/mfontanini/libtins
synced 2026-01-23 02:35:57 +01:00
Added enum to identify PDU type. ARP is being sent but not well implemented
This commit is contained in:
@@ -6,21 +6,40 @@
|
||||
#include "pdu.h"
|
||||
|
||||
namespace Tins {
|
||||
|
||||
|
||||
/**
|
||||
* \brief Class that represents an ARP PDU.
|
||||
*
|
||||
*/
|
||||
class ARP : public PDU {
|
||||
public:
|
||||
/**
|
||||
* \brief Enum which indicates the type of ARP packet.
|
||||
*/
|
||||
enum Flags {
|
||||
REQUEST = 0x0100,
|
||||
REPLY = 0x0200
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Default constructor for ARP PDU objects.
|
||||
*/
|
||||
ARP();
|
||||
|
||||
|
||||
/* Getters */
|
||||
/**
|
||||
* \brief Getter for the sender's hardware's address.
|
||||
*
|
||||
* \return The hardware address of the sender in an uint8_t*.
|
||||
*/
|
||||
inline const uint8_t* sender_hw_address() { return this->_arp.ar_sha; }
|
||||
|
||||
PDUType pdu_type() const { return PDU::ARP; }
|
||||
|
||||
void set_arp_request(const std::string &ip_dst, const std::string &ip_src, const std::string &hw_src = "");
|
||||
|
||||
|
||||
uint32_t header_size() const;
|
||||
|
||||
bool send(PacketSender* sender);
|
||||
|
||||
private:
|
||||
struct arphdr {
|
||||
uint16_t ar_hrd; /* format of hardware address */
|
||||
@@ -28,15 +47,15 @@ namespace Tins {
|
||||
uint8_t ar_hln; /* length of hardware address */
|
||||
uint8_t ar_pln; /* length of protocol address */
|
||||
uint16_t ar_op; /* ARP opcode (command) */
|
||||
|
||||
|
||||
uint8_t ar_sha[6]; /* sender hardware address */
|
||||
uint32_t ar_sip; /* sender IP address */
|
||||
uint8_t ar_tha[6]; /* target hardware address */
|
||||
uint32_t ar_tip; /* target IP address */
|
||||
} __attribute__((packed));
|
||||
|
||||
} __attribute__((__packed__));
|
||||
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
|
||||
|
||||
arphdr _arp;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace Tins {
|
||||
/**
|
||||
* \brief Class representing an ethernet IEEE 802.3 packet
|
||||
*/
|
||||
class Ethernet : public PDU {
|
||||
class EthernetII : public PDU {
|
||||
|
||||
public:
|
||||
/**
|
||||
@@ -46,7 +46,7 @@ namespace Tins {
|
||||
* \param iface string containing the interface's name from where to send the packet.
|
||||
* \param child PDU* with the PDU contained by the ethernet PDU (optional).
|
||||
*/
|
||||
Ethernet(const uint8_t* mac_dst, const uint8_t* mac_src, const std::string& iface, PDU* child = 0) throw (std::runtime_error);
|
||||
EthernetII(const uint8_t* mac_dst, const uint8_t* mac_src, const std::string& iface, PDU* child = 0) throw (std::runtime_error);
|
||||
|
||||
/**
|
||||
* \brief Constructor for creating an ethernet PDU
|
||||
@@ -59,7 +59,7 @@ namespace Tins {
|
||||
* \param iface_index uint32_t containing the interface's index from where to send the packet.
|
||||
* \param child PDU* with the PDU contained by the ethernet PDU (optional).
|
||||
*/
|
||||
Ethernet(const uint8_t* mac_dst, const uint8_t* mac_src, const uint32_t iface_index, PDU* child = 0);
|
||||
EthernetII(const uint8_t* mac_dst, const uint8_t* mac_src, const uint32_t iface_index, PDU* child = 0);
|
||||
|
||||
/* Getters */
|
||||
/**
|
||||
@@ -126,6 +126,8 @@ namespace Tins {
|
||||
*/
|
||||
bool send(PacketSender* sender);
|
||||
|
||||
PDUType pdu_type() const { return PDU::ETHERNET_II; }
|
||||
|
||||
private:
|
||||
/**
|
||||
* Struct that represents the Ethernet II header
|
||||
@@ -138,6 +138,8 @@ namespace Tins {
|
||||
|
||||
bool matches_response(uint8_t *ptr, uint32_t total_sz);
|
||||
|
||||
PDUType pdu_type() const { return PDU::ICMP; }
|
||||
|
||||
PDU *clone_packet(uint8_t *ptr, uint32_t total_sz);
|
||||
private:
|
||||
static uint16_t global_id, global_seq;
|
||||
|
||||
14
include/ip.h
14
include/ip.h
@@ -119,15 +119,17 @@ namespace Tins {
|
||||
/* Virtual methods */
|
||||
uint32_t header_size() const;
|
||||
bool send(PacketSender* sender);
|
||||
|
||||
|
||||
bool matches_response(uint8_t *ptr, uint32_t total_sz);
|
||||
|
||||
|
||||
PDU *recv_response(PacketSender *sender);
|
||||
|
||||
|
||||
PDUType pdu_type() const { return PDU::IP; }
|
||||
|
||||
PDU *clone_packet(uint8_t *ptr, uint32_t total_sz);
|
||||
private:
|
||||
static const uint8_t DEFAULT_TTL;
|
||||
|
||||
|
||||
struct iphdr {
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
unsigned int ihl:4;
|
||||
@@ -170,11 +172,11 @@ namespace Tins {
|
||||
} __attribute__((__packed__));
|
||||
|
||||
/** \brief Creates an instance of IP from an iphdr pointer.
|
||||
*
|
||||
*
|
||||
* \param ptr The ip header pointer.
|
||||
*/
|
||||
IP(const iphdr *ptr);
|
||||
|
||||
|
||||
void init_ip_fields();
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ namespace Tins {
|
||||
enum SocketType {
|
||||
ETHER_SOCKET,
|
||||
IP_SOCKET,
|
||||
ARP_SOCKET,
|
||||
ICMP_SOCKET,
|
||||
SOCKETS_END
|
||||
};
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
* libtins is a net packet wrapper library for crafting and
|
||||
* libtins is a net packet wrapper library for crafting and
|
||||
* interpreting sniffed packets.
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2011 Nasel
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
@@ -31,7 +31,7 @@ namespace Tins {
|
||||
class PacketSender;
|
||||
|
||||
/** \brief PDU is the base class for protocol data units.
|
||||
*
|
||||
*
|
||||
* Every PDU implementation must inherit this one. PDUs can be serialized,
|
||||
* therefore allowing a PacketSender to send them through sockets. PDUs
|
||||
* are created upwards: upper layers will be children of the lower ones.
|
||||
@@ -41,6 +41,22 @@ namespace Tins {
|
||||
*/
|
||||
class PDU {
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief Enum which identifies each type of PDU.
|
||||
*
|
||||
* This enum is used to identify the PDU type.
|
||||
*/
|
||||
enum PDUType {
|
||||
RAW,
|
||||
ETHERNET_II,
|
||||
IP,
|
||||
ARP,
|
||||
TCP,
|
||||
UDP,
|
||||
ICMP
|
||||
};
|
||||
|
||||
/** \brief PDU constructor
|
||||
*
|
||||
* Must be called by subclasses in their constructors.
|
||||
@@ -53,24 +69,24 @@ namespace Tins {
|
||||
/** \brief The header's size
|
||||
*/
|
||||
virtual uint32_t header_size() const = 0;
|
||||
|
||||
|
||||
/** \brief Trailer's size.
|
||||
*
|
||||
*
|
||||
* Some protocols require a trailer(like Ethernet). This defaults to 0.
|
||||
*/
|
||||
virtual uint32_t trailer_size() const { return 0; }
|
||||
|
||||
|
||||
/** \brief The whole chain of PDU's size, including this one.
|
||||
*
|
||||
*
|
||||
* Returns the sum of this and all children PDUs' size.
|
||||
*/
|
||||
uint32_t size() const;
|
||||
|
||||
/** \brief This PDU's type flag identifier.
|
||||
*
|
||||
|
||||
/** \brief This PDU's type flag identifier.
|
||||
*
|
||||
*/
|
||||
inline uint32_t flag() const { return _flag; }
|
||||
|
||||
|
||||
/** \brief The child PDU.
|
||||
*/
|
||||
inline PDU *inner_pdu() const { return _inner_pdu; }
|
||||
@@ -78,26 +94,26 @@ namespace Tins {
|
||||
/** \brief Sets the flag identifier.
|
||||
*/
|
||||
void flag(uint32_t new_flag);
|
||||
|
||||
|
||||
/** \brief Sets the child PDU.
|
||||
*
|
||||
*
|
||||
* \param next_pdu The new child PDU.
|
||||
* When setting a new inner_pdu, the instance takesownership of
|
||||
* When setting a new inner_pdu, the instance takesownership of
|
||||
* the object, therefore deleting it when it's no longer required.
|
||||
*/
|
||||
void inner_pdu(PDU *next_pdu);
|
||||
|
||||
|
||||
/** \brief Serializes the whole chain of PDU's, including this one.
|
||||
*
|
||||
|
||||
/** \brief Serializes the whole chain of PDU's, including this one.
|
||||
*
|
||||
* \param sz The size of the buffer must be returned through this parameter.
|
||||
* The buffer returned must be deleted by the user using
|
||||
* operator delete[].
|
||||
* The buffer returned must be deleted by the user using
|
||||
* operator delete[].
|
||||
*/
|
||||
uint8_t *serialize(uint32_t &sz);
|
||||
|
||||
/** \brief Send the stack of PDUs through a PacketSender.
|
||||
*
|
||||
*
|
||||
* This method will be called only for the PDU on the bottom of the stack,
|
||||
* therefore it should only implement this method if it can be sent.
|
||||
* PacketSender implements specific methods to send packets which start
|
||||
@@ -106,16 +122,16 @@ namespace Tins {
|
||||
* \param sender The PacketSender which will send the packet.
|
||||
*/
|
||||
virtual bool send(PacketSender *sender) { return false; }
|
||||
|
||||
|
||||
/** \brief Receives a matching response for this packet.
|
||||
*
|
||||
*
|
||||
* This method should act as a proxy for PacketSender::recv_lX methods.
|
||||
* \param sender The packet sender which will receive the packet.
|
||||
*/
|
||||
virtual PDU *recv_response(PacketSender *sender) { return false; }
|
||||
|
||||
|
||||
/** \brief Check wether ptr points to a valid response for this PDU.
|
||||
*
|
||||
*
|
||||
* This method must check wether the buffer pointed by ptr is a valid
|
||||
* response for this PDU. If it is valid, then it might want to propagate
|
||||
* the call to the next PDU. Note that in some cases, such as ICMP
|
||||
@@ -124,14 +140,21 @@ namespace Tins {
|
||||
* \param total_sz The size of the buffer.
|
||||
*/
|
||||
virtual bool matches_response(uint8_t *ptr, uint32_t total_sz) { return false; }
|
||||
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
*
|
||||
* \return Returns the PDUType corresponding to the PDU.
|
||||
*/
|
||||
virtual PDUType pdu_type() const = 0;
|
||||
|
||||
virtual PDU *clone_packet(uint8_t *ptr, uint32_t total_sz) { return 0; }
|
||||
protected:
|
||||
/* Serialize this PDU storing the result in buffer. */
|
||||
void serialize(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
|
||||
/** \brief Serialices this TCP PDU.
|
||||
*
|
||||
*
|
||||
* Each PDU must override this method and implement it's own
|
||||
* serialization.
|
||||
* \param buffer The buffer in which the PDU will be serialized.
|
||||
@@ -139,7 +162,7 @@ namespace Tins {
|
||||
* \param parent The PDU that's one level below this one on the stack. Might be 0.
|
||||
*/
|
||||
virtual void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) = 0;
|
||||
|
||||
|
||||
static uint32_t do_checksum(uint8_t *start, uint8_t *end);
|
||||
static uint32_t pseudoheader_checksum(uint32_t source_ip, uint32_t dest_ip, uint32_t len, uint32_t flag);
|
||||
private:
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
* libtins is a net packet wrapper library for crafting and
|
||||
* libtins is a net packet wrapper library for crafting and
|
||||
* interpreting sniffed packets.
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2011 Nasel
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
@@ -27,31 +27,34 @@
|
||||
|
||||
|
||||
namespace Tins {
|
||||
|
||||
|
||||
/** \brief Represents a PDU which holds raw data.
|
||||
*
|
||||
*
|
||||
* In order to send payloads over TCP, UDP, or other transport layer or
|
||||
* higher level protocols, RawPDU can be used as a wrapper for raw byte arrays.
|
||||
*/
|
||||
class RawPDU : public PDU {
|
||||
public:
|
||||
/** \brief Creates an instance of RawPDU.
|
||||
*
|
||||
*
|
||||
* The payload is NOT copied. Therefore, it must be manually freed by the user.
|
||||
* \param payload The payload which the RawPDU will contain.
|
||||
* \param size The size of the payload.
|
||||
*/
|
||||
|
||||
|
||||
RawPDU(uint8_t *payload, uint32_t size);
|
||||
|
||||
|
||||
/** \brief Returns the header size.
|
||||
*
|
||||
*
|
||||
* This metod overrides PDU::header_size. \sa PDU::header_size
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
PDUType pdu_type() const { return PDU::RAW; }
|
||||
|
||||
private:
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
|
||||
|
||||
uint8_t *_payload;
|
||||
uint32_t _payload_size;
|
||||
};
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
* libtins is a net packet wrapper library for crafting and
|
||||
* libtins is a net packet wrapper library for crafting and
|
||||
* interpreting sniffed packets.
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2011 Nasel
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
@@ -34,7 +34,7 @@
|
||||
namespace Tins {
|
||||
|
||||
/** \brief TCP represents the TCP PDU.
|
||||
*
|
||||
*
|
||||
* TCP is the representation of the TCP PDU. Instances of this class
|
||||
* must be sent over a level 3 PDU, this will otherwise fail.
|
||||
*/
|
||||
@@ -42,7 +42,7 @@ namespace Tins {
|
||||
class TCP : public PDU {
|
||||
public:
|
||||
/** \brief TCP flags enum.
|
||||
*
|
||||
*
|
||||
* These flags identify those supported by the TCP PDU.
|
||||
*/
|
||||
enum Flags {
|
||||
@@ -55,139 +55,142 @@ namespace Tins {
|
||||
ECE,
|
||||
CWR
|
||||
};
|
||||
|
||||
|
||||
/** \brief TCP options enum.
|
||||
*
|
||||
*
|
||||
* This enum identifies valid options supported by TCP PDU.
|
||||
*/
|
||||
|
||||
|
||||
enum Options {
|
||||
MSS = 2,
|
||||
TSOPT = 8
|
||||
};
|
||||
|
||||
|
||||
/** \brief TCP constructor.
|
||||
*
|
||||
*
|
||||
* Creates an instance of TCP. Destination and source port can
|
||||
* be provided, otherwise both will be 0.
|
||||
* \param dport Destination port.
|
||||
* \param sport Source port.
|
||||
* */
|
||||
|
||||
|
||||
TCP(uint16_t dport = 0, uint16_t sport = 0);
|
||||
|
||||
|
||||
/** \brief TCP destructor.
|
||||
*
|
||||
*
|
||||
* Destructs the TCP instance. Does not free the payload.
|
||||
* */
|
||||
|
||||
|
||||
~TCP();
|
||||
|
||||
|
||||
/** \brief Returns the destination port.
|
||||
*/
|
||||
inline uint16_t dport() const { return _tcp.dport; }
|
||||
|
||||
|
||||
/** \brief Returns the source port.
|
||||
*/
|
||||
inline uint16_t sport() const { return _tcp.sport; }
|
||||
|
||||
|
||||
/** \brief Returns the sequence number.
|
||||
*/
|
||||
inline uint32_t seq() const { return _tcp.seq; }
|
||||
|
||||
|
||||
/** \brief Returns the acknowledge number.
|
||||
*/
|
||||
inline uint32_t ack_seq() const { return _tcp.ack_seq; }
|
||||
|
||||
|
||||
/** \brief Returns the window size.
|
||||
*/
|
||||
inline uint16_t window() const { return _tcp.window; }
|
||||
|
||||
|
||||
/** \brief Returns the checksum.
|
||||
*/
|
||||
inline uint16_t check() const { return _tcp.check; }
|
||||
|
||||
|
||||
/** \brief Returns the urgent pointer.
|
||||
*/
|
||||
inline uint16_t urg_ptr() const { return _tcp.urg_ptr; }
|
||||
|
||||
|
||||
/** \brief Set the destination port.
|
||||
* \param new_dport New destination port.
|
||||
*/
|
||||
void dport(uint16_t new_dport);
|
||||
|
||||
|
||||
/** \brief Set the source port.
|
||||
* \param new_sport New source port.
|
||||
*/
|
||||
void sport(uint16_t new_sport);
|
||||
|
||||
|
||||
/** \brief Set the sequence number.
|
||||
* \param new_seq New sequence number.
|
||||
*/
|
||||
void seq(uint32_t new_seq);
|
||||
|
||||
|
||||
/** \brief Set the acknowledge number.
|
||||
* \param new_ack_seq New acknowledge number.
|
||||
*/
|
||||
void ack_seq(uint32_t new_ack_seq);
|
||||
|
||||
|
||||
/** \brief Set the window size.
|
||||
* \param new_window New window size.
|
||||
*/
|
||||
void window(uint16_t new_window);
|
||||
|
||||
|
||||
/** \brief Set the checksum.
|
||||
* \param new_check New checksum.
|
||||
*/
|
||||
void check(uint16_t new_check);
|
||||
|
||||
|
||||
/** \brief Set the urgent pointer.
|
||||
* \param new_urg_ptr New urgent pointer.
|
||||
*/
|
||||
void urg_ptr(uint16_t new_urg_ptr);
|
||||
|
||||
|
||||
/** \brief Set the payload.
|
||||
*
|
||||
* Payload is NOT copied. Therefore, pointers provided as
|
||||
*
|
||||
* Payload is NOT copied. Therefore, pointers provided as
|
||||
* payloads must be freed manually by the user. This actually
|
||||
* creates a RawPDU that holds the payload, and sets it as the
|
||||
* creates a RawPDU that holds the payload, and sets it as the
|
||||
* inner_pdu. Therefore, if an inner_pdu was set previously,
|
||||
* a call to TCP::payload will delete it.
|
||||
* \param new_payload New payload.
|
||||
* \param new_payload_size New payload's size
|
||||
*/
|
||||
void payload(uint8_t *new_payload, uint32_t new_payload_size);
|
||||
|
||||
|
||||
/** \brief Set maximum segment size.
|
||||
* \param value New maximum segment size.
|
||||
*/
|
||||
void set_mss(uint16_t value);
|
||||
|
||||
|
||||
/** \brief Set the timestamp.
|
||||
* \param value Current value of the timestamp clock.
|
||||
* \param reply Echo reply field.
|
||||
*/
|
||||
void set_timestamp(uint32_t value, uint32_t reply);
|
||||
|
||||
|
||||
/** \brief Set a TCP flag value.
|
||||
* \param tcp_flag Indicates which flag will be set.
|
||||
* \param value New value for this flag. Must be 0 or 1.
|
||||
*/
|
||||
void set_flag(Flags tcp_flag, uint8_t value);
|
||||
|
||||
|
||||
/** \brief Adds a TCP option.
|
||||
* \param tcp_option Indicates the option that will be set.
|
||||
* \param length Length of this option.
|
||||
* \param data This option's data.
|
||||
*/
|
||||
void add_option(Options tcp_option, uint8_t length = 0, uint8_t *data = 0);
|
||||
|
||||
|
||||
/** \brief Returns the header size.
|
||||
*
|
||||
*
|
||||
* This metod overrides PDU::header_size. This size includes the
|
||||
* payload and options size. \sa PDU::header_size
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
PDUType pdu_type() const { return PDU::TCP; }
|
||||
|
||||
private:
|
||||
struct tcphdr {
|
||||
uint16_t sport;
|
||||
@@ -218,31 +221,31 @@ namespace Tins {
|
||||
fin:1;
|
||||
#else
|
||||
#error "Endian is not LE nor BE..."
|
||||
#endif
|
||||
#endif
|
||||
uint16_t window;
|
||||
uint16_t check;
|
||||
uint16_t urg_ptr;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
struct TCPOption {
|
||||
TCPOption(uint8_t okind, uint8_t olength, uint8_t *odata) :
|
||||
kind(okind), length(olength), data(odata) { }
|
||||
|
||||
kind(okind), length(olength), data(odata) { }
|
||||
|
||||
uint8_t *write(uint8_t *buffer);
|
||||
|
||||
|
||||
uint8_t kind, length;
|
||||
uint8_t *data;
|
||||
};
|
||||
|
||||
|
||||
static const uint16_t DEFAULT_WINDOW;
|
||||
|
||||
|
||||
/** \brief Serialices this TCP PDU.
|
||||
* \param buffer The buffer in which the PDU will be serialized.
|
||||
* \param total_sz The size available in the buffer.
|
||||
* \param parent The PDU that's one level below this one on the stack.
|
||||
*/
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
|
||||
|
||||
tcphdr _tcp;
|
||||
std::vector<TCPOption> _options;
|
||||
uint32_t _options_size, _total_options_size;
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
* libtins is a net packet wrapper library for crafting and
|
||||
* libtins is a net packet wrapper library for crafting and
|
||||
* interpreting sniffed packets.
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2011 Nasel
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
@@ -28,60 +28,63 @@
|
||||
namespace Tins {
|
||||
|
||||
/** \brief UDP represents the UDP PDU.
|
||||
*
|
||||
*
|
||||
* UDP is the representation of the UDP PDU. Instances of this class
|
||||
* must be sent over a level 3 PDU, this will otherwise fail.
|
||||
*/
|
||||
class UDP : public PDU {
|
||||
public:
|
||||
/** \brief UDP constructor.
|
||||
*
|
||||
*
|
||||
* Creates an instance of UDP. Destination and source port can
|
||||
* be provided, otherwise both will be 0.
|
||||
* \param dport Destination port.
|
||||
* \param sport Source port.
|
||||
* */
|
||||
UDP(uint16_t sport = 0, uint16_t dport = 0);
|
||||
|
||||
|
||||
|
||||
|
||||
/** \brief Returns the destination port
|
||||
*/
|
||||
inline uint16_t dport() const { return _udp.dport; }
|
||||
|
||||
|
||||
/** \brief Returns the source port
|
||||
*/
|
||||
inline uint16_t sport() const { return _udp.sport; }
|
||||
|
||||
|
||||
/** \brief Set the destination port.
|
||||
*
|
||||
*
|
||||
* \param new_dport The new destination port.
|
||||
*/
|
||||
void dport(uint16_t new_dport);
|
||||
|
||||
|
||||
/** \brief Set the source port.
|
||||
*
|
||||
*
|
||||
* \param new_sport The new source port.
|
||||
*/
|
||||
void sport(uint16_t new_sport);
|
||||
|
||||
|
||||
/** \brief Set the payload.
|
||||
*
|
||||
* Payload is NOT copied. Therefore, pointers provided as
|
||||
*
|
||||
* Payload is NOT copied. Therefore, pointers provided as
|
||||
* payloads must be freed manually by the user. This actually
|
||||
* creates a RawPDU that holds the payload, and sets it as the
|
||||
* creates a RawPDU that holds the payload, and sets it as the
|
||||
* inner_pdu. Therefore, if an inner_pdu was set previously,
|
||||
* a call to UDP::payload will delete it.
|
||||
* \param new_payload New payload.
|
||||
* \param new_payload_size New payload's size
|
||||
*/
|
||||
void payload(uint8_t *new_payload, uint32_t new_payload_size);
|
||||
|
||||
|
||||
/** \brief Returns the header size.
|
||||
*
|
||||
*
|
||||
* This metod overrides PDU::header_size. This size includes the
|
||||
* payload and options size. \sa PDU::header_size
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
PDUType pdu_type() const { return PDU::UDP; }
|
||||
|
||||
private:
|
||||
struct udphdr {
|
||||
uint16_t sport;
|
||||
@@ -89,9 +92,9 @@ namespace Tins {
|
||||
uint16_t len;
|
||||
uint16_t check;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
|
||||
|
||||
udphdr _udp;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -29,12 +29,3 @@ void Tins::ARP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PD
|
||||
memcpy(buffer, &_arp, sizeof(arphdr));
|
||||
}
|
||||
|
||||
bool Tins::ARP::send(PacketSender* sender) {
|
||||
struct sockaddr_in link_addr;
|
||||
link_addr.sin_family = AF_INET;
|
||||
link_addr.sin_port = 0;
|
||||
link_addr.sin_addr.s_addr = _arp.ar_sip;
|
||||
|
||||
return sender->send_l3(this, (struct sockaddr*)&link_addr, sizeof(link_addr), PacketSender::IP_SOCKET);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,46 +28,50 @@
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#include "ethernet.h"
|
||||
#include "ethernetII.h"
|
||||
#include "utils.h"
|
||||
|
||||
Tins::Ethernet::Ethernet(const uint8_t* mac_dst, const uint8_t* mac_src, const std::string& iface, PDU* child) throw (std::runtime_error) : PDU(ETHERTYPE_IP, child) {
|
||||
#include <iostream>
|
||||
|
||||
Tins::EthernetII::EthernetII(const uint8_t* mac_dst, const uint8_t* mac_src, const std::string& iface, PDU* child) throw (std::runtime_error) : PDU(ETHERTYPE_IP, child) {
|
||||
|
||||
this->dst_mac(mac_dst);
|
||||
this->src_mac(mac_src);
|
||||
this->iface(iface);
|
||||
this->header.payload_type = 0;
|
||||
|
||||
}
|
||||
|
||||
Tins::Ethernet::Ethernet(const uint8_t* mac_dst, const uint8_t* mac_src, uint32_t iface_index, PDU* child) : PDU(ETHERTYPE_IP, child) {
|
||||
Tins::EthernetII::EthernetII(const uint8_t* mac_dst, const uint8_t* mac_src, uint32_t iface_index, PDU* child) : PDU(ETHERTYPE_IP, child) {
|
||||
this->dst_mac(mac_dst);
|
||||
this->src_mac(mac_src);
|
||||
this->iface(iface_index);
|
||||
this->header.payload_type = 0;
|
||||
}
|
||||
|
||||
void Tins::Ethernet::dst_mac(const uint8_t* new_dst_mac) {
|
||||
void Tins::EthernetII::dst_mac(const uint8_t* new_dst_mac) {
|
||||
memcpy(this->header.dst_mac, new_dst_mac, 6);
|
||||
}
|
||||
|
||||
void Tins::Ethernet::src_mac(const uint8_t* new_src_mac) {
|
||||
void Tins::EthernetII::src_mac(const uint8_t* new_src_mac) {
|
||||
memcpy(this->header.src_mac, new_src_mac, 6);
|
||||
}
|
||||
|
||||
void Tins::Ethernet::iface(uint32_t new_iface_index) {
|
||||
void Tins::EthernetII::iface(uint32_t new_iface_index) {
|
||||
this->_iface_index = new_iface_index;
|
||||
}
|
||||
|
||||
void Tins::Ethernet::iface(const std::string& new_iface) throw (std::runtime_error) {
|
||||
void Tins::EthernetII::iface(const std::string& new_iface) throw (std::runtime_error) {
|
||||
if (!Tins::Utils::interface_id(new_iface, this->_iface_index)) {
|
||||
throw std::runtime_error("Invalid interface name!");
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t Tins::Ethernet::header_size() const {
|
||||
uint32_t Tins::EthernetII::header_size() const {
|
||||
return sizeof(ethernet_header);
|
||||
}
|
||||
|
||||
bool Tins::Ethernet::send(PacketSender* sender) {
|
||||
bool Tins::EthernetII::send(PacketSender* sender) {
|
||||
|
||||
struct sockaddr_ll addr;
|
||||
|
||||
@@ -83,21 +87,28 @@ bool Tins::Ethernet::send(PacketSender* sender) {
|
||||
|
||||
}
|
||||
|
||||
void Tins::Ethernet::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) {
|
||||
void Tins::EthernetII::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) {
|
||||
uint32_t my_sz = header_size();
|
||||
assert(total_sz >= my_sz);
|
||||
/*
|
||||
if (this->inner_pdu()) {
|
||||
new_flag = this->inner_pdu()->flag();
|
||||
|
||||
switch (new_flag) {
|
||||
/* Inner type defaults to IP */
|
||||
|
||||
if ((this->header.payload_type == 0) && this->inner_pdu()) {
|
||||
uint16_t type = ETHERTYPE_IP;
|
||||
switch (this->inner_pdu()->pdu_type()) {
|
||||
case PDU::IP:
|
||||
type = ETHERTYPE_IP;
|
||||
break;
|
||||
case PDU::ARP:
|
||||
type = ETHERTYPE_ARP;
|
||||
break;
|
||||
default:
|
||||
type = 0;
|
||||
}
|
||||
|
||||
std::cout << std::hex << type << '\n';
|
||||
this->header.payload_type = Utils::net_to_host_s(type);
|
||||
}
|
||||
*/
|
||||
/* This should be replaced by a switch statement */
|
||||
this->header.payload_type = Utils::net_to_host_s(ETHERTYPE_IP);
|
||||
|
||||
|
||||
memcpy(buffer, &this->header, sizeof(ethernet_header));
|
||||
|
||||
18
src/tcp.cpp
18
src/tcp.cpp
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
* libtins is a net packet wrapper library for crafting and
|
||||
* libtins is a net packet wrapper library for crafting and
|
||||
* interpreting sniffed packets.
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2011 Nasel
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
@@ -138,17 +138,17 @@ void Tins::TCP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PD
|
||||
for(unsigned i(0); i < _options.size(); ++i)
|
||||
buffer = _options[i].write(buffer);
|
||||
|
||||
if(_options_size < _total_options_size) {
|
||||
if(_options_size < _total_options_size) {
|
||||
uint8_t padding = _total_options_size;
|
||||
while(padding < _options_size) {
|
||||
*(buffer++) = 1;
|
||||
padding++;
|
||||
}
|
||||
}
|
||||
|
||||
const IP *ip_packet = dynamic_cast<const IP*>(parent);
|
||||
|
||||
const Tins::IP *ip_packet = dynamic_cast<const Tins::IP*>(parent);
|
||||
if(!_tcp.check && ip_packet) {
|
||||
uint32_t checksum = PDU::pseudoheader_checksum(ip_packet->source_address(), ip_packet->dest_address(), size(), IPPROTO_TCP) +
|
||||
uint32_t checksum = PDU::pseudoheader_checksum(ip_packet->source_address(), ip_packet->dest_address(), size(), IPPROTO_TCP) +
|
||||
PDU::do_checksum(tcp_start + sizeof(tcphdr), tcp_start + total_sz) + PDU::do_checksum((uint8_t*)&_tcp, ((uint8_t*)&_tcp) + sizeof(tcphdr));
|
||||
while (checksum >> 16)
|
||||
checksum = (checksum & 0xffff) + (checksum >> 16);
|
||||
|
||||
16
src/udp.cpp
16
src/udp.cpp
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
* libtins is a net packet wrapper library for crafting and
|
||||
* libtins is a net packet wrapper library for crafting and
|
||||
* interpreting sniffed packets.
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2011 Nasel
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
@@ -44,7 +44,7 @@ void Tins::UDP::payload(uint8_t *new_payload, uint32_t new_payload_size) {
|
||||
void Tins::UDP::dport(uint16_t new_dport) {
|
||||
_udp.dport = new_dport;
|
||||
}
|
||||
|
||||
|
||||
void Tins::UDP::sport(uint16_t new_sport) {
|
||||
_udp.sport = new_sport;
|
||||
}
|
||||
@@ -55,9 +55,9 @@ uint32_t Tins::UDP::header_size() const {
|
||||
|
||||
void Tins::UDP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) {
|
||||
assert(total_sz >= sizeof(udphdr));
|
||||
const IP *ip_packet = dynamic_cast<const IP*>(parent);
|
||||
const Tins::IP *ip_packet = dynamic_cast<const Tins::IP*>(parent);
|
||||
if(!_udp.check && ip_packet) {
|
||||
uint32_t checksum = PDU::pseudoheader_checksum(ip_packet->source_address(), ip_packet->dest_address(), size(), IPPROTO_UDP) +
|
||||
uint32_t checksum = PDU::pseudoheader_checksum(ip_packet->source_address(), ip_packet->dest_address(), size(), IPPROTO_UDP) +
|
||||
PDU::do_checksum(buffer + sizeof(udphdr), buffer + total_sz) + PDU::do_checksum((uint8_t*)&_udp, ((uint8_t*)&_udp) + sizeof(udphdr));
|
||||
while (checksum >> 16)
|
||||
checksum = (checksum & 0xffff)+(checksum >> 16);
|
||||
|
||||
Reference in New Issue
Block a user