1
0
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:
Santiago Alessandri
2011-08-15 19:14:31 -03:00
parent 835229f104
commit 6e801011c2
13 changed files with 235 additions and 175 deletions

View File

@@ -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;
};
};

View File

@@ -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

View File

@@ -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;

View File

@@ -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);

View File

@@ -47,6 +47,7 @@ namespace Tins {
enum SocketType {
ETHER_SOCKET,
IP_SOCKET,
ARP_SOCKET,
ICMP_SOCKET,
SOCKETS_END
};

View File

@@ -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:

View File

@@ -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;
};

View File

@@ -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;

View File

@@ -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;
};
};

View File

@@ -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);
}

View File

@@ -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));

View File

@@ -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);

View File

@@ -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);