1
0
mirror of https://github.com/mfontanini/libtins synced 2026-01-23 02:35:57 +01:00

Done minor modifications.

This commit is contained in:
Matias Fontanini
2012-03-06 08:31:10 -03:00
parent d2f6862b7b
commit 53dfad8bf2
5 changed files with 120 additions and 40 deletions

View File

@@ -41,6 +41,11 @@ namespace Tins {
* \brief Broadcast hardware address.
*/
static const uint8_t *BROADCAST;
/**
* \brief Dot11 address size.
*/
static const uint32_t ADDR_SIZE = 6;
/**
* \brief Enum for the different types of 802.11 frames.
@@ -147,22 +152,12 @@ namespace Tins {
/**
* \brief IEEE 802.11 options struct.
*/
struct Dot11_Option {
struct Dot11Option {
friend class Dot11;
friend class Dot11Beacon;
friend class Dot11ManagementFrame;
/**
* \brief The option number.
*/
uint8_t option;
/**
* \brief The value's length in bytes.
*/
uint8_t length;
/**
* \brief The option's value.
*/
uint8_t *value;
/**
* \brief Creates an instance of Dot11_Option.
* \brief Creates an instance of Dot11Option.
*
* The option's value is copied, therefore the user should
* manually free any memory pointed by the "val" parameter.
@@ -170,7 +165,31 @@ namespace Tins {
* \param len The length of the option's value in bytes.
* \param val The option's value.
*/
Dot11_Option(uint8_t opt, uint8_t len, const uint8_t *val);
Dot11Option(uint8_t opt, uint8_t len, const uint8_t *val);
/**
* \brief Getter for Dot11 options' data pointer.
*/
const uint8_t* data_ptr() const { return value; }
/**
* \brief Getter for the data size field
*/
uint8_t data_size() const { return length; }
/**
* \brief The option number.
*/
uint8_t option;
private:
/**
* \brief The value's length in bytes.
*/
uint8_t length;
/**
* \brief The option's value.
*/
uint8_t *value;
};
/**
@@ -450,7 +469,7 @@ namespace Tins {
* \param opt The option identifier.
* \return The option found, or 0 if no such option has been set.
*/
const Dot11_Option *lookup_option(TaggedOption opt) const;
const Dot11Option *search_option(TaggedOption opt) const;
/**
* \brief Getter for the PDU's type.
@@ -512,7 +531,7 @@ namespace Tins {
#endif
} __attribute__((__packed__)) control;
uint16_t duration_id;
uint8_t addr1[6];
uint8_t addr1[ADDR_SIZE];
} __attribute__((__packed__));
private:
@@ -524,7 +543,7 @@ namespace Tins {
ieee80211_header _header;
uint32_t _iface_index, _options_size;
std::list<Dot11_Option> _options;
std::list<Dot11Option> _options;
};
/**

View File

@@ -89,6 +89,7 @@ namespace Tins {
* \brief This class represents an IP option.
*/
struct IPOption {
friend class IP;
struct {
#if __BYTE_ORDER == __LITTLE_ENDIAN
unsigned int number:5;
@@ -100,10 +101,20 @@ namespace Tins {
unsigned int number:5;
#endif
} type;
uint8_t* optional_data;
uint32_t optional_data_size;
uint8_t* write(uint8_t* buffer);
/**
* \brief Getter for IP options' data pointer.
*/
const uint8_t* data_ptr() const;
/**
* \brief Getter for the data size field
*/
uint8_t data_size() const;
private:
uint8_t* optional_data, optional_data_size;
} __attribute__((__packed__));
/**

View File

@@ -40,13 +40,12 @@
using namespace std;
const uint8_t *Tins::Dot11::BROADCAST = (const uint8_t*)"\xff\xff\xff\xff\xff\xff";
const uint32_t Tins::Dot11::ADDR_SIZE;
Tins::Dot11::Dot11(const uint8_t* dst_hw_addr, PDU* child) : PDU(ETHERTYPE_IP, child), _options_size(0) {
memset(&this->_header, 0, sizeof(ieee80211_header));
if(dst_hw_addr) {
if(dst_hw_addr)
this->addr1(dst_hw_addr);
}
}
Tins::Dot11::Dot11(const std::string& iface, const uint8_t* dst_hw_addr, PDU* child) throw (std::runtime_error) : PDU(ETHERTYPE_IP, child), _options_size(0) {
@@ -109,19 +108,19 @@ void Tins::Dot11::parse_tagged_parameters(const uint8_t *buffer, uint32_t total_
}
}
Tins::Dot11::Dot11_Option::Dot11_Option(uint8_t opt, uint8_t len, const uint8_t *val) : option(opt), length(len) {
Tins::Dot11::Dot11Option::Dot11Option(uint8_t opt, uint8_t len, const uint8_t *val) : option(opt), length(len) {
value = new uint8_t[len];
std::memcpy(value, val, len);
}
void Tins::Dot11::add_tagged_option(TaggedOption opt, uint8_t len, const uint8_t *val) {
uint32_t opt_size = len + (sizeof(uint8_t) << 1);
_options.push_back(Dot11_Option((uint8_t)opt, len, val));
_options.push_back(Dot11Option((uint8_t)opt, len, val));
_options_size += opt_size;
}
const Tins::Dot11::Dot11_Option *Tins::Dot11::lookup_option(TaggedOption opt) const {
for(std::list<Dot11_Option>::const_iterator it = _options.begin(); it != _options.end(); ++it)
const Tins::Dot11::Dot11Option *Tins::Dot11::search_option(TaggedOption opt) const {
for(std::list<Dot11Option>::const_iterator it = _options.begin(); it != _options.end(); ++it)
if(it->option == (uint8_t)opt)
return &(*it);
return 0;
@@ -218,7 +217,7 @@ void Tins::Dot11::write_serialization(uint8_t *buffer, uint32_t total_sz, const
uint32_t child_len = write_fixed_parameters(buffer, total_sz - _options_size);
buffer += child_len;
assert(total_sz >= child_len + _options_size);
for(std::list<Dot11_Option>::const_iterator it = _options.begin(); it != _options.end(); ++it) {
for(std::list<Dot11Option>::const_iterator it = _options.begin(); it != _options.end(); ++it) {
*(buffer++) = it->option;
*(buffer++) = it->length;
std::memcpy(buffer, it->value, it->length);
@@ -268,8 +267,8 @@ void Tins::Dot11::copy_80211_fields(const Dot11 *other) {
std::memcpy(&_header, &other->_header, sizeof(_header));
_iface_index = other->_iface_index;
_options_size = other->_options_size;
for(std::list<Dot11_Option>::const_iterator it = other->_options.begin(); it != other->_options.end(); ++it)
_options.push_back(Dot11_Option(it->option, it->length, it->value));
for(std::list<Dot11Option>::const_iterator it = other->_options.begin(); it != other->_options.end(); ++it)
_options.push_back(Dot11Option(it->option, it->length, it->value));
}
/* Dot11ManagementFrame */
@@ -753,12 +752,12 @@ void Tins::Dot11Beacon::qos_capabilities(uint8_t qos_info) {
}
string Tins::Dot11Beacon::essid() const {
const Dot11::Dot11_Option *option = lookup_option(SSID);
const Dot11::Dot11Option *option = search_option(SSID);
return (option) ? string((const char*)option->value, option->length) : 0;
}
bool Tins::Dot11Beacon::rsn_information(RSNInformation *rsn) {
const Dot11::Dot11_Option *option = lookup_option(RSN);
const Dot11::Dot11Option *option = search_option(RSN);
if(!option || option->length < (sizeof(uint16_t) << 1) + sizeof(uint32_t))
return false;
const uint8_t *buffer = option->value;

View File

@@ -246,8 +246,10 @@ void Tins::IP::set_option(uint8_t copied,
option.type.number = number;
uint8_t* buffer(0);
if (data_size) {
buffer = new uint8_t[data_size];
memcpy(buffer, data, data_size);
buffer = new uint8_t[data_size + 1];
buffer[0] = data_size;
memcpy(buffer + 1, data, data_size);
data_size++;
}
option.optional_data = buffer;
option.optional_data_size = data_size;
@@ -275,6 +277,14 @@ uint8_t* Tins::IP::IPOption::write(uint8_t* buffer) {
return buffer;
}
const uint8_t* Tins::IP::IPOption::data_ptr() const {
return optional_data ? optional_data + 1 : 0;
}
uint8_t Tins::IP::IPOption::data_size() const {
return optional_data_size ? optional_data_size - 1 : 0;
}
/* Virtual method overriding. */
uint32_t Tins::IP::header_size() const {
@@ -318,7 +328,7 @@ void Tins::IP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU
this->flag(new_flag);
}
this->tot_len(total_sz);
this->head_len (my_sz / sizeof(uint32_t));
this->head_len(my_sz / sizeof(uint32_t));
memcpy(buffer, &_ip, sizeof(_ip));

View File

@@ -12,9 +12,14 @@ class IPTest : public testing::Test {
public:
static const uint8_t expected_packet[];
void test_equals(const IP &tcp1, const IP &tcp2);
void test_equals(const IP &ip1, const IP &ip2);
};
const uint8_t IPTest::expected_packet[] = { '(', '\x7f', '\x00', ' ',
'\x00', 'z', '\x00', 'C', '\x15', '\x01', '\xfb', 'g', 'T', '4', '\xfe',
'\x05', '\xc0', '\xa8', '\t', '+', '\x82', '\x0b', 't', 'j', 'g', '\xab',
'w', '\xab', 'h', 'e', 'l', '\x00' };
TEST_F(IPTest, DefaultConstructor) {
IP ip;
@@ -128,6 +133,42 @@ TEST_F(IPTest, SecOption) {
ip.set_sec_option(data, sizeof(data));
const IP::IPOption *option;
ASSERT_TRUE((option = ip.search_option(IP::CONTROL, IP::SEC)));
ASSERT_EQ(option->optional_data_size, sizeof(data));
EXPECT_TRUE(memcmp(option->optional_data, data, sizeof(data)) == 0);
ASSERT_EQ(option->data_size(), sizeof(data));
EXPECT_TRUE(memcmp(option->data_ptr(), data, sizeof(data)) == 0);
}
void IPTest::test_equals(const IP &ip1, const IP &ip2) {
EXPECT_EQ(ip1.dst_addr(), ip2.dst_addr());
EXPECT_EQ(ip1.src_addr(), ip2.src_addr());
EXPECT_EQ(ip1.id(), ip2.id());
EXPECT_EQ(ip1.frag_off(), ip2.frag_off());
EXPECT_EQ(ip1.tos(), ip2.tos());
EXPECT_EQ(ip1.ttl(), ip2.ttl());
EXPECT_EQ(ip1.version(), ip2.version());
}
TEST_F(IPTest, ConstructorFromBuffer) {
IP ip1(expected_packet, sizeof(expected_packet));
const uint8_t opt_sec[] = { 't', 'j', 'g', '\xab', 'w', '\xab', 'h', 'e', 'l' };
EXPECT_EQ(ip1.dst_addr(), Utils::ip_to_int("192.168.9.43"));
EXPECT_EQ(ip1.src_addr(), Utils::ip_to_int("84.52.254.5"));
EXPECT_EQ(ip1.id(), 0x7a);
EXPECT_EQ(ip1.tos(), 0x7f);
EXPECT_EQ(ip1.frag_off(), 0x43);
EXPECT_EQ(ip1.protocol(), 1);
EXPECT_EQ(ip1.ttl(), 0x15);
EXPECT_EQ(ip1.version(), 2);
const IP::IPOption *option;
ASSERT_TRUE((option = ip1.search_option(IP::CONTROL, IP::SEC)));
EXPECT_EQ(option->type.number, IP::SEC);
EXPECT_EQ(option->type.op_class, IP::CONTROL);
ASSERT_EQ(option->data_size(), sizeof(opt_sec));
EXPECT_TRUE(memcmp(option->data_ptr(), opt_sec, sizeof(opt_sec)) == 0);
uint32_t size;
uint8_t *buffer = ip1.serialize(size);
ASSERT_TRUE(buffer);
IP ip2(buffer, size);
}