1
0
mirror of https://github.com/mfontanini/libtins synced 2026-01-28 20:44:26 +01:00

Added some Dot11 tests and fixed some bugs.

This commit is contained in:
Matias Fontanini
2012-08-21 12:01:26 -03:00
parent 80198909eb
commit c0c1d43b5e
3 changed files with 199 additions and 54 deletions

View File

@@ -938,6 +938,47 @@ namespace Tins {
void immediate_block_ack(bool new_value) { this->_immediate_block_ack = new_value; }
} __attribute__((__packed__));
struct fh_params_set {
uint16_t dwell_time;
uint8_t hop_set, hop_pattern, hop_index;
fh_params_set() {}
fh_params_set(uint16_t dwell_time, uint8_t hop_set,
uint8_t hop_pattern, uint8_t hop_index)
: dwell_time(dwell_time), hop_set(hop_set),
hop_pattern(hop_pattern), hop_index(hop_index) {}
} __attribute__((__packed__));
struct cf_params_set {
uint8_t cfp_count, cfp_period;
uint16_t cfp_max_duration, cfp_dur_remaining;
cf_params_set() {}
cf_params_set(uint8_t cfp_count, uint8_t cfp_period,
uint16_t cfp_max_duration, uint16_t cfp_dur_remaining)
: cfp_count(cfp_count), cfp_period(cfp_period),
cfp_max_duration(cfp_max_duration),
cfp_dur_remaining(cfp_dur_remaining) {}
} __attribute__((__packed__));
struct ibss_dfs_params {
static const bool minimum_size = address_type::address_size + sizeof(uint8_t) + 2 * sizeof(uint8_t);
address_type dfs_owner;
uint8_t recovery_interval;
channels_type channel_map;
ibss_dfs_params() {}
ibss_dfs_params(const address_type &addr,
uint8_t recovery_interval, const channels_type &channels)
: dfs_owner(addr), recovery_interval(recovery_interval),
channel_map(channels) {}
};
/**
* \brief Getter for the second address.
@@ -1081,12 +1122,9 @@ namespace Tins {
/**
* \brief Helper method to set the FH parameter.
*
* \param dwell_time uint16_t with the dwell_time value.
* \param hop_set uint8_t with the value of the set_hop.
* \param hop_pattern uint8_t with the value of the hop_pattern field.
* \param hop_index uint8_t with the value of the hop_index field.
* \param fh_params the fh parameter set.
*/
void fh_parameter_set(uint16_t dwell_time, uint8_t hop_set, uint8_t hop_pattern, uint8_t hop_index);
void fh_parameter_set(fh_params_set fh_params);
/**
* \brief Helper method to set the DS parameter.
@@ -1098,12 +1136,9 @@ namespace Tins {
/**
* \brief Helper method to set the CF parameter.
*
* \param cfp_count uint8_t with the value of the cfp count field.
* \param cfp_period uint8_t with the value of the cfp period field.
* \param cfp_max_duration uint16_t with the value of the cfp max duration field.
* \param cfp_dur_remaining uint16_t with the value of the DurRemaining field.
* \param params the CF parammeters to be set.
*/
void cf_parameter_set(uint8_t cfp_count, uint8_t cfp_period, uint16_t cfp_max_duration, uint16_t cfp_dur_remaining);
void cf_parameter_set(cf_params_set params);
/**
* \brief Helper method to set the IBSS parameter.
@@ -1115,11 +1150,9 @@ namespace Tins {
/**
* \brief Helper method to set the IBSS DFS tagged option.
*
* \param dfs_owner uint8_t array of 6 bytes with the dfs owner.
* \param recovery_interval uint8_t with the value of the recovery interval field.
* \param channel_map Reference to a constant vector of pair of uint8_t with the map of channels.
* \param params The IBSS DFS data to be set.
*/
void ibss_dfs(const uint8_t* dfs_owner, uint8_t recovery_interval, const std::vector<std::pair<uint8_t, uint8_t> >& channel_map);
void ibss_dfs(const ibss_dfs_params &params);
/**
* \brief Helper method to set the country tagged option.
@@ -1293,6 +1326,42 @@ namespace Tins {
*/
request_info_type request_information() const;
/**
* \brief Helper method to get the fh parameter set.
*
* Throws a std::runtime_error if the option has not been set.
*
* \return fh_params_set containing the fh parameter set.
*/
fh_params_set fh_parameter_set() const;
/**
* \brief Helper method to get the ds parameter set.
*
* Throws a std::runtime_error if the option has not been set.
*
* \return uint8_t containing the ds parameter set.
*/
uint8_t ds_parameter_set() const;
/**
* \brief Helper method to get the ibss parameter set.
*
* Throws a std::runtime_error if the option has not been set.
*
* \return uint16_t containing the ibss parameter set.
*/
uint16_t ibss_parameter_set() const;
/**
* \brief Helper method to get the ibss dfs.
*
* Throws a std::runtime_error if the option has not been set.
*
* \return ibss_dfs_params containing the ibss dfs.
*/
ibss_dfs_params ibss_dfs() const;
// ************************
/**

View File

@@ -411,14 +411,12 @@ void Dot11ManagementFrame::request_information(const request_info_type elements)
delete[] buffer;
}
void Dot11ManagementFrame::fh_parameter_set(uint16_t dwell_time, uint8_t hop_set, uint8_t hop_pattern, uint8_t hop_index) {
uint8_t buffer[5];
uint16_t* ptr_buffer = (uint16_t*)buffer;
ptr_buffer[0] = dwell_time;
buffer[2] = hop_set;
buffer[3] = hop_pattern;
buffer[4] = hop_index;
add_tagged_option(FH_SET, 5, buffer);
void Dot11ManagementFrame::fh_parameter_set(fh_params_set fh_params) {
fh_params.dwell_time = Utils::host_to_le(fh_params.dwell_time);
fh_params.hop_set = Utils::host_to_le(fh_params.hop_set);
fh_params.hop_pattern = Utils::host_to_le(fh_params.hop_pattern);
fh_params.hop_index = Utils::host_to_le(fh_params.hop_index);
add_tagged_option(FH_SET, sizeof(fh_params_set), (uint8_t*)&fh_params);
}
@@ -426,24 +424,37 @@ void Dot11ManagementFrame::ds_parameter_set(uint8_t current_channel) {
add_tagged_option(DS_SET, 1, &current_channel);
}
void Dot11ManagementFrame::cf_parameter_set(uint8_t cfp_count,
uint8_t cfp_period,
uint16_t cfp_max_duration,
uint16_t cfp_dur_remaining) {
uint8_t buffer[6];
uint16_t* ptr_buffer = (uint16_t*)buffer;
buffer[0] = cfp_count;
buffer[1] = cfp_period;
ptr_buffer[1] = cfp_max_duration;
ptr_buffer[2] = cfp_dur_remaining;
add_tagged_option(CF_SET, 6, buffer);
void Dot11ManagementFrame::cf_parameter_set(cf_params_set params) {
params.cfp_count = Utils::host_to_le(params.cfp_count);
params.cfp_period = Utils::host_to_le(params.cfp_period);
params.cfp_max_duration = Utils::host_to_le(params.cfp_max_duration);
params.cfp_dur_remaining = Utils::host_to_le(params.cfp_dur_remaining);
add_tagged_option(CF_SET, sizeof(params), (uint8_t*)&params);
}
void Dot11ManagementFrame::ibss_parameter_set(uint16_t atim_window) {
atim_window = Utils::host_to_le(atim_window);
add_tagged_option(IBSS_SET, 2, (uint8_t*)&atim_window);
}
void Dot11ManagementFrame::ibss_dfs(const ibss_dfs_params &params) {
uint8_t sz = address_type::address_size + sizeof(uint8_t) + sizeof(uint8_t) * 2 * params.channel_map.size();
uint8_t* buffer = new uint8_t[sz];
uint8_t* ptr_buffer = buffer;
ptr_buffer = params.dfs_owner.copy(ptr_buffer);
*(ptr_buffer++) = params.recovery_interval;
for (channels_type::const_iterator it = params.channel_map.begin(); it != params.channel_map.end(); ++it) {
*(ptr_buffer++) = it->first;
*(ptr_buffer++) = it->second;
}
add_tagged_option(IBSS_DFS, sz, buffer);
delete[] buffer;
}
void Dot11ManagementFrame::country(const std::vector<uint8_t*>& countries,
const std::vector<uint8_t>& first_channels,
const std::vector<uint8_t>& number_channels,
@@ -526,25 +537,6 @@ void Dot11ManagementFrame::quiet(uint8_t quiet_count, uint8_t quiet_period, uint
}
void Dot11ManagementFrame::ibss_dfs(const uint8_t* dfs_owner, uint8_t recovery_interval, const vector<pair<uint8_t, uint8_t> >& channel_map) {
uint8_t sz = 7 + 2 * channel_map.size();
uint8_t* buffer = new uint8_t[sz];
uint8_t* ptr_buffer = buffer;
memcpy(ptr_buffer, dfs_owner, 6);
ptr_buffer += 6;
*(ptr_buffer++) = recovery_interval;
for (vector<pair<uint8_t, uint8_t> >::const_iterator it = channel_map.begin(); it != channel_map.end(); it++) {
*(ptr_buffer++) = it->first;
*(ptr_buffer++) = it->second;
}
add_tagged_option(IBSS_DFS, sz, buffer);
delete[] buffer;
}
void Dot11ManagementFrame::tpc_report(uint8_t transmit_power, uint8_t link_margin) {
uint8_t buffer[2];
buffer[0] = transmit_power;
@@ -680,7 +672,7 @@ Dot11ManagementFrame::channels_type Dot11ManagementFrame::supported_channels() c
Dot11ManagementFrame::request_info_type Dot11ManagementFrame::request_information() const {
const Dot11::Dot11Option *option = search_option(REQUEST_INFORMATION);
if(!option)
throw std::runtime_error("Supported channels not set");
throw std::runtime_error("Request information not set");
request_info_type output;
const uint8_t *ptr = option->data_ptr(), *end = ptr + option->data_size();
while(ptr != end)
@@ -688,6 +680,50 @@ Dot11ManagementFrame::request_info_type Dot11ManagementFrame::request_informatio
return output;
}
Dot11ManagementFrame::fh_params_set Dot11ManagementFrame::fh_parameter_set() const {
const Dot11::Dot11Option *option = search_option(FH_SET);
if(!option || option->data_size() != sizeof(fh_params_set))
throw std::runtime_error("FH parameters set not set");
fh_params_set output = *reinterpret_cast<const fh_params_set*>(option->data_ptr());
output.dwell_time = Utils::le_to_host(output.dwell_time);
output.hop_set = Utils::le_to_host(output.hop_set);
output.hop_pattern = Utils::le_to_host(output.hop_pattern);
output.hop_index = Utils::le_to_host(output.hop_index);
return output;
}
uint8_t Dot11ManagementFrame::ds_parameter_set() const {
const Dot11::Dot11Option *option = search_option(DS_SET);
if(!option || option->data_size() != sizeof(uint8_t))
throw std::runtime_error("DS parameters set not set");
return *option->data_ptr();
}
uint16_t Dot11ManagementFrame::ibss_parameter_set() const {
const Dot11::Dot11Option *option = search_option(IBSS_SET);
if(!option || option->data_size() != sizeof(uint16_t))
throw std::runtime_error("IBSS parameters set not set");
return Utils::le_to_host(*reinterpret_cast<const uint16_t*>(option->data_ptr()));
}
Dot11ManagementFrame::ibss_dfs_params Dot11ManagementFrame::ibss_dfs() const {
const Dot11::Dot11Option *option = search_option(IBSS_DFS);
if(!option || option->data_size() < ibss_dfs_params::minimum_size)
throw std::runtime_error("IBSS DFS set not set");
ibss_dfs_params output;
const uint8_t *ptr = option->data_ptr(), *end = ptr + option->data_size();
output.dfs_owner = ptr;
ptr += output.dfs_owner.size();
output.recovery_interval = *(ptr++);
while(ptr != end) {
uint8_t first = *(ptr++);
if(ptr == end)
throw std::runtime_error("Malformed channel data");
output.channel_map.push_back(std::make_pair(first, *(ptr++)));
}
return output;
}
/* Dot11Beacon */
Dot11Beacon::Dot11Beacon(const NetworkInterface& iface,

View File

@@ -239,3 +239,43 @@ TEST_F(Dot11BeaconTest, RequestInformation) {
ASSERT_EQ(info.size(), found_info.size());
EXPECT_TRUE(std::equal(info.begin(), info.end(), found_info.begin()));
}
TEST_F(Dot11BeaconTest, FHParameterSet) {
Dot11Beacon dot11;
Dot11Beacon::fh_params_set params(0x482f, 67, 42, 0xa1), output;
dot11.fh_parameter_set(params);
output = dot11.fh_parameter_set();
EXPECT_EQ(output.hop_index, params.hop_index);
EXPECT_EQ(output.hop_pattern, params.hop_pattern);
EXPECT_EQ(output.hop_set, params.hop_set);
EXPECT_EQ(output.dwell_time, params.dwell_time);
}
TEST_F(Dot11BeaconTest, DSParameterSet) {
Dot11Beacon dot11;
dot11.ds_parameter_set(0x1e);
EXPECT_EQ(dot11.ds_parameter_set(), 0x1e);
}
TEST_F(Dot11BeaconTest, IBSSParameterSet) {
Dot11Beacon dot11;
dot11.ibss_parameter_set(0x1ef3);
EXPECT_EQ(dot11.ibss_parameter_set(), 0x1ef3);
}
TEST_F(Dot11BeaconTest, IBSS_DFS) {
Dot11Beacon dot11;
Dot11Beacon::ibss_dfs_params params, output;
params.dfs_owner = "00:01:02:03:04:05";
params.recovery_interval = 0x7f;
params.channel_map.push_back(std::make_pair(0x8e, 0x92));
params.channel_map.push_back(std::make_pair(0x02, 0xf2));
params.channel_map.push_back(std::make_pair(0x3a, 0x53));
dot11.ibss_dfs(params);
output = dot11.ibss_dfs();
EXPECT_EQ(params.dfs_owner, output.dfs_owner);
EXPECT_EQ(params.recovery_interval, output.recovery_interval);
ASSERT_EQ(params.channel_map.size(), output.channel_map.size());
EXPECT_TRUE(std::equal(params.channel_map.begin(), params.channel_map.end(), output.channel_map.begin()));
}