mirror of
https://github.com/mfontanini/libtins
synced 2026-01-23 02:35:57 +01:00
Add support for XChannel field on RadioTap
This commit is contained in:
@@ -84,7 +84,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
enum PresentFlags {
|
enum PresentFlags {
|
||||||
TSFT = 1 << 0,
|
TSFT = 1 << 0,
|
||||||
TSTF = 1 << 0, // Deprecated (typo in the name...)
|
TSTF = 1 << 0, ///< Deprecated (typo), use TSFT
|
||||||
FLAGS = 1 << 1,
|
FLAGS = 1 << 1,
|
||||||
RATE = 1 << 2,
|
RATE = 1 << 2,
|
||||||
CHANNEL = 1 << 3,
|
CHANNEL = 1 << 3,
|
||||||
@@ -101,6 +101,7 @@ public:
|
|||||||
RX_FLAGS = 1 << 14,
|
RX_FLAGS = 1 << 14,
|
||||||
TX_FLAGS = 1 << 15,
|
TX_FLAGS = 1 << 15,
|
||||||
DATA_RETRIES = 1 << 17,
|
DATA_RETRIES = 1 << 17,
|
||||||
|
XCHANNEL = 1 << 18,
|
||||||
CHANNEL_PLUS = 1 << 18,
|
CHANNEL_PLUS = 1 << 18,
|
||||||
MCS = 1 << 19
|
MCS = 1 << 19
|
||||||
};
|
};
|
||||||
@@ -128,6 +129,17 @@ public:
|
|||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
uint8_t mcs;
|
uint8_t mcs;
|
||||||
} TINS_END_PACK;
|
} TINS_END_PACK;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief The type used to represent the XChannel field
|
||||||
|
*/
|
||||||
|
TINS_BEGIN_PACK
|
||||||
|
struct xchannel_type {
|
||||||
|
uint32_t flags;
|
||||||
|
uint16_t frequency;
|
||||||
|
uint8_t channel;
|
||||||
|
uint8_t max_power;
|
||||||
|
} TINS_END_PACK;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type used to store RadioTap options
|
* The type used to store RadioTap options
|
||||||
@@ -250,6 +262,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
void tx_flags(uint16_t new_tx_flag);
|
void tx_flags(uint16_t new_tx_flag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Setter for the xchannel field.
|
||||||
|
* \param new_xchannel The xchannel field
|
||||||
|
*/
|
||||||
|
void xchannel(xchannel_type new_xchannel);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Setter for the data retries field.
|
* \brief Setter for the data retries field.
|
||||||
* \param new_rx_flag The data retries.
|
* \param new_rx_flag The data retries.
|
||||||
@@ -343,10 +361,10 @@ public:
|
|||||||
uint8_t db_signal() const;
|
uint8_t db_signal() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Getter for the channel+ field.
|
* \brief Getter for the XChannel field.
|
||||||
* \return The channel+ field.
|
* \return The XChannel field.
|
||||||
*/
|
*/
|
||||||
uint32_t channel_plus() const;
|
xchannel_type xchannel() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Getter for the data retries field
|
* \brief Getter for the data retries field
|
||||||
|
|||||||
@@ -180,6 +180,14 @@ void RadioTap::tx_flags(uint16_t new_tx_flags) {
|
|||||||
add_integral_option(*this, TX_FLAGS, new_tx_flags);
|
add_integral_option(*this, TX_FLAGS, new_tx_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RadioTap::xchannel(xchannel_type new_xchannel) {
|
||||||
|
uint8_t buffer[sizeof(new_xchannel)];
|
||||||
|
new_xchannel.flags = Endian::host_to_le(new_xchannel.flags);
|
||||||
|
new_xchannel.frequency = Endian::host_to_le(new_xchannel.frequency);
|
||||||
|
memcpy(buffer, &new_xchannel, sizeof(new_xchannel));
|
||||||
|
add_option(RadioTap::option(XCHANNEL, sizeof(buffer), buffer));
|
||||||
|
}
|
||||||
|
|
||||||
void RadioTap::mcs(const mcs_type& new_mcs) {
|
void RadioTap::mcs(const mcs_type& new_mcs) {
|
||||||
uint8_t buffer[sizeof(new_mcs)];
|
uint8_t buffer[sizeof(new_mcs)];
|
||||||
memcpy(buffer, &new_mcs, sizeof(new_mcs));
|
memcpy(buffer, &new_mcs, sizeof(new_mcs));
|
||||||
@@ -279,7 +287,7 @@ uint8_t RadioTap::antenna() const {
|
|||||||
RadioTap::mcs_type RadioTap::mcs() const {
|
RadioTap::mcs_type RadioTap::mcs() const {
|
||||||
const option opt = do_find_option(MCS);
|
const option opt = do_find_option(MCS);
|
||||||
mcs_type output;
|
mcs_type output;
|
||||||
memcpy(&output, opt.data_ptr(), sizeof(mcs_type));
|
memcpy(&output, opt.data_ptr(), sizeof(output));
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,13 +295,13 @@ uint8_t RadioTap::db_signal() const {
|
|||||||
return do_find_option(DB_SIGNAL).to<uint8_t>();
|
return do_find_option(DB_SIGNAL).to<uint8_t>();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t RadioTap::channel_plus() const {
|
RadioTap::xchannel_type RadioTap::xchannel() const {
|
||||||
/*if (!header_.flags.channel_plus) {
|
const option opt = do_find_option(XCHANNEL);
|
||||||
throw field_not_present();
|
xchannel_type output;
|
||||||
}
|
memcpy(&output, opt.data_ptr(), sizeof(output));
|
||||||
return Endian::le_to_host<uint32_t>(channel_type_);*/
|
output.flags = Endian::le_to_host(output.flags);
|
||||||
// TODO: wat
|
output.frequency = Endian::le_to_host(output.frequency);
|
||||||
return 0xdadedade;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t RadioTap::rx_flags() const {
|
uint16_t RadioTap::rx_flags() const {
|
||||||
@@ -355,19 +363,6 @@ void RadioTap::write_serialization(uint8_t* buffer, uint32_t total_sz) {
|
|||||||
header_.it_len = Endian::host_to_le<uint16_t>(header_size());
|
header_.it_len = Endian::host_to_le<uint16_t>(header_size());
|
||||||
stream.write(header_);
|
stream.write(header_);
|
||||||
stream.write(options_payload_.begin(), options_payload_.end());
|
stream.write(options_payload_.begin(), options_payload_.end());
|
||||||
/*if (header_.flags.channel_plus) {
|
|
||||||
const uint32_t padding = ((stream.pointer() - buffer_start) % 4);
|
|
||||||
if (padding != 0) {
|
|
||||||
stream.fill(4 - padding, 0);
|
|
||||||
}
|
|
||||||
uint32_t dummy = channel_type_;
|
|
||||||
// nasty Big Endian fix
|
|
||||||
dummy = Endian::le_to_host<uint32_t>(Endian::host_to_le<uint16_t>(dummy));
|
|
||||||
stream.write(dummy);
|
|
||||||
stream.write(channel_freq_);
|
|
||||||
stream.write(channel_);
|
|
||||||
stream.write(max_power_);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// If we have a trailer size, then we have the FCS flag on
|
// If we have a trailer size, then we have the FCS flag on
|
||||||
if (trailer_size() > 0 && inner_pdu()) {
|
if (trailer_size() > 0 && inner_pdu()) {
|
||||||
|
|||||||
@@ -346,7 +346,7 @@ TEST_F(RadioTapTest, ConstructorFromBuffer) {
|
|||||||
EXPECT_TRUE((radio.present() & RadioTap::RATE) != 0);
|
EXPECT_TRUE((radio.present() & RadioTap::RATE) != 0);
|
||||||
EXPECT_TRUE((radio.present() & RadioTap::DBM_SIGNAL) != 0);
|
EXPECT_TRUE((radio.present() & RadioTap::DBM_SIGNAL) != 0);
|
||||||
EXPECT_TRUE((radio.present() & RadioTap::ANTENNA) != 0);
|
EXPECT_TRUE((radio.present() & RadioTap::ANTENNA) != 0);
|
||||||
EXPECT_TRUE((radio.present() & RadioTap::CHANNEL_PLUS) != 0);
|
EXPECT_TRUE((radio.present() & RadioTap::XCHANNEL) != 0);
|
||||||
|
|
||||||
EXPECT_TRUE((radio.flags() & RadioTap::FCS) != 0);
|
EXPECT_TRUE((radio.flags() & RadioTap::FCS) != 0);
|
||||||
EXPECT_THROW(radio.channel_type(), field_not_present);
|
EXPECT_THROW(radio.channel_type(), field_not_present);
|
||||||
@@ -507,6 +507,22 @@ TEST_F(RadioTapTest, TSFT) {
|
|||||||
EXPECT_EQ(radio.tsft(), 0x7afb9a8dU);
|
EXPECT_EQ(radio.tsft(), 0x7afb9a8dU);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(RadioTapTest, XChannel) {
|
||||||
|
RadioTap radio;
|
||||||
|
RadioTap::xchannel_type xchannel;
|
||||||
|
xchannel.flags = 0xabcd1234;
|
||||||
|
xchannel.frequency = 0xda21;
|
||||||
|
xchannel.max_power = 0x19;
|
||||||
|
xchannel.channel = 0x99;
|
||||||
|
radio.xchannel(xchannel);
|
||||||
|
|
||||||
|
RadioTap::xchannel_type found_xchannel = radio.xchannel();
|
||||||
|
EXPECT_EQ(xchannel.flags, found_xchannel.flags);
|
||||||
|
EXPECT_EQ(xchannel.frequency, found_xchannel.frequency);
|
||||||
|
EXPECT_EQ(xchannel.max_power, found_xchannel.max_power);
|
||||||
|
EXPECT_EQ(xchannel.channel, found_xchannel.channel);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(RadioTapTest, SerializationWorksFine) {
|
TEST_F(RadioTapTest, SerializationWorksFine) {
|
||||||
const uint8_t expected[] = {
|
const uint8_t expected[] = {
|
||||||
0, 0, 26, 0, 43, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 108,
|
0, 0, 26, 0, 43, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 108,
|
||||||
@@ -555,7 +571,7 @@ TEST_F(RadioTapTest, RadioTapParsing) {
|
|||||||
EXPECT_EQ(2, parser.current_option().to<uint8_t>());
|
EXPECT_EQ(2, parser.current_option().to<uint8_t>());
|
||||||
EXPECT_TRUE(parser.advance_field());
|
EXPECT_TRUE(parser.advance_field());
|
||||||
|
|
||||||
EXPECT_EQ(RadioTap::CHANNEL_PLUS,parser.current_field());
|
EXPECT_EQ(RadioTap::XCHANNEL,parser.current_field());
|
||||||
EXPECT_EQ(0x1124143c00000140ULL, parser.current_option().to<uint64_t>());
|
EXPECT_EQ(0x1124143c00000140ULL, parser.current_option().to<uint64_t>());
|
||||||
|
|
||||||
EXPECT_FALSE(parser.advance_field());
|
EXPECT_FALSE(parser.advance_field());
|
||||||
|
|||||||
Reference in New Issue
Block a user