mirror of
https://github.com/mfontanini/libtins
synced 2026-01-29 21:14:28 +01:00
Ported DHCP and Dot11. Almost ported DHCPv6 completely.
This commit is contained in:
@@ -32,6 +32,7 @@
|
||||
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "bootp.h"
|
||||
#include "pdu_option.h"
|
||||
@@ -271,7 +272,7 @@ namespace Tins {
|
||||
*
|
||||
* \param routers A list of ip addresses.
|
||||
*/
|
||||
void routers(const std::list<ipaddress_type> &routers);
|
||||
void routers(const std::vector<ipaddress_type> &routers);
|
||||
|
||||
/**
|
||||
* \brief Adds a domain name servers option.
|
||||
@@ -280,7 +281,7 @@ namespace Tins {
|
||||
*
|
||||
* \param dns A list of ip addresses.
|
||||
*/
|
||||
void domain_name_servers(const std::list<ipaddress_type> &dns);
|
||||
void domain_name_servers(const std::vector<ipaddress_type> &dns);
|
||||
|
||||
/**
|
||||
* \brief Adds a broadcast address option.
|
||||
@@ -377,10 +378,10 @@ namespace Tins {
|
||||
* If the option is not found, an option_not_found exception
|
||||
* is thrown.
|
||||
*
|
||||
* \return std::list<ipaddress_type> Containing the routers
|
||||
* \return std::vector<ipaddress_type> Containing the routers
|
||||
* option data.
|
||||
*/
|
||||
std::list<ipaddress_type> routers() const;
|
||||
std::vector<ipaddress_type> routers() const;
|
||||
|
||||
/**
|
||||
* \brief Searchs for a dns option.
|
||||
@@ -391,7 +392,7 @@ namespace Tins {
|
||||
* \return std::list<ipaddress_type> Contanining the DNS servers
|
||||
* provided.
|
||||
*/
|
||||
std::list<ipaddress_type> domain_name_servers() const;
|
||||
std::vector<ipaddress_type> domain_name_servers() const;
|
||||
|
||||
/**
|
||||
* \brief Searchs for a broadcast option.
|
||||
@@ -450,27 +451,19 @@ namespace Tins {
|
||||
}
|
||||
private:
|
||||
static const uint32_t MAX_DHCP_SIZE;
|
||||
|
||||
template<typename T>
|
||||
struct type2type {};
|
||||
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
|
||||
|
||||
template<class T>
|
||||
T generic_search(OptionTypes opt, type2type<T>) const {
|
||||
T search_and_convert(OptionTypes opt) const {
|
||||
const option *option = search_option(opt);
|
||||
if(option && option->data_size() == sizeof(T))
|
||||
return *(const T*)option->data_ptr();
|
||||
else
|
||||
if(!option)
|
||||
throw option_not_found();
|
||||
return option->to<T>();
|
||||
}
|
||||
|
||||
void internal_add_option(const option &opt);
|
||||
std::list<ipaddress_type> generic_search(OptionTypes opt, type2type<std::list<ipaddress_type> >) const;
|
||||
std::string generic_search(OptionTypes opt, type2type<std::string>) const;
|
||||
ipaddress_type generic_search(OptionTypes opt, type2type<ipaddress_type>) const;
|
||||
|
||||
serialization_type serialize_list(const std::list<ipaddress_type> &ip_list);
|
||||
serialization_type serialize_list(const std::vector<ipaddress_type> &ip_list);
|
||||
|
||||
options_type _options;
|
||||
uint32_t _size;
|
||||
|
||||
@@ -179,6 +179,8 @@ public:
|
||||
ia_na_type(uint32_t id = 0, uint32_t t1 = 0, uint32_t t2 = 0,
|
||||
const options_type& options = options_type())
|
||||
: id(id), t1(t1), t2(t2), options(options) {}
|
||||
|
||||
static ia_na_type from_option(const option &opt);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -194,6 +196,8 @@ public:
|
||||
ia_ta_type(uint32_t id = 0,
|
||||
const options_type& options = options_type())
|
||||
: id(id), options(options) {}
|
||||
|
||||
static ia_ta_type from_option(const option &opt);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -211,6 +215,8 @@ public:
|
||||
const options_type& options = options_type())
|
||||
: address(address), preferred_lifetime(preferred_lifetime),
|
||||
valid_lifetime(valid_lifetime), options(options) {}
|
||||
|
||||
static ia_address_type from_option(const option &opt);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -228,6 +234,8 @@ public:
|
||||
const auth_info_type &auth_info = auth_info_type())
|
||||
: protocol(protocol), algorithm(algorithm), rdm(rdm),
|
||||
replay_detection(replay_detection), auth_info(auth_info) {}
|
||||
|
||||
static authentication_type from_option(const option &opt);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -239,6 +247,8 @@ public:
|
||||
|
||||
status_code_type(uint16_t code = 0, const std::string &message = "")
|
||||
: code(code), message(message) { }
|
||||
|
||||
static status_code_type from_option(const option &opt);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -253,6 +263,8 @@ public:
|
||||
vendor_info_type(uint32_t enterprise_number = 0,
|
||||
const data_type &data = data_type())
|
||||
: enterprise_number(enterprise_number), data(data) { }
|
||||
|
||||
static vendor_info_type from_option(const option &opt);
|
||||
};
|
||||
|
||||
|
||||
@@ -279,6 +291,8 @@ public:
|
||||
const class_data_type &vendor_class_data = class_data_type())
|
||||
: enterprise_number(enterprise_number),
|
||||
vendor_class_data(vendor_class_data) { }
|
||||
|
||||
static vendor_class_type from_option(const option &opt);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -361,12 +375,14 @@ public:
|
||||
|
||||
duid_type(const duid_ll &identifier)
|
||||
: id(duid_en::duid_id), data(identifier.serialize()) {}
|
||||
|
||||
static duid_type from_option(const option &opt);
|
||||
};
|
||||
|
||||
/**
|
||||
* The type used to store the Option Request option.
|
||||
*/
|
||||
typedef std::vector<OptionTypes> option_request_type;
|
||||
typedef std::vector<uint16_t> option_request_type;
|
||||
|
||||
/**
|
||||
* The type used to store the Relay Message option.
|
||||
@@ -837,6 +853,14 @@ private:
|
||||
throw option_not_found();
|
||||
return option;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T search_and_convert(OptionTypes opt) const {
|
||||
const option *option = search_option(opt);
|
||||
if(!option)
|
||||
throw option_not_found();
|
||||
return option->to<T>();
|
||||
}
|
||||
|
||||
template<typename InputIterator>
|
||||
void class_option_data2option(InputIterator start, InputIterator end,
|
||||
@@ -882,7 +906,48 @@ private:
|
||||
uint32_t options_size;
|
||||
ipaddress_type link_addr, peer_addr;
|
||||
options_type options_;
|
||||
};
|
||||
};
|
||||
|
||||
namespace Internals {
|
||||
template<typename InputIterator>
|
||||
void class_option_data2option(InputIterator start, InputIterator end,
|
||||
std::vector<uint8_t>& buffer, size_t start_index = 0)
|
||||
{
|
||||
size_t index = start_index;
|
||||
while(start != end) {
|
||||
buffer.resize(buffer.size() + sizeof(uint16_t) + start->size());
|
||||
*(uint16_t*)&buffer[index] = Endian::host_to_be<uint16_t>(start->size());
|
||||
index += sizeof(uint16_t);
|
||||
std::copy(start->begin(), start->end(), buffer.begin() + index);
|
||||
index += start->size();
|
||||
|
||||
start++;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename OutputType>
|
||||
OutputType option2class_option_data(const uint8_t *ptr, uint32_t total_sz)
|
||||
{
|
||||
typedef typename OutputType::value_type value_type;
|
||||
OutputType output;
|
||||
size_t index = 0;
|
||||
while(index + 2 < total_sz) {
|
||||
uint16_t size = Endian::be_to_host(
|
||||
*(const uint16_t*)(ptr + index)
|
||||
);
|
||||
index += sizeof(uint16_t);
|
||||
if(index + size > total_sz)
|
||||
throw option_not_found();
|
||||
output.push_back(
|
||||
value_type(ptr + index, ptr + index + size)
|
||||
);
|
||||
index += size;
|
||||
}
|
||||
if(index != total_sz)
|
||||
throw malformed_option();
|
||||
return output;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // TINS_DHCPV6_H
|
||||
|
||||
@@ -379,6 +379,8 @@ public:
|
||||
uint8_t hop_pattern, uint8_t hop_index)
|
||||
: dwell_time(dwell_time), hop_set(hop_set),
|
||||
hop_pattern(hop_pattern), hop_index(hop_index) {}
|
||||
|
||||
static fh_params_set from_option(const option &opt);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -395,6 +397,8 @@ public:
|
||||
: cfp_count(cfp_count), cfp_period(cfp_period),
|
||||
cfp_max_duration(cfp_max_duration),
|
||||
cfp_dur_remaining(cfp_dur_remaining) {}
|
||||
|
||||
static cf_params_set from_option(const option &opt);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -413,6 +417,8 @@ public:
|
||||
uint8_t recovery_interval, const channels_type &channels)
|
||||
: dfs_owner(addr), recovery_interval(recovery_interval),
|
||||
channel_map(channels) {}
|
||||
|
||||
static ibss_dfs_params from_option(const option &opt);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -431,6 +437,8 @@ public:
|
||||
const byte_array &number, const byte_array &max)
|
||||
: country(country), first_channel(first), number_channels(number),
|
||||
max_transmit_power(max) {}
|
||||
|
||||
static country_params from_option(const option &opt);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -448,6 +456,8 @@ public:
|
||||
uint8_t offset, const byte_array& table)
|
||||
: flag(flag), number_of_sets(sets), modulus(modulus),
|
||||
offset(offset), random_table(table) {}
|
||||
|
||||
static fh_pattern_type from_option(const option &opt);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -460,6 +470,8 @@ public:
|
||||
|
||||
channel_switch_type(uint8_t mode, uint8_t channel, uint8_t count)
|
||||
: switch_mode(mode), new_channel(channel), switch_count(count) { }
|
||||
|
||||
static channel_switch_type from_option(const option &opt);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -475,6 +487,8 @@ public:
|
||||
uint16_t offset)
|
||||
: quiet_count(count), quiet_period(period),
|
||||
quiet_duration(duration), quiet_offset(offset) {}
|
||||
|
||||
static quiet_type from_option(const option &opt);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -491,6 +505,8 @@ public:
|
||||
uint16_t capacity)
|
||||
: station_count(count), available_capacity(capacity),
|
||||
channel_utilization(utilization) {}
|
||||
|
||||
static bss_load_type from_option(const option &opt);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -506,6 +522,8 @@ public:
|
||||
const byte_array &bitmap)
|
||||
: dtim_count(count), dtim_period(period), bitmap_control(control),
|
||||
partial_virtual_bitmap(bitmap) {}
|
||||
|
||||
static tim_type from_option(const option &opt);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -39,8 +39,8 @@
|
||||
#include "endianness.h"
|
||||
#include "internals.h"
|
||||
#include "ip_address.h"
|
||||
#include "hw_address.h"
|
||||
#include "ipv6_address.h"
|
||||
#include "hw_address.h"
|
||||
|
||||
namespace Tins {
|
||||
/**
|
||||
@@ -113,6 +113,30 @@ namespace Internals {
|
||||
return HWAddress<n>(opt.data_ptr());
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct converter<IPv4Address> {
|
||||
template<typename X, typename PDUType>
|
||||
static IPv4Address convert(const PDUOption<X, PDUType>& opt) {
|
||||
if(opt.data_size() != sizeof(uint32_t))
|
||||
throw malformed_option();
|
||||
const uint32_t *ptr = (const uint32_t*)opt.data_ptr();
|
||||
if(PDUType::endianness == PDUType::BE)
|
||||
return IPv4Address(*ptr);
|
||||
else
|
||||
return IPv4Address(Endian::change_endian(*ptr));
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct converter<IPv6Address> {
|
||||
template<typename X, typename PDUType>
|
||||
static IPv6Address convert(const PDUOption<X, PDUType>& opt) {
|
||||
if(opt.data_size() != IPv6Address::address_size)
|
||||
throw malformed_option();
|
||||
return IPv6Address(opt.data_ptr());
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct converter<std::string> {
|
||||
@@ -208,7 +232,7 @@ namespace Internals {
|
||||
if(PDUType::endianness == PDUType::BE)
|
||||
*it++ = IPv4Address(*ptr++);
|
||||
else
|
||||
*it++ = Endian::change_endian(*ptr++);
|
||||
*it++ = IPv4Address(Endian::change_endian(*ptr++));
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user