mirror of
https://github.com/mfontanini/libtins
synced 2026-01-23 02:35:57 +01:00
Add remove_option member to IP, TCP, Dot11, ICMPv6, DHCP and DHCPv6
This commit is contained in:
@@ -210,6 +210,17 @@ namespace Tins {
|
||||
_options.push_back(std::move(opt));
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Removes a DHCP option.
|
||||
*
|
||||
* If there are multiple options of the given type, only the first one
|
||||
* will be removed.
|
||||
*
|
||||
* \param type The type of the option to be removed.
|
||||
* \return true if the option was removed, false otherwise.
|
||||
*/
|
||||
bool remove_option(OptionTypes type);
|
||||
|
||||
/**
|
||||
* \brief Searchs for an option that matchs the given flag.
|
||||
@@ -501,6 +512,8 @@ namespace Tins {
|
||||
|
||||
void internal_add_option(const option &opt);
|
||||
serialization_type serialize_list(const std::vector<ipaddress_type> &ip_list);
|
||||
options_type::const_iterator search_option_iterator(OptionTypes opt) const;
|
||||
options_type::iterator search_option_iterator(OptionTypes opt);
|
||||
|
||||
options_type _options;
|
||||
uint32_t _size;
|
||||
|
||||
@@ -816,15 +816,26 @@ public:
|
||||
void add_option(const option &opt);
|
||||
|
||||
/**
|
||||
* \brief Searchs for an option that matchs the given flag.
|
||||
* \brief Removes a DHCPv6 option.
|
||||
*
|
||||
* If there are multiple options of the given type, only the first one
|
||||
* will be removed.
|
||||
*
|
||||
* \param type The type of the option to be removed.
|
||||
* \return true if the option was removed, false otherwise.
|
||||
*/
|
||||
bool remove_option(OptionTypes type);
|
||||
|
||||
/**
|
||||
* \brief Searchs for an option that matchs the given type.
|
||||
*
|
||||
* If the option is not found, a null pointer is returned.
|
||||
* Deleting the returned pointer will result in <b>undefined
|
||||
* behaviour</b>.
|
||||
*
|
||||
* \param id The option identifier to be searched.
|
||||
* \param type The option identifier to be searched.
|
||||
*/
|
||||
const option *search_option(OptionTypes id) const;
|
||||
const option *search_option(OptionTypes type) const;
|
||||
|
||||
// PDU stuff
|
||||
|
||||
@@ -859,6 +870,8 @@ public:
|
||||
private:
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *);
|
||||
uint8_t* write_option(const option &option, uint8_t* buffer) const;
|
||||
options_type::const_iterator search_option_iterator(OptionTypes type) const;
|
||||
options_type::iterator search_option_iterator(OptionTypes type);
|
||||
|
||||
template<template <typename> class Functor>
|
||||
const option *safe_search_option(OptionTypes opt, uint32_t size) const {
|
||||
|
||||
@@ -409,15 +409,26 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Removes a Dot11 option.
|
||||
*
|
||||
* If there are multiple options of the given type, only the first one
|
||||
* will be removed.
|
||||
*
|
||||
* \param type The type of the option to be removed.
|
||||
* \return true if the option was removed, false otherwise.
|
||||
*/
|
||||
bool remove_option(OptionTypes type);
|
||||
|
||||
/**
|
||||
* \brief Looks up a tagged option in the option list.
|
||||
*
|
||||
* The returned pointer <b>must not</b> be free'd.
|
||||
*
|
||||
* \param opt The option identifier.
|
||||
* \param type The option identifier.
|
||||
* \return The option found, or 0 if no such option has been set.
|
||||
*/
|
||||
const option *search_option(OptionTypes opt) const;
|
||||
const option *search_option(OptionTypes type) const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
@@ -511,6 +522,8 @@ private:
|
||||
|
||||
void internal_add_option(const option &opt);
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
options_type::const_iterator search_option_iterator(OptionTypes type) const;
|
||||
options_type::iterator search_option_iterator(OptionTypes type);
|
||||
|
||||
|
||||
ieee80211_header _header;
|
||||
|
||||
@@ -853,6 +853,17 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Removes an ICMPv6 option.
|
||||
*
|
||||
* If there are multiple options of the given type, only the first one
|
||||
* will be removed.
|
||||
*
|
||||
* \param type The type of the option to be removed.
|
||||
* \return true if the option was removed, false otherwise.
|
||||
*/
|
||||
bool remove_option(OptionTypes type);
|
||||
|
||||
/**
|
||||
* \brief Returns the header size.
|
||||
*
|
||||
@@ -877,9 +888,9 @@ public:
|
||||
* Deleting the returned pointer will result in <b>undefined
|
||||
* behaviour</b>.
|
||||
*
|
||||
* \param id The option identifier to be searched.
|
||||
* \param type The option identifier to be searched.
|
||||
*/
|
||||
const option *search_option(OptionTypes id) const;
|
||||
const option *search_option(OptionTypes type) const;
|
||||
|
||||
/**
|
||||
* \sa PDU::clone
|
||||
@@ -1309,6 +1320,8 @@ private:
|
||||
void parse_options(const uint8_t *&buffer, uint32_t &total_sz);
|
||||
void add_addr_list(uint8_t type, const addr_list_type &value);
|
||||
addr_list_type search_addr_list(OptionTypes type) const;
|
||||
options_type::const_iterator search_option_iterator(OptionTypes type) const;
|
||||
options_type::iterator search_option_iterator(OptionTypes type);
|
||||
|
||||
template<template <typename> class Functor>
|
||||
const option *safe_search_option(OptionTypes opt, uint32_t size) const {
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace Tins {
|
||||
END = 0,
|
||||
NOOP = 1,
|
||||
SEC = 2,
|
||||
LSSR = 3,
|
||||
LSRR = 3,
|
||||
TIMESTAMP = 4,
|
||||
EXTSEC = 5,
|
||||
RR = 7,
|
||||
@@ -443,6 +443,17 @@ namespace Tins {
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Removes an IP option.
|
||||
*
|
||||
* If there are multiple options of the given type, only the first one
|
||||
* will be removed.
|
||||
*
|
||||
* \param type The type of the option to be removed.
|
||||
* \return true if the option was removed, false otherwise.
|
||||
*/
|
||||
bool remove_option(option_identifier id);
|
||||
|
||||
/**
|
||||
* \brief Searchs for an option that matchs the given flag.
|
||||
*
|
||||
@@ -653,11 +664,15 @@ namespace Tins {
|
||||
void add_route_option(option_identifier id, const generic_route_option_type &data);
|
||||
generic_route_option_type search_route_option(option_identifier id) const;
|
||||
void checksum(uint16_t new_check);
|
||||
options_type::const_iterator search_option_iterator(option_identifier id) const;
|
||||
options_type::iterator search_option_iterator(option_identifier id);
|
||||
void update_padded_options_size();
|
||||
|
||||
iphdr _ip;
|
||||
uint16_t _options_size, _padded_options_size;
|
||||
options_type _ip_options;
|
||||
};
|
||||
}
|
||||
|
||||
} // Tins
|
||||
|
||||
#endif // TINS_IP_H
|
||||
|
||||
@@ -523,5 +523,25 @@ private:
|
||||
data_type* big_buffer_ptr;
|
||||
} payload_;
|
||||
};
|
||||
|
||||
namespace Internals {
|
||||
/*
|
||||
* \cond
|
||||
*/
|
||||
template <typename Option>
|
||||
struct option_type_equality_comparator {
|
||||
option_type_equality_comparator(typename Option::option_type type) : type(type) { }
|
||||
|
||||
bool operator()(const Option& opt) const {
|
||||
return opt.option() == type;
|
||||
}
|
||||
|
||||
typename Option::option_type type;
|
||||
};
|
||||
/*
|
||||
* \endcond
|
||||
*/
|
||||
} // Internals
|
||||
|
||||
} // namespace Tins
|
||||
#endif // TINS_PDU_OPTION_H
|
||||
|
||||
@@ -467,6 +467,17 @@ namespace Tins {
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Removes a TCP option.
|
||||
*
|
||||
* If there are multiple options of the given type, only the first one
|
||||
* will be removed.
|
||||
*
|
||||
* \param type The type of the option to be removed.
|
||||
* \return true if the option was removed, false otherwise.
|
||||
*/
|
||||
bool remove_option(OptionTypes type);
|
||||
|
||||
/**
|
||||
* \brief Returns the header size.
|
||||
*
|
||||
@@ -494,11 +505,11 @@ namespace Tins {
|
||||
PDUType pdu_type() const { return PDU::TCP; }
|
||||
|
||||
/**
|
||||
* \brief Searchs for an option that matchs the given flag.
|
||||
* \param opt_flag The flag to be searched.
|
||||
* \brief Searchs for an option that matchs the given type.
|
||||
* \param type The option type to be searched.
|
||||
* \return A pointer to the option, or 0 if it was not found.
|
||||
*/
|
||||
const option *search_option(OptionTypes opt) const;
|
||||
const option *search_option(OptionTypes type) const;
|
||||
|
||||
/**
|
||||
* \sa PDU::clone
|
||||
@@ -568,6 +579,9 @@ namespace Tins {
|
||||
void internal_add_option(const option &option);
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
void checksum(uint16_t new_check);
|
||||
void update_options_size();
|
||||
options_type::const_iterator search_option_iterator(OptionTypes type) const;
|
||||
options_type::iterator search_option_iterator(OptionTypes type);
|
||||
|
||||
uint8_t *write_option(const option &opt, uint8_t *buffer);
|
||||
|
||||
@@ -575,6 +589,6 @@ namespace Tins {
|
||||
uint16_t _options_size, _total_options_size;
|
||||
options_type _options;
|
||||
};
|
||||
}
|
||||
} // Tins
|
||||
|
||||
#endif // TINS_TCP_H
|
||||
|
||||
30
src/dhcp.cpp
30
src/dhcp.cpp
@@ -33,11 +33,13 @@
|
||||
#include "endianness.h"
|
||||
#include "dhcp.h"
|
||||
#include "ethernetII.h"
|
||||
#include "internals.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
using std::string;
|
||||
using std::list;
|
||||
using std::runtime_error;
|
||||
using std::find_if;
|
||||
|
||||
namespace Tins {
|
||||
// Magic cookie: uint32_t.
|
||||
@@ -89,12 +91,30 @@ void DHCP::internal_add_option(const option &opt) {
|
||||
_size += static_cast<uint32_t>(opt.data_size() + (sizeof(uint8_t) << 1));
|
||||
}
|
||||
|
||||
const DHCP::option *DHCP::search_option(OptionTypes opt) const {
|
||||
for(options_type::const_iterator it = _options.begin(); it != _options.end(); ++it) {
|
||||
if(it->option() == opt)
|
||||
return &(*it);
|
||||
bool DHCP::remove_option(OptionTypes type) {
|
||||
options_type::iterator iter = search_option_iterator(type);
|
||||
if (iter == _options.end()) {
|
||||
return false;
|
||||
}
|
||||
return 0;
|
||||
_size -= static_cast<uint32_t>(iter->data_size() + (sizeof(uint8_t) << 1));
|
||||
_options.erase(iter);
|
||||
return true;
|
||||
}
|
||||
|
||||
const DHCP::option *DHCP::search_option(OptionTypes opt) const {
|
||||
// Search for the iterator. If we found something, return it, otherwise return nullptr.
|
||||
options_type::const_iterator iter = search_option_iterator(opt);
|
||||
return (iter != _options.end()) ? &*iter : 0;
|
||||
}
|
||||
|
||||
DHCP::options_type::const_iterator DHCP::search_option_iterator(OptionTypes opt) const {
|
||||
Internals::option_type_equality_comparator<option> comparator(opt);
|
||||
return find_if(_options.begin(), _options.end(), comparator);
|
||||
}
|
||||
|
||||
DHCP::options_type::iterator DHCP::search_option_iterator(OptionTypes opt) {
|
||||
Internals::option_type_equality_comparator<option> comparator(opt);
|
||||
return find_if(_options.begin(), _options.end(), comparator);
|
||||
}
|
||||
|
||||
void DHCP::type(Flags type) {
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
#include "dhcpv6.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
using std::find_if;
|
||||
|
||||
namespace Tins {
|
||||
DHCPv6::DHCPv6() : options_size() {
|
||||
std::fill(header_data, header_data + sizeof(header_data), 0);
|
||||
@@ -84,12 +86,30 @@ void DHCPv6::add_option(const option &opt) {
|
||||
options_size += opt.data_size() + sizeof(uint16_t) * 2;
|
||||
}
|
||||
|
||||
const DHCPv6::option *DHCPv6::search_option(OptionTypes id) const {
|
||||
for(options_type::const_iterator it = options_.begin(); it != options_.end(); ++it) {
|
||||
if(it->option() == static_cast<uint16_t>(id))
|
||||
return &*it;
|
||||
bool DHCPv6::remove_option(OptionTypes type) {
|
||||
options_type::iterator iter = search_option_iterator(type);
|
||||
if (iter == options_.end()) {
|
||||
return false;
|
||||
}
|
||||
return 0;
|
||||
options_size -= iter->data_size() + sizeof(uint16_t) * 2;
|
||||
options_.erase(iter);
|
||||
return true;
|
||||
}
|
||||
|
||||
const DHCPv6::option *DHCPv6::search_option(OptionTypes type) const {
|
||||
// Search for the iterator. If we found something, return it, otherwise return nullptr.
|
||||
options_type::const_iterator iter = search_option_iterator(type);
|
||||
return (iter != options_.end()) ? &*iter : 0;
|
||||
}
|
||||
|
||||
DHCPv6::options_type::const_iterator DHCPv6::search_option_iterator(OptionTypes type) const {
|
||||
Internals::option_type_equality_comparator<option> comparator(type);
|
||||
return find_if(options_.begin(), options_.end(), comparator);
|
||||
}
|
||||
|
||||
DHCPv6::options_type::iterator DHCPv6::search_option_iterator(OptionTypes type) {
|
||||
Internals::option_type_equality_comparator<option> comparator(type);
|
||||
return find_if(options_.begin(), options_.end(), comparator);
|
||||
}
|
||||
|
||||
uint8_t* DHCPv6::write_option(const option &opt, uint8_t* buffer) const {
|
||||
@@ -151,8 +171,9 @@ void DHCPv6::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *
|
||||
buffer = link_addr.copy(buffer);
|
||||
buffer = peer_addr.copy(buffer);
|
||||
}
|
||||
for(options_type::const_iterator it = options_.begin(); it != options_.end(); ++it)
|
||||
for(options_type::const_iterator it = options_.begin(); it != options_.end(); ++it) {
|
||||
buffer = write_option(*it, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -106,16 +106,35 @@ void Dot11::internal_add_option(const option &opt) {
|
||||
_options_size += static_cast<uint32_t>(opt.data_size() + sizeof(uint8_t) * 2);
|
||||
}
|
||||
|
||||
bool Dot11::remove_option(OptionTypes type) {
|
||||
options_type::iterator iter = search_option_iterator(type);
|
||||
if (iter == _options.end()) {
|
||||
return false;
|
||||
}
|
||||
_options_size -= static_cast<uint32_t>(iter->data_size() + sizeof(uint8_t) * 2);
|
||||
_options.erase(iter);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Dot11::add_option(const option &opt) {
|
||||
internal_add_option(opt);
|
||||
_options.push_back(opt);
|
||||
}
|
||||
|
||||
const Dot11::option *Dot11::search_option(OptionTypes opt) const {
|
||||
for(std::list<option>::const_iterator it = _options.begin(); it != _options.end(); ++it)
|
||||
if(it->option() == (uint8_t)opt)
|
||||
return &(*it);
|
||||
return 0;
|
||||
const Dot11::option *Dot11::search_option(OptionTypes type) const {
|
||||
// Search for the iterator. If we found something, return it, otherwise return nullptr.
|
||||
options_type::const_iterator iter = search_option_iterator(type);
|
||||
return (iter != _options.end()) ? &*iter : 0;
|
||||
}
|
||||
|
||||
Dot11::options_type::const_iterator Dot11::search_option_iterator(OptionTypes type) const {
|
||||
Internals::option_type_equality_comparator<option> comparator(static_cast<uint8_t>(type));
|
||||
return find_if(_options.begin(), _options.end(), comparator);
|
||||
}
|
||||
|
||||
Dot11::options_type::iterator Dot11::search_option_iterator(OptionTypes type) {
|
||||
Internals::option_type_equality_comparator<option> comparator(static_cast<uint8_t>(type));
|
||||
return find_if(_options.begin(), _options.end(), comparator);
|
||||
}
|
||||
|
||||
void Dot11::protocol(small_uint<2> new_proto) {
|
||||
|
||||
@@ -263,18 +263,36 @@ void ICMPv6::internal_add_option(const option &option) {
|
||||
_options_size += static_cast<uint32_t>(option.data_size() + sizeof(uint8_t) * 2);
|
||||
}
|
||||
|
||||
bool ICMPv6::remove_option(OptionTypes type) {
|
||||
options_type::iterator iter = search_option_iterator(type);
|
||||
if (iter == _options.end()) {
|
||||
return false;
|
||||
}
|
||||
_options_size -= static_cast<uint32_t>(iter->data_size() + sizeof(uint8_t) * 2);
|
||||
_options.erase(iter);
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t *ICMPv6::write_option(const option &opt, uint8_t *buffer) {
|
||||
*buffer++ = opt.option();
|
||||
*buffer++ = static_cast<uint8_t>((opt.length_field() + sizeof(uint8_t) * 2) / 8);
|
||||
return std::copy(opt.data_ptr(), opt.data_ptr() + opt.data_size(), buffer);
|
||||
}
|
||||
|
||||
const ICMPv6::option *ICMPv6::search_option(OptionTypes id) const {
|
||||
for(options_type::const_iterator it = _options.begin(); it != _options.end(); ++it) {
|
||||
if(it->option() == id)
|
||||
return &*it;
|
||||
}
|
||||
return 0;
|
||||
const ICMPv6::option *ICMPv6::search_option(OptionTypes type) const {
|
||||
// Search for the iterator. If we found something, return it, otherwise return nullptr.
|
||||
options_type::const_iterator iter = search_option_iterator(type);
|
||||
return (iter != _options.end()) ? &*iter : 0;
|
||||
}
|
||||
|
||||
ICMPv6::options_type::const_iterator ICMPv6::search_option_iterator(OptionTypes type) const {
|
||||
Internals::option_type_equality_comparator<option> comparator(type);
|
||||
return find_if(_options.begin(), _options.end(), comparator);
|
||||
}
|
||||
|
||||
ICMPv6::options_type::iterator ICMPv6::search_option_iterator(OptionTypes type) {
|
||||
Internals::option_type_equality_comparator<option> comparator(type);
|
||||
return find_if(_options.begin(), _options.end(), comparator);
|
||||
}
|
||||
|
||||
// ********************************************************************
|
||||
|
||||
36
src/ip.cpp
36
src/ip.cpp
@@ -297,18 +297,40 @@ void IP::add_option(const option &opt) {
|
||||
_ip_options.push_back(opt);
|
||||
}
|
||||
|
||||
void IP::internal_add_option(const option &opt) {
|
||||
_options_size += static_cast<uint16_t>(1 + opt.data_size());
|
||||
void IP::update_padded_options_size() {
|
||||
uint8_t padding = _options_size % 4;
|
||||
_padded_options_size = padding ? (_options_size - padding + 4) : _options_size;
|
||||
}
|
||||
|
||||
const IP::option *IP::search_option(option_identifier id) const {
|
||||
for(options_type::const_iterator it = _ip_options.begin(); it != _ip_options.end(); ++it) {
|
||||
if(it->option() == id)
|
||||
return &(*it);
|
||||
void IP::internal_add_option(const option &opt) {
|
||||
_options_size += static_cast<uint16_t>(1 + opt.data_size());
|
||||
update_padded_options_size();
|
||||
}
|
||||
|
||||
bool IP::remove_option(option_identifier id) {
|
||||
options_type::iterator iter = search_option_iterator(id);
|
||||
if (iter == _ip_options.end()) {
|
||||
return false;
|
||||
}
|
||||
return 0;
|
||||
_options_size -= static_cast<uint16_t>(1 + iter->data_size());
|
||||
_ip_options.erase(iter);
|
||||
update_padded_options_size();
|
||||
return true;
|
||||
}
|
||||
|
||||
const IP::option *IP::search_option(option_identifier id) const {
|
||||
options_type::const_iterator iter = search_option_iterator(id);
|
||||
return (iter != _ip_options.end()) ? &*iter : 0;
|
||||
}
|
||||
|
||||
IP::options_type::const_iterator IP::search_option_iterator(option_identifier id) const {
|
||||
Internals::option_type_equality_comparator<option> comparator(id);
|
||||
return find_if(_ip_options.begin(), _ip_options.end(), comparator);
|
||||
}
|
||||
|
||||
IP::options_type::iterator IP::search_option_iterator(option_identifier id) {
|
||||
Internals::option_type_equality_comparator<option> comparator(id);
|
||||
return find_if(_ip_options.begin(), _ip_options.end(), comparator);
|
||||
}
|
||||
|
||||
uint8_t* IP::write_option(const option &opt, uint8_t* buffer) {
|
||||
|
||||
59
src/tcp.cpp
59
src/tcp.cpp
@@ -28,6 +28,7 @@
|
||||
*/
|
||||
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include "tcp.h"
|
||||
#include "ip.h"
|
||||
@@ -36,6 +37,9 @@
|
||||
#include "rawpdu.h"
|
||||
#include "utils.h"
|
||||
#include "exceptions.h"
|
||||
#include "internals.h"
|
||||
|
||||
using std::find_if;
|
||||
|
||||
namespace Tins {
|
||||
|
||||
@@ -321,12 +325,20 @@ void TCP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *par
|
||||
}
|
||||
}
|
||||
|
||||
const TCP::option *TCP::search_option(OptionTypes opt) const {
|
||||
for(options_type::const_iterator it = _options.begin(); it != _options.end(); ++it) {
|
||||
if(it->option() == opt)
|
||||
return &(*it);
|
||||
}
|
||||
return 0;
|
||||
const TCP::option *TCP::search_option(OptionTypes type) const {
|
||||
// Search for the iterator. If we found something, return it, otherwise return nullptr.
|
||||
options_type::const_iterator iter = search_option_iterator(type);
|
||||
return (iter != _options.end()) ? &*iter : 0;
|
||||
}
|
||||
|
||||
TCP::options_type::const_iterator TCP::search_option_iterator(OptionTypes type) const {
|
||||
Internals::option_type_equality_comparator<option> comparator(type);
|
||||
return find_if(_options.begin(), _options.end(), comparator);
|
||||
}
|
||||
|
||||
TCP::options_type::iterator TCP::search_option_iterator(OptionTypes type) {
|
||||
Internals::option_type_equality_comparator<option> comparator(type);
|
||||
return find_if(_options.begin(), _options.end(), comparator);
|
||||
}
|
||||
|
||||
/* options */
|
||||
@@ -347,18 +359,35 @@ uint8_t *TCP::write_option(const option &opt, uint8_t *buffer) {
|
||||
}
|
||||
}
|
||||
|
||||
void TCP::update_options_size() {
|
||||
uint8_t padding = _options_size & 3;
|
||||
_total_options_size = (padding) ? (_options_size - padding + 4) : _options_size;
|
||||
}
|
||||
|
||||
void TCP::internal_add_option(const option &opt) {
|
||||
uint8_t padding;
|
||||
|
||||
_options_size += sizeof(uint8_t);
|
||||
// SACK_OK contains length but not data....
|
||||
if(opt.data_size() || opt.option() == SACK_OK)
|
||||
_options_size += sizeof(uint8_t);
|
||||
|
||||
_options_size += static_cast<uint16_t>(opt.data_size());
|
||||
|
||||
padding = _options_size & 3;
|
||||
_total_options_size = (padding) ? _options_size - padding + 4 : _options_size;
|
||||
if(opt.data_size() || opt.option() == SACK_OK) {
|
||||
_options_size += sizeof(uint8_t);
|
||||
_options_size += static_cast<uint16_t>(opt.data_size());
|
||||
}
|
||||
update_options_size();
|
||||
}
|
||||
|
||||
bool TCP::remove_option(OptionTypes type) {
|
||||
options_type::iterator iter = search_option_iterator(type);
|
||||
if (iter == _options.end()) {
|
||||
return false;
|
||||
}
|
||||
_options_size -= sizeof(uint8_t);
|
||||
// SACK_OK contains length but not data....
|
||||
if(iter->data_size() || iter->option() == SACK_OK) {
|
||||
_options_size -= sizeof(uint8_t);
|
||||
_options_size -= static_cast<uint16_t>(iter->data_size());
|
||||
}
|
||||
_options.erase(iter);
|
||||
update_options_size();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TCP::matches_response(const uint8_t *ptr, uint32_t total_sz) const {
|
||||
|
||||
@@ -276,7 +276,7 @@ TEST_F(DHCPTest, ConstructorFromBuffer) {
|
||||
DHCP dhcp1(expected_packet, sizeof(expected_packet));
|
||||
std::vector<IPv4Address> routers, expected_routers;
|
||||
expected_routers.push_back("192.168.0.1");
|
||||
expected_routers.push_back("127.0.0.1");
|
||||
expected_routers.push_back("127.0.0.1");
|
||||
|
||||
EXPECT_EQ(dhcp1.opcode(), DHCP::DISCOVER);
|
||||
EXPECT_EQ(dhcp1.htype(), 1);
|
||||
@@ -305,4 +305,15 @@ TEST_F(DHCPTest, Serialize) {
|
||||
test_equals(dhcp1, dhcp2);
|
||||
}
|
||||
|
||||
TEST_F(DHCPTest, RemoveOption) {
|
||||
DHCP dhcp;
|
||||
PDU::serialization_type old_buffer = dhcp.serialize();
|
||||
dhcp.domain_name("libtins.github.io");
|
||||
dhcp.server_identifier("192.168.0.1");
|
||||
|
||||
EXPECT_TRUE(dhcp.remove_option(DHCP::DOMAIN_NAME));
|
||||
EXPECT_TRUE(dhcp.remove_option(DHCP::DHCP_SERVER_IDENTIFIER));
|
||||
|
||||
PDU::serialization_type new_buffer = dhcp.serialize();
|
||||
EXPECT_EQ(old_buffer, new_buffer);
|
||||
}
|
||||
|
||||
@@ -334,3 +334,17 @@ TEST_F(DHCPv6Test, Client_Server_ID_DUIDEN) {
|
||||
EXPECT_EQ(tmp.id, tmp2.id);
|
||||
EXPECT_EQ(tmp.data, tmp2.data);
|
||||
}
|
||||
|
||||
TEST_F(DHCPv6Test, RemoveOption) {
|
||||
DHCPv6 dhcp;
|
||||
PDU::serialization_type old_buffer = dhcp.serialize();
|
||||
|
||||
dhcp.server_unicast("fe00:0a9d:dd23::1");
|
||||
dhcp.preference(12);
|
||||
|
||||
EXPECT_TRUE(dhcp.remove_option(DHCPv6::UNICAST));
|
||||
EXPECT_TRUE(dhcp.remove_option(DHCPv6::PREFERENCE));
|
||||
|
||||
PDU::serialization_type new_buffer = dhcp.serialize();
|
||||
EXPECT_EQ(old_buffer, new_buffer);
|
||||
}
|
||||
|
||||
@@ -407,7 +407,6 @@ TEST_F(Dot11BeaconTest, RSNInformationTest) {
|
||||
EXPECT_EQ(rsn_info.akm_cyphers(), found.akm_cyphers());
|
||||
}
|
||||
|
||||
|
||||
TEST_F(Dot11BeaconTest, PCAPLoad1) {
|
||||
const uint8_t buffer[] = {
|
||||
128, 0, 0, 0, 255, 255, 255, 255, 255, 255, 244, 236, 56, 254, 77,
|
||||
@@ -460,4 +459,18 @@ TEST_F(Dot11BeaconTest, Serialize) {
|
||||
EXPECT_TRUE(std::equal(buffer.begin(), buffer.end(), expected_packet));
|
||||
}
|
||||
|
||||
TEST_F(Dot11BeaconTest, RemoveOption) {
|
||||
Dot11Beacon dot11;
|
||||
PDU::serialization_type old_buffer = dot11.serialize();
|
||||
|
||||
dot11.challenge_text("libtins ftw");
|
||||
dot11.power_constraint(0x1e);
|
||||
|
||||
EXPECT_TRUE(dot11.remove_option(Dot11::CHALLENGE_TEXT));
|
||||
EXPECT_TRUE(dot11.remove_option(Dot11::POWER_CONSTRAINT));
|
||||
|
||||
PDU::serialization_type new_buffer = dot11.serialize();
|
||||
EXPECT_EQ(old_buffer, new_buffer);
|
||||
}
|
||||
|
||||
#endif // HAVE_DOT11
|
||||
|
||||
@@ -469,3 +469,20 @@ TEST_F(ICMPv6Test, ChecksumCalculation) {
|
||||
const ICMPv6& icmp = eth.rfind_pdu<ICMPv6>();
|
||||
EXPECT_EQ(0x68bd, icmp.checksum());
|
||||
}
|
||||
|
||||
TEST_F(ICMPv6Test, RemoveOption) {
|
||||
ICMPv6 icmp;
|
||||
PDU::serialization_type old_buffer = icmp.serialize();
|
||||
|
||||
ICMPv6::recursive_dns_type data(0x9283712);
|
||||
data.servers.push_back("827d:adae::1");
|
||||
data.servers.push_back("2929:1234:fefe::2");
|
||||
icmp.recursive_dns_servers(data);
|
||||
icmp.timestamp(0x2837d6aaa231ULL);
|
||||
|
||||
EXPECT_TRUE(icmp.remove_option(ICMPv6::TIMESTAMP));
|
||||
EXPECT_TRUE(icmp.remove_option(ICMPv6::RECURSIVE_DNS_SERV));
|
||||
|
||||
PDU::serialization_type new_buffer = icmp.serialize();
|
||||
EXPECT_EQ(old_buffer, new_buffer);
|
||||
}
|
||||
|
||||
@@ -695,3 +695,26 @@ TEST_F(IPTest, SpoofedOptions) {
|
||||
EXPECT_EQ(3U, pdu.options().size());
|
||||
EXPECT_EQ(pdu.serialize().size(), pdu.size());
|
||||
}
|
||||
|
||||
TEST_F(IPTest, RemoveOption) {
|
||||
IP ip(TINS_DEFAULT_TEST_IP);
|
||||
PDU::serialization_type old_buffer = ip.serialize();
|
||||
|
||||
// Add a record route option
|
||||
IP::record_route_type record_route(0x2d);
|
||||
record_route.routes.push_back("192.168.2.3");
|
||||
record_route.routes.push_back("192.168.5.1");
|
||||
ip.record_route(record_route);
|
||||
|
||||
// Add a lsrr option
|
||||
IP::lsrr_type lsrr(0x2d);
|
||||
lsrr.routes.push_back("192.168.2.3");
|
||||
lsrr.routes.push_back("192.168.5.1");
|
||||
ip.lsrr(lsrr);
|
||||
|
||||
EXPECT_TRUE(ip.remove_option(IP::option_identifier(IP::LSRR, IP::CONTROL, 1)));
|
||||
EXPECT_TRUE(ip.remove_option(IP::option_identifier(IP::RR, IP::CONTROL, 0)));
|
||||
|
||||
PDU::serialization_type new_buffer = ip.serialize();
|
||||
EXPECT_EQ(old_buffer, new_buffer);
|
||||
}
|
||||
|
||||
@@ -263,3 +263,22 @@ TEST_F(TCPTest, SpoofedOptions) {
|
||||
EXPECT_EQ(3U, pdu.options().size());
|
||||
EXPECT_EQ(pdu.serialize().size(), pdu.size());
|
||||
}
|
||||
|
||||
TEST_F(TCPTest, RemoveOption) {
|
||||
TCP tcp(22, 987);
|
||||
uint8_t a[] = { 1,2,3,4,5,6 };
|
||||
// Add an option
|
||||
tcp.mss(1400);
|
||||
PDU::serialization_type old_buffer = tcp.serialize();
|
||||
|
||||
// Add options and remove them. The serializations before and after should be equal.
|
||||
tcp.add_option(TCP::option(TCP::SACK, 250, a, a + sizeof(a)));
|
||||
tcp.add_option(TCP::option(TCP::SACK_OK));
|
||||
tcp.add_option(TCP::option(TCP::NOP));
|
||||
EXPECT_TRUE(tcp.remove_option(TCP::SACK));
|
||||
EXPECT_TRUE(tcp.remove_option(TCP::SACK_OK));
|
||||
EXPECT_TRUE(tcp.remove_option(TCP::NOP));
|
||||
|
||||
PDU::serialization_type new_buffer = tcp.serialize();
|
||||
EXPECT_EQ(old_buffer, new_buffer);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user