From e587d18796a0ad4d9fa9e8af4d45f8e62320f76b Mon Sep 17 00:00:00 2001 From: Matias Fontanini Date: Tue, 16 Aug 2011 20:53:55 -0300 Subject: [PATCH] Documented many header files. Done some minor code refactoring over PDU::clone_packet. --- include/arp.h | 54 ++++++++++++++++++++++++++------------------ include/ethernetII.h | 4 ++++ include/icmp.h | 12 +++++++--- include/ip.h | 6 ++++- include/pdu.h | 36 +++++++++++++++++++++++++++-- include/rawpdu.h | 4 ++++ include/tcp.h | 4 ++++ include/udp.h | 6 ++++- src/arp.cpp | 26 ++++++++------------- src/ethernetII.cpp | 16 +++---------- src/icmp.cpp | 10 ++------ src/pdu.cpp | 13 +++++++++++ 12 files changed, 125 insertions(+), 66 deletions(-) diff --git a/include/arp.h b/include/arp.h index 396267a..7b12be6 100644 --- a/include/arp.h +++ b/include/arp.h @@ -39,12 +39,15 @@ namespace Tins { * \brief Enum which indicates the type of ARP packet. */ enum Flags { - REQUEST = 0x0100, - REPLY = 0x0200 + REQUEST = 0x0001, + REPLY = 0x0002 }; /** * \brief Default constructor for ARP PDU objects. + * + * ARP requests and replies can be constructed easily using + * ARP::make_arp_request/reply static functions. */ ARP(); @@ -112,6 +115,11 @@ namespace Tins { */ inline uint16_t opcode() { return this->_arp.ar_op; } + /** \brief Getter for the header size. + * \return Returns the ARP header size. + * \sa PDU::header_size + */ + uint32_t header_size() const; /* Setters */ /** @@ -176,27 +184,11 @@ namespace Tins { * \param new_opcode Flag enum value of the ARP opcode to set. */ void opcode(Flags new_opcode); - - /** \brief Check wether ptr points to a valid response for this PDU. - * - * \sa PDU::matches_response - * \param ptr The pointer to the buffer. - * \param total_sz The size of the buffer. + + /** + * \brief Getter for the PDU's type. + * \sa PDU::pdu_type */ - bool matches_response(uint8_t *ptr, uint32_t total_sz); - - uint32_t header_size() const; - - /** \brief Clones this pdu, filling the corresponding header with data - * extracted from a buffer. - * - * \param ptr The pointer to the from from which the data will be extracted. - * \param total_sz The size of the buffer. - * \return The cloned PDU. - * \sa PDU::clone_packet - */ - PDU *clone_packet(uint8_t *ptr, uint32_t total_sz); - PDUType pdu_type() const { return PDU::ARP; } /** @@ -281,6 +273,24 @@ namespace Tins { * \param hw_snd uint8_t array of 6 bytes containing the sender's hardware address. */ void set_arp_reply(const std::string& ip_tgt, const std::string& ip_snd, const uint8_t* hw_tgt, const uint8_t* hw_snd); + + /** \brief Check wether ptr points to a valid response for this PDU. + * + * \sa PDU::matches_response + * \param ptr The pointer to the buffer. + * \param total_sz The size of the buffer. + */ + bool matches_response(uint8_t *ptr, uint32_t total_sz); + + /** \brief Clones this pdu, filling the corresponding header with data + * extracted from a buffer. + * + * \param ptr The pointer to the from from which the data will be extracted. + * \param total_sz The size of the buffer. + * \return The cloned PDU. + * \sa PDU::clone_packet + */ + PDU *clone_packet(uint8_t *ptr, uint32_t total_sz); private: struct arphdr { diff --git a/include/ethernetII.h b/include/ethernetII.h index 6d649c0..0d1dc99 100644 --- a/include/ethernetII.h +++ b/include/ethernetII.h @@ -147,6 +147,10 @@ namespace Tins { */ PDU *recv_response(PacketSender *sender); + /** + * \brief Getter for the PDU's type. + * \sa PDU::pdu_type + */ PDUType pdu_type() const { return PDU::ETHERNET_II; } /** \brief Clones this pdu, filling the corresponding header with data diff --git a/include/icmp.h b/include/icmp.h index c4792c0..90971d2 100644 --- a/include/icmp.h +++ b/include/icmp.h @@ -150,11 +150,13 @@ namespace Tins { */ uint8_t code() const { return _icmp.code; } - /** \brief Returns the echo id. + /** \brief Getter for the echo id. + * \return Returns the echo id. */ uint16_t id() const { return _icmp.un.echo.id; } - /** \brief Returns the echo sequence number. + /** \brief Getter for the echo sequence number. + * \return Returns the echo sequence number. */ uint16_t sequence() const { return _icmp.un.echo.sequence; } @@ -166,7 +168,11 @@ namespace Tins { uint32_t header_size() const; bool matches_response(uint8_t *ptr, uint32_t total_sz); - + + /** + * \brief Getter for the PDU's type. + * \sa PDU::pdu_type + */ PDUType pdu_type() const { return PDU::ICMP; } PDU *clone_packet(uint8_t *ptr, uint32_t total_sz); diff --git a/include/ip.h b/include/ip.h index fdb0dc6..fd18dc2 100644 --- a/include/ip.h +++ b/include/ip.h @@ -123,7 +123,11 @@ namespace Tins { bool matches_response(uint8_t *ptr, uint32_t total_sz); PDU *recv_response(PacketSender *sender); - + + /** + * \brief Getter for the PDU's type. + * \sa PDU::pdu_type + */ PDUType pdu_type() const { return PDU::IP; } PDU *clone_packet(uint8_t *ptr, uint32_t total_sz); diff --git a/include/pdu.h b/include/pdu.h index 829f5bd..6f92daa 100644 --- a/include/pdu.h +++ b/include/pdu.h @@ -157,10 +157,24 @@ namespace Tins { */ virtual PDU *clone_packet(uint8_t *ptr, uint32_t total_sz) { return 0; } protected: - /* Serialize this PDU storing the result in buffer. */ + /** \brief Serializes this PDU and propagates this action to child PDUs. + * + * \param buffer The buffer in which to store this PDU's serialization. + * \param total_sz The total size of the buffer. + * \param parent The parent PDU. Will be 0 if there's the parent does not exist. + */ void serialize(uint8_t *buffer, uint32_t total_sz, const PDU *parent); + + /** \brief Clones the inner pdu(if any). + * + * This method clones the inner pdu using data from a buffer. + * \param ptr The pointer from which the child PDU must be cloned. + * \param total_sz The total size of the buffer. + * \return Returns the cloned PDU. Will be 0 if cloning failed. + */ + PDU *clone_inner_pdu(uint8_t *ptr, uint32_t total_sz); - /** \brief Serialices this TCP PDU. + /** \brief Serializes this TCP PDU. * * Each PDU must override this method and implement it's own * serialization. @@ -170,7 +184,25 @@ namespace Tins { */ virtual void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) = 0; + /** \brief Does the 16 bits sum of all 2 bytes elements between start and end. + * + * This is the checksum used by IP, UDP and TCP. If there's and odd number of + * bytes, the last one is padded and added to the checksum. The checksum is performed + * using network endiannes. + * \param start The pointer to the start of the buffer. + * \param end The pointer to the end of the buffer(excluding the last element). + * \return Returns the checksum between start and end(non inclusive). + */ static uint32_t do_checksum(uint8_t *start, uint8_t *end); + + /** \brief Performs the pseudo header checksum used in TCP and UDP PDUs. + * + * \param source_ip The source ip address. + * \param dest_ip The destination ip address. + * \param len The length to be included in the pseudo header. + * \param flag The flag to use in the protocol field of the pseudo header. + * \return The pseudo header checksum. + */ static uint32_t pseudoheader_checksum(uint32_t source_ip, uint32_t dest_ip, uint32_t len, uint32_t flag); private: uint32_t _flag; diff --git a/include/rawpdu.h b/include/rawpdu.h index ed02045..f8c2308 100644 --- a/include/rawpdu.h +++ b/include/rawpdu.h @@ -50,6 +50,10 @@ namespace Tins { */ uint32_t header_size() const; + /** + * \brief Getter for the PDU's type. + * \sa PDU::pdu_type + */ PDUType pdu_type() const { return PDU::RAW; } private: diff --git a/include/tcp.h b/include/tcp.h index ee13fdc..d2d5d6d 100644 --- a/include/tcp.h +++ b/include/tcp.h @@ -189,6 +189,10 @@ namespace Tins { */ uint32_t header_size() const; + /** + * \brief Getter for the PDU's type. + * \sa PDU::pdu_type + */ PDUType pdu_type() const { return PDU::TCP; } private: diff --git a/include/udp.h b/include/udp.h index b0e59b2..d4de486 100644 --- a/include/udp.h +++ b/include/udp.h @@ -82,7 +82,11 @@ namespace Tins { * payload and options size. \sa PDU::header_size */ uint32_t header_size() const; - + + /** + * \brief Getter for the PDU's type. + * \sa PDU::pdu_type + */ PDUType pdu_type() const { return PDU::UDP; } private: diff --git a/src/arp.cpp b/src/arp.cpp index a54839e..8f9aa01 100644 --- a/src/arp.cpp +++ b/src/arp.cpp @@ -52,7 +52,7 @@ Tins::PDU* Tins::ARP::make_arp_request(const std::string& iface, if (hw_snd) { memcpy(arp->_arp.ar_sha, hw_snd, 6); } - arp->_arp.ar_op = Tins::ARP::REQUEST; + arp->_arp.ar_op = Utils::net_to_host_s(REQUEST); /* Create the EthernetII PDU with the ARP PDU as its inner PDU */ EthernetII* eth = new EthernetII(iface, Tins::EthernetII::BROADCAST, hw_snd, arp); @@ -82,7 +82,7 @@ Tins::PDU* Tins::ARP::make_arp_reply(const string& iface, arp->_arp.ar_sip = sender; memcpy(arp->_arp.ar_sha, hw_snd, 6); memcpy(arp->_arp.ar_tha, hw_tgt, 6); - arp->_arp.ar_op = Tins::ARP::REPLY; + arp->_arp.ar_op = Utils::net_to_host_s(REPLY); /* Create the EthernetII PDU with the ARP PDU as its inner PDU */ EthernetII* eth = new EthernetII(iface, hw_tgt, hw_snd, arp); @@ -91,13 +91,13 @@ Tins::PDU* Tins::ARP::make_arp_reply(const string& iface, Tins::ARP::ARP() : PDU(0x0608) { std::memset(&_arp, 0, sizeof(arphdr)); - _arp.ar_hrd = 0x0100; - _arp.ar_pro = 0x0008; + _arp.ar_hrd = Utils::net_to_host_s(0x0001); + _arp.ar_pro = Utils::net_to_host_s(0x0800); _arp.ar_hln = 6; _arp.ar_pln = 4; } -Tins::ARP::ARP(arphdr *arp_ptr) : PDU(0x0608) { +Tins::ARP::ARP(arphdr *arp_ptr) : PDU(Utils::net_to_host_s(0x0806)) { memcpy(&_arp, arp_ptr, sizeof(arphdr)); } @@ -140,10 +140,9 @@ void Tins::ARP::opcode(Flags new_opcode) { void Tins::ARP::set_arp_request(const std::string& ip_tgt, const std::string& ip_snd, const uint8_t* hw_snd) { this->_arp.ar_tip = Utils::resolve_ip(ip_tgt); this->_arp.ar_sip = Utils::resolve_ip(ip_snd); - if (hw_snd) { + if (hw_snd) memcpy(this->_arp.ar_sha, hw_snd, 6); - } - this->_arp.ar_op = REQUEST; + this->_arp.ar_op = Utils::net_to_host_s(REQUEST); } void Tins::ARP::set_arp_reply(const std::string& ip_tgt, @@ -155,7 +154,7 @@ void Tins::ARP::set_arp_reply(const std::string& ip_tgt, this->_arp.ar_sip = Utils::resolve_ip(ip_snd); memcpy(this->_arp.ar_tha, hw_tgt, 6); memcpy(this->_arp.ar_sha, hw_snd, 6); - this->_arp.ar_op = REPLY; + this->_arp.ar_op = Utils::net_to_host_s(REPLY); } @@ -181,13 +180,8 @@ Tins::PDU *Tins::ARP::clone_packet(uint8_t *ptr, uint32_t total_sz) { arphdr *arp_ptr = (arphdr*)ptr; PDU *child = 0, *cloned; if(total_sz > sizeof(arphdr)) { - if(inner_pdu()) { - child = inner_pdu()->clone_packet(ptr + sizeof(arphdr), total_sz - sizeof(arphdr)); - if(!child) - return 0; - } - else - child = new RawPDU(ptr + sizeof(arphdr), total_sz - sizeof(arphdr)); + if((child = PDU::clone_inner_pdu(ptr + sizeof(arphdr), total_sz - sizeof(arphdr))) == 0) + return 0; } cloned = new ARP(arp_ptr); cloned->inner_pdu(child); diff --git a/src/ethernetII.cpp b/src/ethernetII.cpp index ed18439..f5d954b 100644 --- a/src/ethernetII.cpp +++ b/src/ethernetII.cpp @@ -108,9 +108,8 @@ bool Tins::EthernetII::matches_response(uint8_t *ptr, uint32_t total_sz) { 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); - + /* Inner type defaults to IP */ - if ((this->_eth.payload_type == 0) && this->inner_pdu()) { uint16_t type = ETHERTYPE_IP; switch (this->inner_pdu()->pdu_type()) { @@ -125,15 +124,11 @@ void Tins::EthernetII::write_serialization(uint8_t *buffer, uint32_t total_sz, c } this->_eth.payload_type = Utils::net_to_host_s(type); } - - memcpy(buffer, &this->_eth, sizeof(ethhdr)); - } Tins::PDU *Tins::EthernetII::recv_response(PacketSender *sender) { struct sockaddr_ll addr; - memset(&addr, 0, sizeof(struct sockaddr_ll)); addr.sll_family = Utils::net_to_host_s(PF_PACKET); @@ -151,13 +146,8 @@ Tins::PDU *Tins::EthernetII::clone_packet(uint8_t *ptr, uint32_t total_sz) { ethhdr *eth_ptr = (ethhdr*)ptr; PDU *child = 0, *cloned; if(total_sz > sizeof(ethhdr)) { - if(inner_pdu()) { - child = inner_pdu()->clone_packet(ptr + sizeof(ethhdr), total_sz - sizeof(ethhdr)); - if(!child) - return 0; - } - else - child = new RawPDU(ptr + sizeof(ethhdr), total_sz - sizeof(ethhdr)); + if((child = PDU::clone_inner_pdu(ptr + sizeof(ethhdr), total_sz - sizeof(ethhdr))) == 0) + return 0; } cloned = new EthernetII(eth_ptr); cloned->inner_pdu(child); diff --git a/src/icmp.cpp b/src/icmp.cpp index c691008..b26787a 100644 --- a/src/icmp.cpp +++ b/src/icmp.cpp @@ -163,14 +163,8 @@ Tins::PDU *Tins::ICMP::clone_packet(uint8_t *ptr, uint32_t total_sz) { icmphdr *icmp_ptr = (icmphdr*)ptr; PDU *child = 0, *cloned; if(total_sz > sizeof(icmphdr)) { - if(inner_pdu()) { - child = inner_pdu()->clone_packet(ptr + sizeof(icmphdr), total_sz - sizeof(icmphdr)); - if(!child) - return 0; - } - else - child = new RawPDU(ptr + sizeof(icmphdr), total_sz - sizeof(icmphdr)); - + if((child = PDU::clone_inner_pdu(ptr + sizeof(icmphdr), total_sz - sizeof(icmphdr))) == 0) + return 0; } cloned = new ICMP(icmp_ptr); cloned->inner_pdu(child); diff --git a/src/pdu.cpp b/src/pdu.cpp index 8dc27da..054d78b 100644 --- a/src/pdu.cpp +++ b/src/pdu.cpp @@ -22,6 +22,7 @@ #include #include "utils.h" #include "pdu.h" +#include "rawpdu.h" Tins::PDU::PDU(uint32_t flag, PDU *next_pdu) : _flag(flag), _inner_pdu(next_pdu) { @@ -67,6 +68,18 @@ void Tins::PDU::serialize(uint8_t *buffer, uint32_t total_sz, const PDU *parent) write_serialization(buffer, total_sz, parent); } +Tins::PDU *Tins::PDU::clone_inner_pdu(uint8_t *ptr, uint32_t total_sz) { + PDU *child = 0; + if(inner_pdu()) { + child = inner_pdu()->clone_packet(ptr, total_sz); + if(!child) + return 0; + } + else + child = new RawPDU(ptr, total_sz); + return child; +} + /* Static methods */ uint32_t Tins::PDU::do_checksum(uint8_t *start, uint8_t *end) { uint32_t checksum(0);