diff --git a/include/arp.h b/include/arp.h index cb22ca6..63fa64d 100644 --- a/include/arp.h +++ b/include/arp.h @@ -128,7 +128,7 @@ namespace Tins { * * \param new_snd_hw_addr uint8_t array containing the new sender's hardware address. */ - void sender_hw_addr(uint8_t* new_snd_hw_addr); + void sender_hw_addr(const uint8_t* new_snd_hw_addr); /** * \brief Setter for the sender's IP address. @@ -137,12 +137,19 @@ namespace Tins { */ void sender_ip_addr(uint32_t new_snd_ip_addr); + /** + * \brief Setter for the sender's IP address. + * + * \param new_snd_ip_addr string containing the new sender's IP address or hostname. + */ + void sender_ip_addr(const std::string& new_snd_ip_addr); + /** * \brief Setter for the target's hardware address. * * \param new_tgt_hw_addr uint8_t array containing the new target's hardware address. */ - void target_hw_addr(uint8_t* new_tgt_hw_addr); + void target_hw_addr(const uint8_t* new_tgt_hw_addr); /** * \brief Setter for the target's IP address. @@ -151,6 +158,13 @@ namespace Tins { */ void target_ip_addr(uint32_t new_tgt_ip_addr); + /** + * \brief Setter for the target's IP address. + * + * \param new_tgt_ip_addr string containing the new target's IP address or hostname. + */ + void target_ip_addr(const std::string& new_tgt_ip_addr); + /** * \brief Setter for the hardware address format. * diff --git a/include/ip.h b/include/ip.h index 078d0af..26ac3a5 100644 --- a/include/ip.h +++ b/include/ip.h @@ -100,45 +100,75 @@ namespace Tins { */ IP(uint32_t ip_dst = 0, uint32_t ip_src = 0, PDU *child = 0); + /** + * \brief Destructor for IP objects. + * + * Destructs IP objects releasing the allocated memory for the options + * if options exist. + */ + ~IP(); + /* Getters */ - /** \brief Getter for the type of service field. + /** + * \brief Getter for the header length field. + * + * \return The number of dwords the header occupies in an uin8_t. + */ + inline uint8_t head_len() const { return this->_ip.ihl; } + + /** + * \brief Getter for the type of service field. * * \return The this IP PDU's type of service. */ inline uint8_t tos() const { return _ip.tos; } - /** \brief Getter for the total length field. + /** + * \brief Getter for the total length field. + * * \return The total length of this IP PDU. */ inline uint16_t tot_len() const { return Utils::net_to_host_s(_ip.tot_len); } - /** \brief Getter for the id field. + /** + * \brief Getter for the id field. + * * \return The id for this IP PDU. */ inline uint16_t id() const { return Utils::net_to_host_s(_ip.id); } - /** \brief Getter for the fragment offset field. + /** + * \brief Getter for the fragment offset field. + * * \return The fragment offset for this IP PDU. */ inline uint16_t frag_off() const { return Utils::net_to_host_s(_ip.frag_off); } - /** \brief Getter for the time to live field. + /** + * \brief Getter for the time to live field. + * * \return The time to live for this IP PDU. */ inline uint8_t ttl() const { return _ip.ttl; } - /** \brief Getter for the protocol field. + /** + * \brief Getter for the protocol field. + * * \return The protocol for this IP PDU. */ inline uint8_t protocol() const { return _ip.protocol; } - /** \brief Getter for the checksum field. + /** + * \brief Getter for the checksum field. + * * \return The checksum for this IP PDU. */ inline uint16_t check() const { return Utils::net_to_host_s(_ip.check); } - /** \brief Getter for the source address field. + /** + * \brief Getter for the source address field. + * * \return The source address for this IP PDU. */ inline uint32_t source_address() const { return _ip.saddr; } @@ -150,62 +180,93 @@ namespace Tins { /* Setters */ - /** \brief Setter for the type of service field. + /** + * \brief Setter for the header length field. + * + * \param new_head_len uint8_t with the new header length. + */ + void head_len(uint8_t new_head_len); + + /** + * \brief Setter for the type of service field. + * * \param new_tos The new type of service. */ void tos(uint8_t new_tos); - /** \brief Setter for the total length field. + /** + * \brief Setter for the total length field. + * * \param new_tot_len The new total length. */ void tot_len(uint16_t new_tot_len); - /** \brief Setter for the id field. + /** + * \brief Setter for the id field. + * * \param new_id The new id. */ void id(uint16_t new_id); - /** \brief Setter for the fragment offset field. + /** + * \brief Setter for the fragment offset field. + * * \param new_frag_off The new fragment offset. */ void frag_off(uint16_t new_frag_off); - /** \brief Setter for the time to live field. + /** + * \brief Setter for the time to live field. + * * \param new_ttl The new time to live. */ void ttl(uint8_t new_ttl); - /** \brief Setter for the protocol field. + /** + * \brief Setter for the protocol field. + * * \param new_protocol The new protocol. */ void protocol(uint8_t new_protocol); - /** \brief Setter for the checksum field. + /** + * \brief Setter for the checksum field. + * * \param new_check The new checksum. */ void check(uint16_t new_check); - /** \brief Setter for the source address field. + /** + * \brief Setter for the source address field. + * * \param ip The ip address in dotted string notation. */ void source_address(const std::string &ip); - /** \brief Setter for the source address field. + /** + * \brief Setter for the source address field. + * * \param ip The ip address in integer notation. */ void source_address(uint32_t ip); - /** \brief Setter for the destination address field. + /** + * \brief Setter for the destination address field. + * * \param ip The ip address in dotted string notation. */ void dest_address(const std::string &ip); - /** \brief Setter for the destination address field. + /** + * \brief Setter for the destination address field. + * * \param ip The ip address in integer notation. */ void dest_address(uint32_t ip); - /** \brief Sets an IP option. + /** + * \brief Sets an IP option. + * * \param copied The copied flag for this option. * \param op_class The option class to be set. * \param number The options number to be set. @@ -214,15 +275,19 @@ namespace Tins { */ void set_option(uint8_t copied, OptionClass op_class, OptionNumber number, uint8_t* data = 0, uint32_t data_size = 0); - /** \brief Sets the End of List option. + /** + * \brief Sets the End of List option. */ void set_option_eol(); - /** \brief Sets the NOP option. + /** + * \brief Sets the NOP option. */ void set_option_noop(); - /** \brief Sets the security option. + /** + * \brief Sets the security option. + * * \param data The data for this option * \param data_len The length of the data. */ @@ -231,7 +296,8 @@ namespace Tins { /* Virtual methods */ - /** \brief Returns the header size. + /** + * \brief Returns the header size. * * This metod overrides PDU::header_size. \sa PDU::header_size */ @@ -242,7 +308,8 @@ namespace Tins { */ bool send(PacketSender* sender); - /** \brief Check wether ptr points to a valid response for this PDU. + /** + * \brief Check wether ptr points to a valid response for this PDU. * * \sa PDU::matches_response * \param ptr The pointer to the buffer. @@ -250,7 +317,8 @@ namespace Tins { */ bool matches_response(uint8_t *ptr, uint32_t total_sz); - /** \brief Receives a matching response for this packet. + /** + * \brief Receives a matching response for this packet. * * \sa PDU::recv_response * \param sender The packet sender which will receive the packet. @@ -263,7 +331,8 @@ namespace Tins { */ PDUType pdu_type() const { return PDU::IP; } - /** \brief Clones this pdu, filling the corresponding header with data + /** + * \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. diff --git a/src/arp.cpp b/src/arp.cpp index 012696a..6c8d5d1 100644 --- a/src/arp.cpp +++ b/src/arp.cpp @@ -47,10 +47,10 @@ Tins::PDU* Tins::ARP::make_arp_request(const std::string& iface, /* Create ARP packet and set its attributes */ ARP* arp = new ARP(); - arp->_arp.ar_tip = target; - arp->_arp.ar_sip = sender; + arp->target_ip_addr(target); + arp->sender_ip_addr(sender); if (hw_snd) { - memcpy(arp->_arp.ar_sha, hw_snd, 6); + arp->sender_hw_addr(hw_snd); } arp->opcode(REQUEST); @@ -78,10 +78,10 @@ Tins::PDU* Tins::ARP::make_arp_reply(const string& iface, /* Create ARP packet and set its attributes */ ARP* arp = new ARP(); - arp->_arp.ar_tip = target; - arp->_arp.ar_sip = sender; - memcpy(arp->_arp.ar_sha, hw_snd, 6); - memcpy(arp->_arp.ar_tha, hw_tgt, 6); + arp->target_ip_addr(target); + arp->sender_ip_addr(sender); + arp->target_hw_addr(hw_tgt); + arp->sender_hw_addr(hw_snd); arp->opcode(REPLY); /* Create the EthernetII PDU with the ARP PDU as its inner PDU */ @@ -91,17 +91,17 @@ Tins::PDU* Tins::ARP::make_arp_reply(const string& iface, Tins::ARP::ARP() : PDU(0x0608) { std::memset(&_arp, 0, sizeof(arphdr)); - _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; + this->hw_addr_format(1); + this->prot_addr_format(0x0800); + this->hw_addr_length(6); + this->prot_addr_length(4); } Tins::ARP::ARP(arphdr *arp_ptr) : PDU(Utils::net_to_host_s(0x0806)) { memcpy(&_arp, arp_ptr, sizeof(arphdr)); } -void Tins::ARP::sender_hw_addr(uint8_t* new_snd_hw_addr) { +void Tins::ARP::sender_hw_addr(const uint8_t* new_snd_hw_addr) { memcpy(this->_arp.ar_sha, new_snd_hw_addr, 6); //Should this use hardware address' length? } @@ -109,7 +109,11 @@ void Tins::ARP::sender_ip_addr(uint32_t new_snd_ip_addr) { this->_arp.ar_sip = new_snd_ip_addr; } -void Tins::ARP::target_hw_addr(uint8_t* new_tgt_hw_addr) { +void Tins::ARP::sender_ip_addr(const string& new_snd_ip_addr) { + this->_arp.ar_sip = Utils::ip_to_int(new_snd_ip_addr); +} + +void Tins::ARP::target_hw_addr(const uint8_t* new_tgt_hw_addr) { memcpy(this->_arp.ar_tha, new_tgt_hw_addr, 6); //Should this use hardware address' length? } @@ -117,6 +121,10 @@ void Tins::ARP::target_ip_addr(uint32_t new_tgt_ip_addr) { this->_arp.ar_tip = new_tgt_ip_addr; } +void Tins::ARP::target_ip_addr(const std::string& new_tgt_ip_addr) { + this->_arp.ar_tip = Utils::ip_to_int(new_tgt_ip_addr); +} + void Tins::ARP::hw_addr_format(uint16_t new_hw_addr_fmt) { this->_arp.ar_hrd = Utils::net_to_host_s(new_hw_addr_fmt); } @@ -138,10 +146,10 @@ 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); + this->target_ip_addr(ip_tgt); + this->sender_ip_addr(ip_snd); if (hw_snd) - memcpy(this->_arp.ar_sha, hw_snd, 6); + this->sender_hw_addr(hw_snd); this->opcode(REQUEST); } @@ -150,10 +158,10 @@ void Tins::ARP::set_arp_reply(const std::string& ip_tgt, const uint8_t* hw_tgt, const uint8_t* hw_snd) { - this->_arp.ar_tip = Utils::resolve_ip(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->target_ip_addr(ip_tgt); + this->sender_ip_addr(ip_snd); + this->sender_hw_addr(hw_snd); + this->target_hw_addr(hw_tgt); this->opcode(REPLY); } diff --git a/src/ip.cpp b/src/ip.cpp index fc1103f..b54de5c 100644 --- a/src/ip.cpp +++ b/src/ip.cpp @@ -53,14 +53,20 @@ Tins::IP::IP(uint32_t ip_dst, uint32_t ip_src, PDU *child) : PDU(IPPROTO_IP, chi _ip.saddr = ip_src; } +Tins::IP::~IP() { + for (vector::iterator it = this->_ip_options.begin(); it != this->_ip_options.end(); it++) { + if (it->optional_data) + delete[] it->optional_data; + } +} + void Tins::IP::init_ip_fields() { memset(&_ip, 0, sizeof(iphdr)); - _ip.version = 4; - _ip.ihl = sizeof(iphdr) / sizeof(uint32_t); - _ip.ttl = DEFAULT_TTL; - _ip.id = Utils::net_to_host_s(1); - _options_size = 0; - _padded_options_size = 0; + this->_ip.version = 4; + this->ttl(DEFAULT_TTL); + this->id(1); + this->_options_size = 0; + this->_padded_options_size = 0; } /* Setters */ @@ -109,6 +115,10 @@ void Tins::IP::dest_address(uint32_t ip) { _ip.daddr = ip; } +void Tins::IP::head_len(uint8_t new_head_len) { + this->_ip.ihl = new_head_len; +} + void Tins::IP::set_option_eol() { this->set_option(0, IP::CONTROL, IP::IPOPT_END); } @@ -196,21 +206,28 @@ void Tins::IP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU } else new_flag = IPPROTO_IP; - flag(new_flag); - _ip.protocol = new_flag; - _ip.tot_len = Utils::net_to_host_s(total_sz); - _ip.ihl = my_sz / sizeof(uint32_t); + this->flag(new_flag); + this->protocol(new_flag); + this->tot_len(total_sz); + this->head_len (my_sz / sizeof(uint32_t)); + memcpy(buffer, &_ip, sizeof(iphdr)); + + uint8_t* ptr_buffer = buffer + sizeof(iphdr); + for (uint32_t i = 0; i < _ip_options.size(); ++i) + ptr_buffer = _ip_options[i].write(ptr_buffer); + + memset(buffer + sizeof(iphdr) + this->_options_size, 0, this->_padded_options_size - this->_options_size); + if (parent && !_ip.check) { - uint32_t checksum = PDU::do_checksum(buffer, buffer + sizeof(iphdr)); + uint32_t checksum = PDU::do_checksum(buffer, buffer + sizeof(iphdr) + _padded_options_size); while (checksum >> 16) checksum = (checksum & 0xffff) + (checksum >> 16); ((iphdr*)buffer)->check = Utils::net_to_host_s(~checksum); + this->check(0); } - /* IP Options here... */ - buffer += sizeof(iphdr); - for (uint32_t i = 0; i < _ip_options.size(); ++i) - buffer = _ip_options[i].write(buffer); + + } bool Tins::IP::matches_response(uint8_t *ptr, uint32_t total_sz) {