1
0
mirror of https://github.com/mfontanini/libtins synced 2026-01-23 02:35:57 +01:00

Added copy constructor and copy assignment operator to all PDUs.

This commit is contained in:
Matias Fontanini
2011-09-03 18:58:57 -03:00
parent fdcefd2132
commit 3178c217b3
22 changed files with 615 additions and 22 deletions

View File

@@ -59,7 +59,17 @@ namespace Tins {
* \param total_sz The total size of the buffer.
*/
ARP(const uint8_t *buffer, uint32_t total_sz);
/**
* \brief Copy constructor.
*/
ARP(const ARP &other);
/**
* \brief Copy asignment operator.
*/
ARP &operator= (const ARP &other);
/* Getters */
/**
* \brief Getter for the sender's hardware address.
@@ -315,6 +325,12 @@ namespace Tins {
*/
PDU *clone_packet(const uint8_t *ptr, uint32_t total_sz);
/**
* \brief Clones this PDU.
*
* \sa PDU::clone_pdu
*/
PDU *clone_pdu() const;
private:
struct arphdr {
uint16_t ar_hrd; /* format of hardware address */
@@ -335,6 +351,7 @@ namespace Tins {
*/
ARP(const arphdr *arp_ptr);
void copy_fields(const ARP *other);
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
arphdr _arp;

View File

@@ -63,6 +63,16 @@ namespace Tins {
*/
BootP(const uint8_t *buffer, uint32_t total_sz, uint32_t vend_field_size = 64);
/**
* \brief Copy constructor.
*/
BootP(const BootP &other);
/**
* \brief Copy assignment operator.
*/
BootP &operator= (const BootP &other);
/** \brief BootP destructor.
*
* This frees the memory allocated to hold the vend field.
@@ -232,7 +242,21 @@ namespace Tins {
* \param size The size of the new vend field.
*/
void vend(uint8_t *new_vend, uint32_t size);
/**
* \brief Getter for the PDU's type.
* \sa PDU::pdu_type
*/
PDUType pdu_type() const { return PDU::BOOTP; }
/**
* \brief Clones this PDU.
*
* \sa PDU::clone_pdu
*/
PDU *clone_pdu() const;
protected:
void copy_bootp_fields(const BootP *other);
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
private:
/**
@@ -255,7 +279,6 @@ namespace Tins {
uint8_t file[128];
} __attribute__((__packed__));
bootphdr _bootp;
uint8_t *_vend;
uint32_t _vend_size;

View File

@@ -172,7 +172,17 @@ namespace Tins {
* Subclasses might use 0 to provide their own interpretation of this field.
*/
DHCP(const uint8_t *buffer, uint32_t total_sz);
/**
* \brief Copy constructor.
*/
DHCP(const DHCP &other);
/**
* \brief Copy assignment operator.
*/
DHCP &operator= (const DHCP &other);
/**
* \brief DHCP destructor
*
@@ -265,9 +275,17 @@ namespace Tins {
* \sa PDU::header_size
*/
uint32_t header_size() const;
/**
* \brief Clones this PDU.
*
* \sa PDU::clone_pdu
*/
PDU *clone_pdu() const;
private:
static const uint32_t MAX_DHCP_SIZE;
void copy_fields(const DHCP *other);
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
uint8_t *serialize_list(const std::list<uint32_t> &int_list, uint32_t &sz);

View File

@@ -117,6 +117,11 @@ namespace Tins {
*/
EAPOL(uint8_t packet_type, EAPOLTYPE type);
/**
* \brief Copy constructor.
*/
EAPOL(const EAPOL &other);
/**
* \brief Constructor which creates an EAPOL object from a buffer.
* \param buffer The buffer from which this PDU will be constructed.
@@ -124,6 +129,8 @@ namespace Tins {
*/
EAPOL(const uint8_t *buffer, uint32_t total_sz);
void copy_eapol_fields(const EAPOL *other);
struct eapolhdr {
uint8_t version, packet_type;
uint16_t length;
@@ -169,6 +176,16 @@ namespace Tins {
*/
RC4EAPOL(const uint8_t *buffer, uint32_t total_sz);
/**
* \brief Copy constructor.
*/
RC4EAPOL(const RC4EAPOL &other);
/**
* \brief Copy assignment operator.
*/
RC4EAPOL &operator= (const RC4EAPOL &other);
/**
* \brief RC4EAPOL destructor
*
@@ -275,6 +292,13 @@ namespace Tins {
* \sa PDU::header_size
*/
uint32_t header_size() const;
/**
* \brief Clones this PDU.
*
* \sa PDU::clone_pdu
*/
PDU *clone_pdu() const;
private:
struct rc4hdr {
uint16_t key_length;
@@ -285,6 +309,7 @@ namespace Tins {
uint8_t key_sign[16];
} __attribute__((__packed__));
void copy_fields(const RC4EAPOL *other);
void write_body(uint8_t *buffer, uint32_t total_sz);
@@ -311,6 +336,16 @@ namespace Tins {
*/
RSNEAPOL(const uint8_t *buffer, uint32_t total_sz);
/**
* \brief Copy constructor.
*/
RSNEAPOL(const RSNEAPOL &other);
/**
* \brief Copy assignment operator.
*/
RSNEAPOL &operator= (const RSNEAPOL &other);
/**
* \brief Destructor.
*
@@ -455,6 +490,13 @@ namespace Tins {
* \sa RSNInformation.
*/
void rsn_information(const RSNInformation &rsn);
/**
* \brief Clones this PDU.
*
* \sa PDU::clone_pdu
*/
PDU *clone_pdu() const;
private:
struct rsnhdr {
uint16_t key_mic:1,
@@ -476,6 +518,8 @@ namespace Tins {
uint16_t wpa_length;
} __attribute__((__packed__));
void copy_fields(const RSNEAPOL *other);
void write_body(uint8_t *buffer, uint32_t total_sz);

View File

@@ -56,6 +56,16 @@ namespace Tins {
* \param flag The type flag which will be set.
*/
ICMP(Flags flag = ECHO_REQUEST);
/**
* \brief Copy constructor.
*/
ICMP(const ICMP &other);
/**
* \brief Copy assignment operator.
*/
ICMP &operator= (const ICMP &other);
/**
* \brief Constructor which creates an ICMP object from a buffer and adds all identifiable
@@ -282,6 +292,13 @@ namespace Tins {
* \sa PDU::clone_packet
*/
PDU *clone_packet(const uint8_t *ptr, uint32_t total_sz);
/**
* \brief Clones this PDU.
*
* \sa PDU::clone_pdu
*/
PDU *clone_pdu() const;
private:
static uint16_t global_id, global_seq;
@@ -308,6 +325,8 @@ namespace Tins {
*/
ICMP(const icmphdr *ptr);
void copy_fields(const ICMP *other);
/** \brief Serialices this ICMP PDU.
* \param buffer The buffer in which the PDU will be serialized.
* \param total_sz The size available in the buffer.

View File

@@ -36,9 +36,7 @@ namespace Tins {
* \brief Class representing an 802.11 frame.
*/
class IEEE802_11 : public PDU {
public:
/**
* \brief Broadcast hardware address.
*/
@@ -217,6 +215,11 @@ namespace Tins {
* \param total_sz The total size of the buffer.
*/
IEEE802_11(const uint8_t *buffer, uint32_t total_sz);
/**
* \brief Copy constructor.
*/
IEEE802_11(const IEEE802_11 &other);
/**
* \brief IEEE802_11 destructor.
@@ -225,6 +228,11 @@ namespace Tins {
*/
~IEEE802_11();
/**
* \brief Copy assignment operator.
*/
IEEE802_11 &operator= (const IEEE802_11 &other);
/**
* \brief Getter for the protocol version.
*
@@ -531,6 +539,7 @@ namespace Tins {
protected:
virtual uint32_t write_fixed_parameters(uint8_t *buffer, uint32_t total_sz) { return 0; }
void parse_tagged_parameters(const uint8_t *buffer, uint32_t total_sz);
void copy_80211_fields(const IEEE802_11 *other);
protected:
/**
* Struct that represents the 802.11 header
@@ -995,6 +1004,7 @@ namespace Tins {
ManagementFrame(const uint8_t *dst_hw_addr = 0, const uint8_t *src_hw_addr = 0);
ManagementFrame(const std::string &iface, const uint8_t *dst_hw_addr, const uint8_t *src_hw_addr) throw (std::runtime_error);
ManagementFrame(const uint8_t *buffer, uint32_t total_sz);
ManagementFrame(const ManagementFrame &other);
void ssid(const std::string &new_ssid);
void rates(const std::list<float> &new_rates);
@@ -1050,6 +1060,16 @@ namespace Tins {
*/
IEEE802_11_Beacon(const uint8_t *buffer, uint32_t total_sz);
/**
* \brief Copy constructor.
*/
IEEE802_11_Beacon(const IEEE802_11_Beacon &other);
/**
* \brief Copy assignment operator.
*/
IEEE802_11_Beacon &operator= (const IEEE802_11_Beacon &other);
/**
* \brief Getter for the timestamp field.
*
@@ -1148,10 +1168,11 @@ namespace Tins {
CapabilityInformation capability;
} __attribute__((__packed__));
BeaconBody _body;
void copy_fields(const IEEE802_11_Beacon *other);
uint32_t write_fixed_parameters(uint8_t *buffer, uint32_t total_sz);
BeaconBody _body;
};
/**
@@ -1180,6 +1201,16 @@ namespace Tins {
*/
IEEE802_11_Disassoc(const std::string& iface, const uint8_t* dst_hw_addr = 0, const uint8_t* src_hw_addr = 0) throw (std::runtime_error);
/**
* \brief Copy constructor.
*/
IEEE802_11_Disassoc(const IEEE802_11_Disassoc &other);
/**
* \brief Copy assignment operator.
*/
IEEE802_11_Disassoc &operator= (const IEEE802_11_Disassoc &other);
/**
* \brief Getter for the reason code.
*
@@ -1206,6 +1237,7 @@ namespace Tins {
uint16_t reason_code;
};
void copy_fields(const IEEE802_11_Disassoc *other);
uint32_t write_fixed_parameters(uint8_t *buffer, uint32_t total_sz);
@@ -1247,6 +1279,16 @@ namespace Tins {
*/
IEEE802_11_Assoc_Request(const uint8_t *buffer, uint32_t total_sz);
/**
* \brief Copy constructor.
*/
IEEE802_11_Assoc_Request(const IEEE802_11_Assoc_Request &other);
/**
* \brief Copy assignment operator.
*/
IEEE802_11_Assoc_Request &operator= (const IEEE802_11_Assoc_Request &other);
/**
* \brief Getter for the Capabilities Information.
*
@@ -1338,6 +1380,7 @@ namespace Tins {
uint16_t listen_interval;
};
void copy_fields(const IEEE802_11_Assoc_Request *other);
uint32_t write_fixed_parameters(uint8_t *buffer, uint32_t total_sz);
AssocReqBody _body;
@@ -1378,6 +1421,16 @@ namespace Tins {
*/
IEEE802_11_Assoc_Response(const uint8_t *buffer, uint32_t total_sz);
/**
* \brief Copy constructor.
*/
IEEE802_11_Assoc_Response(const IEEE802_11_Assoc_Response &other);
/**
* \brief Copy assignment operator
*/
IEEE802_11_Assoc_Response &operator= (const IEEE802_11_Assoc_Response &other);
/**
* \brief Getter for the Capabilities Information.
*
@@ -1458,6 +1511,7 @@ namespace Tins {
uint16_t aid;
};
void copy_fields(const IEEE802_11_Assoc_Response *other);
uint32_t write_fixed_parameters(uint8_t *buffer, uint32_t total_sz);
AssocRespBody _body;
@@ -1512,6 +1566,16 @@ namespace Tins {
*/
IEEE802_11_QoS_Data(const uint8_t *buffer, uint32_t total_sz);
/**
* \brief Copy constructor.
*/
IEEE802_11_QoS_Data(const IEEE802_11_QoS_Data &other);
/**
* \brief Copy assignment operator.
*/
IEEE802_11_QoS_Data &operator= (const IEEE802_11_QoS_Data &other);
/**
* \brief Getter for the qos_control field.
*
@@ -1533,13 +1597,12 @@ namespace Tins {
* \sa PDU::header_size()
*/
uint32_t header_size() const;
private:
uint16_t _qos_control;
void copy_fields(const IEEE802_11_QoS_Data *other);
uint32_t write_fixed_parameters(uint8_t *buffer, uint32_t total_sz);
uint16_t _qos_control;
};
}

View File

@@ -60,6 +60,7 @@ namespace Tins {
TCP,
UDP,
ICMP,
BOOTP,
DHCP,
EAPOL
};
@@ -214,6 +215,18 @@ namespace Tins {
*/
virtual PDU *clone_packet(const uint8_t *ptr, uint32_t total_sz) { return 0; }
protected:
/**
* \brief Copy consstructor.
*/
PDU(const PDU &other);
/**
* \brief Copy other PDU's inner PDU(if any).
* \param pdu The PDU from which to copy the inner PDU.
*/
void copy_inner_pdu(const PDU &pdu);
/** \brief Serializes this PDU and propagates this action to child PDUs.
*
* \param buffer The buffer in which to store this PDU's serialization.

View File

@@ -49,6 +49,16 @@ namespace Tins {
*/
SNAP(const uint8_t *buffer, uint32_t total_sz);
/**
* \brief Copy constructor.
*/
SNAP(const SNAP &other);
/**
* \brief Copy assignment operator.
*/
SNAP &operator= (const SNAP &other);
/**
* \brief Returns the SNAP frame's header length.
*
@@ -62,6 +72,13 @@ namespace Tins {
* \sa PDU::pdu_type
*/
PDUType pdu_type() const { return PDU::SNAP; }
/**
* \brief Clones this PDU.
*
* \sa PDU::clone_pdu
*/
PDU *clone_pdu() const;
private:
struct snaphdr {
uint8_t dsap;
@@ -74,6 +91,7 @@ namespace Tins {
uint16_t eth_type;
} __attribute__((__packed__));
void copy_fields(const SNAP *other);
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
snaphdr _snap;

View File

@@ -82,7 +82,7 @@ namespace Tins {
* \param olength The option's data length.
* \param odata The option's data(if any).
*/
TCPOption(uint8_t okind, uint8_t olength, uint8_t *odata) :
TCPOption(uint8_t okind = 0, uint8_t olength = 0, uint8_t *odata = 0) :
kind(okind), length(olength), data(odata) { }
/**
@@ -114,6 +114,16 @@ namespace Tins {
*/
TCP(const uint8_t *buffer, uint32_t total_sz);
/**
* \brief Copy constructor.
*/
TCP(const TCP &other);
/**
* \brief Copy assignment operator.
*/
TCP &operator= (const TCP &other);
/**
* \brief TCP destructor.
*
@@ -313,6 +323,12 @@ namespace Tins {
*/
PDUType pdu_type() const { return PDU::TCP; }
/**
* \brief Clones this PDU.
*
* \sa PDU::clone_pdu
*/
PDU *clone_pdu() const;
private:
struct tcphdr {
uint16_t sport;
@@ -351,6 +367,7 @@ namespace Tins {
static const uint16_t DEFAULT_WINDOW;
void copy_fields(const TCP *other);
/** \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.

View File

@@ -52,7 +52,17 @@ namespace Tins {
* \param total_sz The total size of the buffer.
*/
UDP(const uint8_t *buffer, uint32_t total_sz);
/**
* \brief Copy constructor.
*/
UDP(const UDP &other);
/**
* \brief Copy assignment operator.
*/
UDP &operator= (const UDP& other);
/**
* \brief Getter for the destination port.
* \return The datagram's destination port.
@@ -113,6 +123,13 @@ namespace Tins {
* \sa PDU::pdu_type
*/
PDUType pdu_type() const { return PDU::UDP; }
/**
* \brief Clones this PDU.
*
* \sa PDU::clone_pdu
*/
PDU *clone_pdu() const;
private:
struct udphdr {
uint16_t sport;
@@ -121,6 +138,7 @@ namespace Tins {
uint16_t check;
} __attribute__((packed));
void copy_fields(const UDP *other);
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
udphdr _udp;

View File

@@ -55,6 +55,16 @@ Tins::ARP::ARP(const uint8_t *buffer, uint32_t total_sz) : PDU(0x0608) {
inner_pdu(new RawPDU(buffer + sizeof(arphdr), total_sz));
}
Tins::ARP::ARP(const ARP &other) : PDU(other) {
copy_fields(&other);
}
Tins::ARP &Tins::ARP::operator= (const ARP &other) {
copy_fields(&other);
copy_inner_pdu(other);
return *this;
}
Tins::ARP::ARP(const arphdr *arp_ptr) : PDU(Utils::net_to_host_s(0x0806)) {
memcpy(&_arp, arp_ptr, sizeof(arphdr));
}
@@ -207,3 +217,13 @@ Tins::PDU* Tins::ARP::make_arp_reply(const string& iface,
EthernetII* eth = new EthernetII(iface, hw_tgt, hw_snd, arp);
return eth;
}
Tins::PDU *Tins::ARP::clone_pdu() const {
ARP *new_pdu = new ARP();
new_pdu->copy_fields(this);
return new_pdu;
}
void Tins::ARP::copy_fields(const ARP *other) {
std::memcpy(&_arp, &other->_arp, sizeof(_arp));
}

View File

@@ -24,6 +24,16 @@ Tins::BootP::BootP(const uint8_t *buffer, uint32_t total_sz, uint32_t vend_field
// Maybe RawPDU on what is left on the buffer?...
}
Tins::BootP::BootP(const BootP &other) : PDU(other) {
copy_bootp_fields(&other);
}
Tins::BootP &Tins::BootP::operator= (const BootP &other) {
copy_bootp_fields(&other);
copy_inner_pdu(other);
return *this;
}
Tins::BootP::~BootP() {
delete[] _vend;
}
@@ -100,3 +110,18 @@ void Tins::BootP::write_serialization(uint8_t *buffer, uint32_t total_sz, const
std::memcpy(buffer, &_bootp, sizeof(bootphdr));
std::memcpy(buffer + sizeof(bootphdr), _vend, _vend_size);
}
void Tins::BootP::copy_bootp_fields(const BootP *other) {
std::memcpy(&_bootp, &other->_bootp, sizeof(_bootp));
_vend_size = other->_vend_size;
if(_vend_size) {
_vend = new uint8_t[_vend_size];
std::memcpy(_vend, other->_vend, _vend_size);
}
}
Tins::PDU *Tins::BootP::clone_pdu() const {
BootP *new_pdu = new BootP();
new_pdu->copy_bootp_fields(this);
return new_pdu;
}

View File

@@ -63,6 +63,16 @@ Tins::DHCP::DHCP(const uint8_t *buffer, uint32_t total_sz) : BootP(buffer, total
}
}
Tins::DHCP::DHCP(const DHCP &other) : BootP(other) {
copy_fields(&other);
}
Tins::DHCP &Tins::DHCP::operator= (const DHCP &other) {
copy_fields(&other);
copy_inner_pdu(other);
return *this;
}
Tins::DHCP::~DHCP() {
while(_options.size()) {
delete[] _options.front().value;
@@ -71,8 +81,12 @@ Tins::DHCP::~DHCP() {
}
Tins::DHCP::DHCPOption::DHCPOption(uint8_t opt, uint8_t len, const uint8_t *val) : option(opt), length(len) {
value = new uint8_t[len];
std::memcpy(value, val, len);
if(len) {
value = new uint8_t[len];
std::memcpy(value, val, len);
}
else
value = 0;
}
bool Tins::DHCP::add_option(Options opt, uint8_t len, const uint8_t *val) {
@@ -149,7 +163,8 @@ void Tins::DHCP::write_serialization(uint8_t *buffer, uint32_t total_sz, const P
for(std::list<DHCPOption>::const_iterator it = _options.begin(); it != _options.end(); ++it) {
*(ptr++) = it->option;
*(ptr++) = it->length;
std::memcpy(ptr, it->value, it->length);
if(it->length)
std::memcpy(ptr, it->value, it->length);
ptr += it->length;
}
// End of options
@@ -160,3 +175,15 @@ void Tins::DHCP::write_serialization(uint8_t *buffer, uint32_t total_sz, const P
delete[] result;
}
void Tins::DHCP::copy_fields(const DHCP *other) {
BootP::copy_bootp_fields(other);
_size = other->_size;
for(std::list<DHCPOption>::const_iterator it = other->_options.begin(); it != other->_options.end(); ++it)
_options.push_back(DHCPOption(it->option, it->length, it->value));
}
Tins::PDU *Tins::DHCP::clone_pdu() const {
DHCP *new_pdu = new DHCP();
new_pdu->copy_fields(this);
return new_pdu;
}

View File

@@ -39,6 +39,10 @@ Tins::EAPOL::EAPOL(const uint8_t *buffer, uint32_t total_sz) : PDU(0xff) {
std::memcpy(&_header, buffer, sizeof(_header));
}
Tins::EAPOL::EAPOL(const EAPOL &other) : PDU(other) {
copy_eapol_fields(&other);
}
Tins::EAPOL *Tins::EAPOL::from_bytes(const uint8_t *buffer, uint32_t total_sz) {
if(total_sz < sizeof(eapolhdr))
throw std::runtime_error("Not enough size for an EAPOL header in the buffer.");
@@ -80,6 +84,11 @@ void Tins::EAPOL::write_serialization(uint8_t *buffer, uint32_t total_sz, const
write_body(buffer + sizeof(_header), total_sz - sizeof(_header));
}
void Tins::EAPOL::copy_eapol_fields(const EAPOL *other) {
std::memcpy(&_header, &other->_header, sizeof(_header));
}
/* RC4EAPOL */
Tins::RC4EAPOL::RC4EAPOL() : EAPOL(0x03, RC4), _key(0), _key_size(0) {
@@ -103,6 +112,16 @@ Tins::RC4EAPOL::RC4EAPOL(const uint8_t *buffer, uint32_t total_sz) : EAPOL(buffe
_key = 0;
}
Tins::RC4EAPOL::RC4EAPOL(const RC4EAPOL &other) : EAPOL(other) {
copy_fields(&other);
}
Tins::RC4EAPOL &Tins::RC4EAPOL::operator= (const RC4EAPOL &other) {
copy_fields(&other);
copy_inner_pdu(other);
return *this;
}
Tins::RC4EAPOL::~RC4EAPOL() {
delete[] _key;
}
@@ -153,6 +172,23 @@ void Tins::RC4EAPOL::write_body(uint8_t *buffer, uint32_t total_sz) {
std::memcpy(buffer, _key, _key_size);
}
Tins::PDU *Tins::RC4EAPOL::clone_pdu() const {
RC4EAPOL *new_pdu = new RC4EAPOL();
new_pdu->copy_fields(this);
return new_pdu;
}
void Tins::RC4EAPOL::copy_fields(const RC4EAPOL *other) {
copy_eapol_fields(other);
std::memcpy(&_header, &other->_header, sizeof(_header));
_key_size = other->_key_size;
if(_key_size) {
_key = new uint8_t[_key_size];
std::memcpy(_key, other->_key, _key_size);
}
else
_key = 0;
}
/* RSNEAPOL */
@@ -178,6 +214,16 @@ Tins::RSNEAPOL::RSNEAPOL(const uint8_t *buffer, uint32_t total_sz) : EAPOL(0x03,
_key = 0;
}
Tins::RSNEAPOL::RSNEAPOL(const RSNEAPOL &other) : EAPOL(other) {
copy_fields(&other);
}
Tins::RSNEAPOL &Tins::RSNEAPOL::operator= (const RSNEAPOL &other) {
copy_fields(&other);
copy_inner_pdu(other);
return *this;
}
Tins::RSNEAPOL::~RSNEAPOL() {
delete[] _key;
}
@@ -248,3 +294,20 @@ void Tins::RSNEAPOL::write_body(uint8_t *buffer, uint32_t total_sz) {
}
}
void Tins::RSNEAPOL::copy_fields(const RSNEAPOL *other) {
copy_eapol_fields(other);
std::memcpy(&_header, &other->_header, sizeof(_header));
_key_size = other->_key_size;
if(_key_size) {
_key = new uint8_t[_key_size];
std::memcpy(_key, other->_key, _key_size);
}
else
_key = 0;
}
Tins::PDU *Tins::RSNEAPOL::clone_pdu() const {
RSNEAPOL *new_pdu = new RSNEAPOL();
new_pdu->copy_fields(this);
return new_pdu;
}

View File

@@ -73,12 +73,13 @@ Tins::EthernetII::EthernetII(const uint8_t *buffer, uint32_t total_sz) : PDU(ETH
inner_pdu(next);
}
Tins::EthernetII::EthernetII(const EthernetII &other) : PDU(ETHERTYPE_IP) {
*this = other;
Tins::EthernetII::EthernetII(const EthernetII &other) : PDU(other) {
copy_fields(&other);
}
Tins::EthernetII &Tins::EthernetII::operator= (const EthernetII &other) {
copy_fields(&other);
copy_inner_pdu(other);
return *this;
}

View File

@@ -48,6 +48,16 @@ Tins::ICMP::ICMP(Flags flag) : PDU(IPPROTO_ICMP) {
};
}
Tins::ICMP::ICMP(const ICMP &other) : PDU(other) {
copy_fields(&other);
}
Tins::ICMP &Tins::ICMP::operator= (const ICMP &other) {
copy_fields(&other);
copy_inner_pdu(other);
return *this;
}
Tins::ICMP::ICMP(const uint8_t *buffer, uint32_t total_sz) : PDU(IPPROTO_ICMP) {
if(total_sz < sizeof(icmphdr))
throw std::runtime_error("Not enough size for an ICMP header in the buffer.");
@@ -199,3 +209,13 @@ Tins::PDU *Tins::ICMP::clone_packet(const uint8_t *ptr, uint32_t total_sz) {
cloned->inner_pdu(child);
return cloned;
}
void Tins::ICMP::copy_fields(const ICMP *other) {
std::memcpy(&_icmp, &other->_icmp, sizeof(_icmp));
}
Tins::PDU *Tins::ICMP::clone_pdu() const {
ICMP *new_pdu = new ICMP();
new_pdu->copy_fields(this);
return new_pdu;
}

View File

@@ -84,6 +84,10 @@ Tins::IEEE802_11::IEEE802_11(const uint8_t *buffer, uint32_t total_sz) : PDU(ETH
}
}
Tins::IEEE802_11::IEEE802_11(const IEEE802_11 &other) : PDU(other) {
copy_80211_fields(&other);
}
Tins::IEEE802_11::~IEEE802_11() {
while(_options.size()) {
delete[] _options.front().value;
@@ -91,6 +95,12 @@ Tins::IEEE802_11::~IEEE802_11() {
}
}
Tins::IEEE802_11 &Tins::IEEE802_11::operator= (const IEEE802_11 &other) {
copy_80211_fields(&other);
copy_inner_pdu(other);
return *this;
}
void Tins::IEEE802_11::parse_tagged_parameters(const uint8_t *buffer, uint32_t total_sz) {
uint8_t opcode, length;
while(total_sz >= 2) {
@@ -261,6 +271,14 @@ Tins::PDU *Tins::IEEE802_11::from_bytes(const uint8_t *buffer, uint32_t total_sz
return ret;
}
void Tins::IEEE802_11::copy_80211_fields(const IEEE802_11 *other) {
std::memcpy(&_header, &other->_header, sizeof(_header));
std::memcpy(_addr4, other->_addr4, sizeof(_header));
_iface_index = other->_iface_index;
_options_size = other->_options_size;
for(std::list<IEEE802_11_Option>::const_iterator it = other->_options.begin(); it != other->_options.end(); ++it)
_options.push_back(IEEE802_11_Option(it->option, it->length, it->value));
}
/*
* ManagementFrame
@@ -280,6 +298,10 @@ Tins::ManagementFrame::ManagementFrame(const std::string &iface,
this->type(IEEE802_11::MANAGEMENT);
}
Tins::ManagementFrame::ManagementFrame(const ManagementFrame &other) : IEEE802_11(other) {
}
void Tins::ManagementFrame::ssid(const std::string &new_ssid) {
add_tagged_option(IEEE802_11::SSID, new_ssid.size(), (const uint8_t*)new_ssid.c_str());
}
@@ -392,6 +414,21 @@ Tins::IEEE802_11_Beacon::IEEE802_11_Beacon(const uint8_t *buffer, uint32_t total
parse_tagged_parameters(buffer, total_sz);
}
Tins::IEEE802_11_Beacon::IEEE802_11_Beacon(const IEEE802_11_Beacon &other) : ManagementFrame(other) {
}
Tins::IEEE802_11_Beacon &Tins::IEEE802_11_Beacon::operator= (const IEEE802_11_Beacon &other) {
copy_fields(&other);
copy_inner_pdu(other);
return *this;
}
void Tins::IEEE802_11_Beacon::copy_fields(const IEEE802_11_Beacon *other) {
copy_80211_fields(other);
std::memcpy(&_body, &other->_body, sizeof(_body));
}
void Tins::IEEE802_11_Beacon::timestamp(uint64_t new_timestamp) {
this->_body.timestamp = new_timestamp;
}
@@ -473,6 +510,8 @@ uint32_t Tins::IEEE802_11_Beacon::write_fixed_parameters(uint8_t *buffer, uint32
return sz;
}
/* 802.11 diassoc */
Tins::IEEE802_11_Disassoc::IEEE802_11_Disassoc() : ManagementFrame() {
this->subtype(IEEE802_11::DISASSOC);
memset(&_body, 0, sizeof(_body));
@@ -485,6 +524,21 @@ Tins::IEEE802_11_Disassoc::IEEE802_11_Disassoc(const std::string& iface,
memset(&_body, 0, sizeof(_body));
}
Tins::IEEE802_11_Disassoc::IEEE802_11_Disassoc(const IEEE802_11_Disassoc &other) : ManagementFrame(other) {
copy_fields(&other);
}
Tins::IEEE802_11_Disassoc &Tins::IEEE802_11_Disassoc::operator= (const IEEE802_11_Disassoc &other) {
copy_inner_pdu(other);
copy_fields(&other);
return *this;
}
void Tins::IEEE802_11_Disassoc::copy_fields(const IEEE802_11_Disassoc *other) {
copy_80211_fields(other);
std::memcpy(&_body, &other->_body, sizeof(_body));
}
void Tins::IEEE802_11_Disassoc::reason_code(uint16_t new_reason_code) {
this->_body.reason_code = new_reason_code;
}
@@ -561,6 +615,8 @@ Tins::RSNInformation Tins::RSNInformation::wpa2_psk() {
return info;
}
/* Assoc request. */
Tins::IEEE802_11_Assoc_Request::IEEE802_11_Assoc_Request() : ManagementFrame() {
this->subtype(IEEE802_11::ASSOC_REQ);
memset(&_body, 0, sizeof(_body));
@@ -584,6 +640,21 @@ Tins::IEEE802_11_Assoc_Request::IEEE802_11_Assoc_Request(const uint8_t *buffer,
parse_tagged_parameters(buffer, total_sz);
}
Tins::IEEE802_11_Assoc_Request::IEEE802_11_Assoc_Request(const IEEE802_11_Assoc_Request &other) : ManagementFrame(other) {
copy_fields(&other);
}
Tins::IEEE802_11_Assoc_Request &Tins::IEEE802_11_Assoc_Request::operator= (const IEEE802_11_Assoc_Request &other) {
copy_inner_pdu(other);
copy_fields(&other);
return *this;
}
void Tins::IEEE802_11_Assoc_Request::copy_fields(const IEEE802_11_Assoc_Request *other) {
copy_80211_fields(other);
std::memcpy(&_body, &other->_body, sizeof(_body));
}
void Tins::IEEE802_11_Assoc_Request::listen_interval(uint16_t new_listen_interval) {
this->_body.listen_interval = new_listen_interval;
}
@@ -627,6 +698,8 @@ uint32_t Tins::IEEE802_11_Assoc_Request::write_fixed_parameters(uint8_t *buffer,
return sz;
}
/* Assoc response. */
Tins::IEEE802_11_Assoc_Response::IEEE802_11_Assoc_Response() : ManagementFrame() {
this->subtype(IEEE802_11::ASSOC_RESP);
memset(&_body, 0, sizeof(_body));
@@ -650,6 +723,21 @@ Tins::IEEE802_11_Assoc_Response::IEEE802_11_Assoc_Response(const uint8_t *buffer
parse_tagged_parameters(buffer, total_sz);
}
Tins::IEEE802_11_Assoc_Response::IEEE802_11_Assoc_Response(const IEEE802_11_Assoc_Response &other) : ManagementFrame(other) {
copy_fields(&other);
}
Tins::IEEE802_11_Assoc_Response &Tins::IEEE802_11_Assoc_Response::operator= (const IEEE802_11_Assoc_Response &other) {
copy_inner_pdu(other);
copy_fields(&other);
return *this;
}
void Tins::IEEE802_11_Assoc_Response::copy_fields(const IEEE802_11_Assoc_Response *other) {
copy_80211_fields(other);
std::memcpy(&_body, &other->_body, sizeof(_body));
}
void Tins::IEEE802_11_Assoc_Response::status_code(uint16_t new_status_code) {
this->_body.status_code = new_status_code;
}
@@ -681,6 +769,8 @@ uint32_t Tins::IEEE802_11_Assoc_Response::write_fixed_parameters(uint8_t *buffer
return sz;
}
/* QoS data. */
Tins::IEEE802_11_QoS_Data::IEEE802_11_QoS_Data(const uint8_t* dst_hw_addr, const uint8_t* src_hw_addr, PDU* child) : IEEE802_11(dst_hw_addr, src_hw_addr, child) {
this->type(IEEE802_11::DATA);
this->subtype(IEEE802_11::QOS_DATA_DATA);
@@ -710,6 +800,21 @@ Tins::IEEE802_11_QoS_Data::IEEE802_11_QoS_Data(const uint8_t *buffer, uint32_t t
inner_pdu(new Tins::SNAP(buffer, total_sz));
}
Tins::IEEE802_11_QoS_Data::IEEE802_11_QoS_Data(const IEEE802_11_QoS_Data &other) : IEEE802_11(other) {
copy_fields(&other);
}
Tins::IEEE802_11_QoS_Data &Tins::IEEE802_11_QoS_Data::operator= (const IEEE802_11_QoS_Data &other) {
copy_inner_pdu(other);
copy_fields(&other);
return *this;
}
void Tins::IEEE802_11_QoS_Data::copy_fields(const IEEE802_11_QoS_Data *other) {
copy_80211_fields(other);
_qos_control = other->_qos_control;
}
void Tins::IEEE802_11_QoS_Data::qos_control(uint16_t new_qos_control) {
this->_qos_control = new_qos_control;
}

View File

@@ -46,8 +46,8 @@ Tins::IP::IP(const string &ip_dst, const string &ip_src, PDU *child) : PDU(IPPRO
}
Tins::IP::IP(const IP &other) : PDU(IPPROTO_IP) {
*this = other;
Tins::IP::IP(const IP &other) : PDU(other) {
copy_fields(&other);
}
Tins::IP::IP() : PDU(IPPROTO_IP) {
@@ -56,8 +56,7 @@ Tins::IP::IP() : PDU(IPPROTO_IP) {
Tins::IP &Tins::IP::operator= (const IP &other) {
copy_fields(&other);
if(other.inner_pdu())
inner_pdu(other.inner_pdu()->clone_packet());
copy_inner_pdu(other);
return *this;
}
@@ -354,9 +353,13 @@ void Tins::IP::copy_fields(const IP *other) {
new_opt.optional_data = new uint8_t[it->optional_data_size];
memcpy(new_opt.optional_data, it->optional_data, it->optional_data_size);
}
else
new_opt.optional_data = 0;
new_opt.optional_data_size = it->optional_data_size;
_ip_options.push_back(new_opt);
}
_options_size = other->_options_size;
_padded_options_size = other->_padded_options_size;
}
Tins::PDU *Tins::IP::clone_pdu() const {

View File

@@ -29,10 +29,20 @@ Tins::PDU::PDU(uint32_t flag, PDU *next_pdu) : _flag(flag), _inner_pdu(next_pdu)
}
Tins::PDU::PDU(const PDU &other) : _inner_pdu(0) {
_flag = other.flag();
copy_inner_pdu(other);
}
Tins::PDU::~PDU() {
delete _inner_pdu;
}
void Tins::PDU::copy_inner_pdu(const PDU &pdu) {
if(pdu.inner_pdu())
inner_pdu(pdu.inner_pdu()->clone_pdu());
}
uint32_t Tins::PDU::size() const {
uint32_t sz = header_size() + trailer_size();
const PDU *ptr(_inner_pdu);

View File

@@ -57,6 +57,16 @@ Tins::SNAP::SNAP(const uint8_t *buffer, uint32_t total_sz) : PDU(0xff) {
};
}
Tins::SNAP::SNAP(const SNAP &other) : PDU(other) {
copy_fields(&other);
}
Tins::SNAP &Tins::SNAP::operator= (const SNAP &other) {
copy_fields(&other);
copy_inner_pdu(other);
return *this;
}
uint32_t Tins::SNAP::header_size() const {
return sizeof(_snap);
}
@@ -83,3 +93,12 @@ void Tins::SNAP::write_serialization(uint8_t *buffer, uint32_t total_sz, const P
std::memcpy(buffer, &_snap, sizeof(_snap));
}
void Tins::SNAP::copy_fields(const SNAP *other) {
std::memcpy(&_snap, &other->_snap, sizeof(_snap));
}
Tins::PDU *Tins::SNAP::clone_pdu() const {
SNAP *new_pdu = new SNAP();
new_pdu->copy_fields(this);
return new_pdu;
}

View File

@@ -42,6 +42,16 @@ Tins::TCP::TCP(uint16_t dport, uint16_t sport) : PDU(IPPROTO_TCP), _options_size
this->check(0);
}
Tins::TCP::TCP(const TCP &other) : PDU(other) {
copy_fields(&other);
}
Tins::TCP &Tins::TCP::operator= (const TCP &other) {
copy_fields(&other);
copy_inner_pdu(other);
return *this;
}
Tins::TCP::TCP(const uint8_t *buffer, uint32_t total_sz) : PDU(IPPROTO_TCP) {
if(total_sz < sizeof(tcphdr))
throw std::runtime_error("Not enough size for an TCP header in the buffer.");
@@ -253,3 +263,24 @@ uint8_t *Tins::TCP::TCPOption::write(uint8_t *buffer) {
return buffer + length + (sizeof(uint8_t) << 1);
}
}
void Tins::TCP::copy_fields(const TCP *other) {
std::memcpy(&_tcp, &other->_tcp, sizeof(_tcp));
for(std::list<TCPOption>::const_iterator it = other->_options.begin(); it != other->_options.end(); ++it) {
TCPOption opt(it->kind, it->length);
if(it->data) {
opt.data = new uint8_t[it->length];
std::memcpy(opt.data, it->data, it->length);
}
_options.push_back(opt);
}
_options_size = other->_options_size;
_total_options_size = other->_total_options_size;
}
Tins::PDU *Tins::TCP::clone_pdu() const {
TCP *new_pdu = new TCP();
new_pdu->copy_fields(this);
return new_pdu;
}

View File

@@ -46,6 +46,16 @@ Tins::UDP::UDP(const uint8_t *buffer, uint32_t total_sz) : PDU(IPPROTO_UDP) {
inner_pdu(new RawPDU(buffer + sizeof(udphdr), total_sz));
}
Tins::UDP::UDP(const UDP &other) : PDU(other) {
copy_fields(&other);
}
Tins::UDP &Tins::UDP::operator= (const UDP& other) {
copy_fields(&other);
copy_inner_pdu(other);
return *this;
}
void Tins::UDP::payload(uint8_t *new_payload, uint32_t new_payload_size) {
inner_pdu(new RawPDU(new_payload, new_payload_size));
}
@@ -82,3 +92,12 @@ void Tins::UDP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PD
_udp.check = 0;
}
void Tins::UDP::copy_fields(const UDP *other) {
std::memcpy(&_udp, &other->_udp, sizeof(_udp));
}
Tins::PDU *Tins::UDP::clone_pdu() const {
UDP *new_pdu = new UDP();
new_pdu->copy_fields(this);
return new_pdu;
}