diff --git a/include/arp.h b/include/arp.h index 941b8ad..b265765 100644 --- a/include/arp.h +++ b/include/arp.h @@ -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; }; }; diff --git a/include/ethernet.h b/include/ethernetII.h similarity index 93% rename from include/ethernet.h rename to include/ethernetII.h index 2eaa986..6762044 100644 --- a/include/ethernet.h +++ b/include/ethernetII.h @@ -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 diff --git a/include/icmp.h b/include/icmp.h index c612f5c..0421735 100644 --- a/include/icmp.h +++ b/include/icmp.h @@ -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; diff --git a/include/ip.h b/include/ip.h index 069bb3b..fdb0dc6 100644 --- a/include/ip.h +++ b/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); diff --git a/include/packetsender.h b/include/packetsender.h index 45d52cb..8eed00a 100644 --- a/include/packetsender.h +++ b/include/packetsender.h @@ -47,6 +47,7 @@ namespace Tins { enum SocketType { ETHER_SOCKET, IP_SOCKET, + ARP_SOCKET, ICMP_SOCKET, SOCKETS_END }; diff --git a/include/pdu.h b/include/pdu.h index b9dd16f..6c1ac52 100644 --- a/include/pdu.h +++ b/include/pdu.h @@ -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: diff --git a/include/rawpdu.h b/include/rawpdu.h index 47796fb..ed02045 100644 --- a/include/rawpdu.h +++ b/include/rawpdu.h @@ -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; }; diff --git a/include/tcp.h b/include/tcp.h index c9e331a..ee13fdc 100644 --- a/include/tcp.h +++ b/include/tcp.h @@ -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 _options; uint32_t _options_size, _total_options_size; diff --git a/include/udp.h b/include/udp.h index 74c0709..b0e59b2 100644 --- a/include/udp.h +++ b/include/udp.h @@ -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; }; }; diff --git a/src/arp.cpp b/src/arp.cpp index ab33c38..945d0ee 100644 --- a/src/arp.cpp +++ b/src/arp.cpp @@ -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); -} - diff --git a/src/ethernet.cpp b/src/ethernetII.cpp similarity index 59% rename from src/ethernet.cpp rename to src/ethernetII.cpp index 006edbe..49ed40b 100644 --- a/src/ethernet.cpp +++ b/src/ethernetII.cpp @@ -28,46 +28,50 @@ #include #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 + +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)); diff --git a/src/tcp.cpp b/src/tcp.cpp index a4d508a..e2e6d85 100644 --- a/src/tcp.cpp +++ b/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(parent); + + const Tins::IP *ip_packet = dynamic_cast(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); diff --git a/src/udp.cpp b/src/udp.cpp index 8df7962..196cd5d 100644 --- a/src/udp.cpp +++ b/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(parent); + const Tins::IP *ip_packet = dynamic_cast(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);