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

Added a generic PDUOption class. TCP, IP, DHCP and Dot11* now use this class to store their options.

This commit is contained in:
Matias Fontanini
2012-09-10 00:11:54 -03:00
parent 83ec6e6bad
commit c49fbe9929
14 changed files with 924 additions and 646 deletions

View File

@@ -1,7 +1,8 @@
src/arp.o: src/arp.cpp include/arp.h include/pdu.h include/endianness.h \
include/hwaddress.h include/ipaddress.h include/ip.h \
include/small_uint.h include/ethernetII.h include/network_interface.h \
include/rawpdu.h include/constants.h include/network_interface.h
include/small_uint.h include/pdu_option.h include/ethernetII.h \
include/network_interface.h include/rawpdu.h include/constants.h \
include/network_interface.h
include/arp.h:
@@ -17,6 +18,8 @@ include/ip.h:
include/small_uint.h:
include/pdu_option.h:
include/ethernetII.h:
include/network_interface.h:
@@ -126,7 +129,7 @@ include/rsn_information.h:
src/ethernetII.o: src/ethernetII.cpp include/ethernetII.h include/pdu.h \
include/endianness.h include/hwaddress.h include/network_interface.h \
include/ipaddress.h include/packet_sender.h include/rawpdu.h \
include/ip.h include/small_uint.h include/arp.h
include/ip.h include/small_uint.h include/pdu_option.h include/arp.h
include/ethernetII.h:
@@ -148,6 +151,8 @@ include/ip.h:
include/small_uint.h:
include/pdu_option.h:
include/arp.h:
src/icmp.o: src/icmp.cpp include/icmp.h include/pdu.h \
include/endianness.h include/rawpdu.h include/utils.h \
@@ -192,9 +197,10 @@ include/ipaddress.h:
include/endianness.h:
src/ip.o: src/ip.cpp include/ip.h include/pdu.h include/small_uint.h \
include/endianness.h include/ipaddress.h include/tcp.h include/udp.h \
include/icmp.h include/rawpdu.h include/utils.h include/hwaddress.h \
include/packet_sender.h include/constants.h
include/endianness.h include/ipaddress.h include/pdu_option.h \
include/tcp.h include/udp.h include/icmp.h include/rawpdu.h \
include/utils.h include/hwaddress.h include/packet_sender.h \
include/constants.h
include/ip.h:
@@ -206,6 +212,8 @@ include/endianness.h:
include/ipaddress.h:
include/pdu_option.h:
include/tcp.h:
include/udp.h:
@@ -306,7 +314,7 @@ include/endianness.h:
src/snap.o: src/snap.cpp include/snap.h include/pdu.h \
include/endianness.h include/small_uint.h include/constants.h \
include/arp.h include/hwaddress.h include/ipaddress.h include/ip.h \
include/eapol.h
include/pdu_option.h include/eapol.h
include/snap.h:
@@ -326,6 +334,8 @@ include/ipaddress.h:
include/ip.h:
include/pdu_option.h:
include/eapol.h:
src/sniffer.o: src/sniffer.cpp include/sniffer.h include/pdu.h \
include/ethernetII.h include/endianness.h include/hwaddress.h \
@@ -347,8 +357,9 @@ include/ipaddress.h:
include/radiotap.h:
src/tcp.o: src/tcp.cpp include/tcp.h include/pdu.h include/endianness.h \
include/small_uint.h include/ip.h include/ipaddress.h \
include/constants.h include/rawpdu.h include/utils.h include/hwaddress.h
include/small_uint.h include/pdu_option.h include/ip.h \
include/ipaddress.h include/constants.h include/rawpdu.h include/utils.h \
include/hwaddress.h
include/tcp.h:
@@ -358,6 +369,8 @@ include/endianness.h:
include/small_uint.h:
include/pdu_option.h:
include/ip.h:
include/ipaddress.h:
@@ -373,7 +386,7 @@ src/tcp_stream.o: src/tcp_stream.cpp include/rawpdu.h include/pdu.h \
include/tcp_stream.h include/sniffer.h include/ethernetII.h \
include/endianness.h include/hwaddress.h include/network_interface.h \
include/ipaddress.h include/radiotap.h include/tcp.h \
include/small_uint.h include/ip.h
include/small_uint.h include/pdu_option.h include/ip.h
include/rawpdu.h:
@@ -399,10 +412,13 @@ include/tcp.h:
include/small_uint.h:
include/pdu_option.h:
include/ip.h:
src/udp.o: src/udp.cpp include/udp.h include/pdu.h include/endianness.h \
include/constants.h include/utils.h include/ipaddress.h \
include/hwaddress.h include/ip.h include/small_uint.h include/rawpdu.h
include/hwaddress.h include/ip.h include/small_uint.h \
include/pdu_option.h include/rawpdu.h
include/udp.h:
@@ -422,11 +438,14 @@ include/ip.h:
include/small_uint.h:
include/pdu_option.h:
include/rawpdu.h:
src/utils.o: src/utils.cpp include/utils.h include/ipaddress.h \
include/hwaddress.h include/pdu.h include/ip.h include/pdu.h \
include/small_uint.h include/endianness.h include/icmp.h include/arp.h \
include/endianness.h include/network_interface.h include/packet_sender.h
include/small_uint.h include/endianness.h include/pdu_option.h \
include/icmp.h include/arp.h include/endianness.h \
include/network_interface.h include/packet_sender.h
include/utils.h:
@@ -444,6 +463,8 @@ include/small_uint.h:
include/endianness.h:
include/pdu_option.h:
include/icmp.h:
include/arp.h:

View File

@@ -24,9 +24,9 @@
#include <list>
#include <vector>
#include <string>
#include "bootp.h"
#include "pdu_option.h"
namespace Tins {
class IPv4Address;
@@ -133,34 +133,15 @@ namespace Tins {
END = 255
};
/**
* \brief DHCP options struct.
/**
* The DHCP option type.
*/
struct DHCPOption {
/**
* \brief Creates an instance of DHCPOption.
*
* The option's value is copied, therefore the user should
* manually free any memory pointed by the "val" parameter.
* \param opt The option number.
* \param len The length of the option's value in bytes.
* \param val The option's value.
*/
DHCPOption(uint8_t opt, uint8_t len = 0, const uint8_t *val = 0);
/**
* \brief The option number.
*/
uint8_t option;
/**
* \brief The option's value.
*/
std::vector<uint8_t> value;
};
typedef PDUOption<uint8_t> dhcp_option;
typedef std::list<DHCPOption> options_type;
/**
* The type used to store the DHCP options.
*/
typedef std::list<dhcp_option> options_type;
/**
* \brief Creates an instance of DHCP.
@@ -181,29 +162,22 @@ namespace Tins {
/**
* \brief Adds a new option to this DHCP PDU.
*
* This copies the value buffer. Adding options may fail if
* there's not enough size to hold a new option.
* \param opt The option identifier.
* \param len The length of the value field.
* \param val The value of this option.
* \return True if the option was added successfully.
* \param option The option to be added.
*/
bool add_option(Options opt, uint8_t len, const uint8_t *val);
void add_option(const dhcp_option &option);
/**
* \brief Searchs for an option that matchs the given flag.
* \param opt_flag The flag to be searched.
* \return A pointer to the option, or 0 if it was not found.
*/
const DHCPOption *search_option(Options opt) const;
const dhcp_option *search_option(Options opt) const;
/**
* \brief Adds a type option the the option list.
* \param type The type of this DHCP PDU.
* \return True if the option was added successfully. \sa DHCP::add_option
*/
bool add_type_option(Flags type);
void type(Flags type);
/**
* \brief Adds an end option the the option list.
@@ -211,157 +185,182 @@ namespace Tins {
* The END option is not added automatically. You should explicitly
* add it at the end of the DHCP options for the PDU to be
* standard-compliant.
*
* \return True if the option was added successfully. \sa DHCP::add_option
*/
bool add_end_option();
/**
* \brief Searchs for a type option.
* \param value A pointer in which the option's value will be stored.
* \return True if the option was found, false otherwise.
*/
bool search_type_option(uint8_t *value);
void end();
/**
* \brief Adds a server identifier option.
* \param ip The ip of the server.
* \return True if the option was added successfully. \sa DHCP::add_option
*/
bool add_server_identifier(ipaddress_type ip);
/**
* \brief Searchs for a server identifier option.
* \param value A pointer in which the option's value will be stored.
* \return True if the option was found, false otherwise.
*/
bool search_server_identifier(ipaddress_type *value);
void server_identifier(ipaddress_type ip);
/**
* \brief Adds an IP address lease time option.
* \param time The lease time.
* \return True if the option was added successfully. \sa DHCP::add_option
*/
bool add_lease_time(uint32_t time);
/**
* \brief Searchs for a lease time option.
* \param value A pointer in which the option's value will be stored.
* \return True if the option was found, false otherwise.
*/
bool search_lease_time(uint32_t *value);
void lease_time(uint32_t time);
/**
* \brief Adds a lease renewal time option.
* \param time The lease renew time.
* \return True if the option was added successfully. \sa DHCP::add_option
*/
bool add_renewal_time(uint32_t time);
/**
* \brief Searchs for a lease renewal time option.
* \param value A pointer in which the option's value will be stored.
* \return True if the option was found, false otherwise.
*/
bool search_renewal_time(uint32_t *value);
void renewal_time(uint32_t time);
/**
* \brief Adds a rebind time option.
* \param time The lease rebind time.
* \return True if the option was added successfully. \sa DHCP::add_option
*/
bool add_rebind_time(uint32_t time);
/**
* \brief Searchs for a rebind time option.
* \param value A pointer in which the option's value will be stored.
* \return True if the option was found, false otherwise.
*/
bool search_rebind_time(uint32_t *value);
void rebind_time(uint32_t time);
/**
* \brief Adds a subnet mask option.
* \param mask The subnet mask.
* \return True if the option was added successfully. \sa DHCP::add_option
*/
bool add_subnet_mask(ipaddress_type mask);
/**
* \brief Searchs for a subnet mask option.
* \param value A pointer in which the option's value will be stored.
* \return True if the option was found, false otherwise.
*/
bool search_subnet_mask(ipaddress_type *value);
void subnet_mask(ipaddress_type mask);
/**
* \brief Adds a routers option.
* \param routers A list of ip addresses.
* \return True if the option was added successfully. \sa DHCP::add_option
*/
bool add_routers_option(const std::list<ipaddress_type> &routers);
/**
* \brief Searchs for a routers option.
* \param routers A pointer in which the option's value will be stored.
* \return True if the option was found, false otherwise.
*/
bool search_routers_option(std::list<ipaddress_type> *routers);
void routers(const std::list<ipaddress_type> &routers);
/**
* \brief Adds a domain name servers option.
* \param dns A list of ip addresses.
* \return True if the option was added successfully. \sa DHCP::add_option
*/
bool add_dns_option(const std::list<ipaddress_type> &dns);
/**
* \brief Searchs for a dns option.
* \param dns A pointer in which the option's value will be stored.
* \return True if the option was found, false otherwise.
*/
bool search_dns_option(std::list<ipaddress_type> *dns);
void domain_name_servers(const std::list<ipaddress_type> &dns);
/**
* \brief Adds a broadcast address option.
* \param addr The broadcast address.
* \return True if the option was added successfully. \sa DHCP::add_option
*/
bool add_broadcast_option(ipaddress_type addr);
/**
* \brief Searchs for a broadcast option.
* \param value A pointer in which the option's value will be stored.
* \return True if the option was found, false otherwise.
*/
bool search_broadcast_option(ipaddress_type *value);
void broadcast(ipaddress_type addr);
/**
* \brief Adds a requested address option.
* \param addr The requested address.
* \return True if the option was added successfully. \sa DHCP::add_option
*/
bool add_requested_ip_option(ipaddress_type addr);
/**
* \brief Searchs for a requested option.
* \param value A pointer in which the option's value will be stored.
* \return True if the option was found, false otherwise.
*/
bool search_requested_ip_option(ipaddress_type *value);
void requested_ip(ipaddress_type addr);
/**
* \brief Adds a domain name option.
* \param name The domain name.
* \return True if the option was added successfully. \sa DHCP::add_option
*/
bool add_domain_name(const std::string &name);
void domain_name(const std::string &name);
// Option getters
/**
* \brief Searchs for a type option.
*
* If the option is not found, a option_not_found exception
* is thrown.
*
* \return uint8_t containing the type option.
*/
uint8_t type() const;
/**
* \brief Searchs for a server identifier option.
*
* If the option is not found, a option_not_found exception
* is thrown.
*
* \return ipaddress_type Containing the server identifier.
*/
ipaddress_type server_identifier() const;
/**
* \brief Searchs for a lease time option.
*
* If the option is not found, a option_not_found exception
* is thrown.
*
* \return uint32_t Containing the lease time.
*/
uint32_t lease_time() const;
/**
* \brief Searchs for a lease renewal time option.
*
* If the option is not found, a option_not_found exception
* is thrown.
*
* \return uint32_t Containing the renewal time.
*/
uint32_t renewal_time() const;
/**
* \brief Searchs for a rebind time option.
*
* If the option is not found, a option_not_found exception
* is thrown.
*
* \return uint32_t Containing the rebind time.
*/
uint32_t rebind_time() const;
/**
* \brief Searchs for a subnet mask option.
*
* If the option is not found, a option_not_found exception
* is thrown.
*
* \return ipaddress_type Containing the subnet mask.
*/
ipaddress_type subnet_mask() const;
/**
* \brief Searchs for a routers option.
*
* If the option is not found, a option_not_found exception
* is thrown.
*
* \return std::list<ipaddress_type> Containing the routers
* option data.
*/
std::list<ipaddress_type> routers() const;
/**
* \brief Searchs for a dns option.
*
* If the option is not found, a option_not_found exception
* is thrown.
*
* \return std::list<ipaddress_type> Contanining the DNS servers
* provided.
*/
std::list<ipaddress_type> domain_name_servers() const;
/**
* \brief Searchs for a broadcast option.
*
* If the option is not found, a option_not_found exception
* is thrown.
*
* \return ipaddress_type Containing the broadcast address.
*/
ipaddress_type broadcast() const;
/**
* \brief Searchs for a requested option.
*
* If the option is not found, a option_not_found exception
* is thrown.
*
* \return ipaddress_type Containing the requested IP address.
*/
ipaddress_type requested_ip() const;
/**
* \brief Searchs for a domain name option.
* \param value A pointer in which the option's value will be stored.
* \return True if the option was found, false otherwise.
*
* If the option is not found, a option_not_found exception
* is thrown.
*
* \return std::string Containing the domain name.
*/
bool search_domain_name(std::string *value);
std::string domain_name() const;
/** \brief Getter for the options list.
* \return The option list.
@@ -389,25 +388,26 @@ 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>
bool generic_search(Options opt, T *value) {
const DHCPOption *option = search_option(opt);
if(option && option->value.size() == sizeof(T)) {
*value = *(T*)&option->value[0];
return true;
}
return false;
T generic_search(Options opt, type2type<T>) const {
const dhcp_option *option = search_option(opt);
if(option && option->data_size() == sizeof(T))
return *(const T*)option->data_ptr();
else
throw option_not_found();
}
bool generic_search(Options opt, std::list<ipaddress_type> *container);
bool generic_search(Options opt, std::string *str);
bool generic_search(Options opt, uint32_t *value);
bool generic_search(Options opt, ipaddress_type *value);
std::list<ipaddress_type> generic_search(Options opt, type2type<std::list<ipaddress_type> >) const;
std::string generic_search(Options opt, type2type<std::string>) const;
ipaddress_type generic_search(Options opt, type2type<ipaddress_type>) const;
uint8_t *serialize_list(const std::list<ipaddress_type> &ip_list, uint32_t &sz);
serialization_type serialize_list(const std::list<ipaddress_type> &ip_list);
options_type _options;
uint32_t _size;

View File

@@ -31,6 +31,7 @@
#include "endianness.h"
#include "hwaddress.h"
#include "small_uint.h"
#include "pdu_option.h"
#include "network_interface.h"
namespace Tins {
@@ -158,39 +159,7 @@ namespace Tins {
/**
* \brief IEEE 802.11 options struct.
*/
struct Dot11Option {
friend class Dot11;
friend class Dot11Beacon;
friend class Dot11ManagementFrame;
/**
* \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.
* \param opt The option number.
* \param len The length of the option's value in bytes.
* \param val The option's value.
*/
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[0]; }
/**
* \brief Getter for the data size field
*/
uint8_t data_size() const { return value.size(); }
/**
* \brief Getter for the data size field
*/
uint8_t option() const { return option_id; }
private:
uint8_t option_id;
std::vector<uint8_t> value;
};
typedef PDUOption<uint8_t> dot11_option;
/**
* \brief Constructor for creating an 802.11 PDU
@@ -425,7 +394,7 @@ namespace Tins {
* \param opt The option identifier.
* \return The option found, or 0 if no such option has been set.
*/
const Dot11Option *search_option(TaggedOption opt) const;
const dot11_option *search_option(TaggedOption opt) const;
/**
* \brief Getter for the PDU's type.
@@ -506,7 +475,7 @@ namespace Tins {
ieee80211_header _header;
NetworkInterface _iface;
uint32_t _options_size;
std::list<Dot11Option> _options;
std::list<dot11_option> _options;
};
/**
@@ -1479,7 +1448,7 @@ namespace Tins {
}
private:
static uint8_t *serialize_rates(const rates_type &rates);
static rates_type deserialize_rates(const Dot11Option *option);
static rates_type deserialize_rates(const dot11_option *option);
ExtendedHeader _ext_header;
address_type _addr4;

View File

@@ -27,6 +27,7 @@
#include "small_uint.h"
#include "endianness.h"
#include "ipaddress.h"
#include "pdu_option.h"
namespace Tins {
@@ -65,7 +66,7 @@ namespace Tins {
*
* Enum Option indicates the possible IP Options.
*/
enum Option {
enum OptionNumber {
END = 0,
NOOP = 1,
SEC = 2,
@@ -88,36 +89,105 @@ namespace Tins {
};
/**
* \brief This class represents an IP option.
* \brief The type used to represent an option's type.
*/
struct IPOption {
friend class IP;
struct {
#if TINS_IS_LITTLE_ENDIAN
unsigned int number:5;
unsigned int op_class:2;
unsigned int copied:1;
#elif TINS_IS_BIG_ENDIAN
unsigned int copied:1;
unsigned int op_class:2;
unsigned int number:5;
#endif
} __attribute__((__packed__)) type;
uint8_t* write(uint8_t* buffer);
struct option_identifier {
#if TINS_IS_LITTLE_ENDIAN
uint8_t number:5,
op_class:2,
copied:1;
#elif TINS_IS_BIG_ENDIAN
uint8_t copied:1,
op_class:2,
number:5;
#endif
/**
* \brief Default constructor.
*
* Initializes every field to 0.
*/
option_identifier() : number(0), op_class(0), copied(0) {}
/**
* Getter for IP options' data pointer.
* \brief Constructs this option from a single uint8_t value.
*
* This parses the value and initializes each field with the
* appropriate value.
*
* \param value The value to be parsed and used for
* initialization
*/
const uint8_t* data_ptr() const;
option_identifier(uint8_t value)
: number(value & 0x1f),
op_class((value >> 5) & 0x03),
copied((value >> 7) & 0x01) {}
/**
* Getter for the data size field
* Constructor using user provided values for each field.
* \param number The number field value.
* \param op_class The option class field value.
* \param copied The copied field value.
*/
uint8_t data_size() const;
private:
std::vector<uint8_t> optional_data;
option_identifier(OptionNumber number, OptionClass op_class,
small_uint<1> copied)
: number(number), op_class(op_class), copied(copied) {}
/**
* \brief Equality operator.
*/
bool operator==(const option_identifier &rhs) const {
return number == rhs.number && op_class == rhs.op_class && copied == rhs.copied;
}
} __attribute__((__packed__));
/**
* The IP options type.
*/
typedef PDUOption<option_identifier> ip_option;
/**
* The type of the security option.
*/
struct security_type {
uint16_t security, compartments;
uint16_t handling_restrictions;
small_uint<24> transmission_control;
security_type(uint16_t sec = 0, uint16_t comp = 0,
uint16_t hand_res = 0, small_uint<24> tcc = 0)
: security(sec), compartments(comp),
handling_restrictions(hand_res), transmission_control(tcc)
{}
};
/**
* The type of the Loose Source and Record Route
*/
struct generic_route_option_type {
typedef std::vector<address_type> routes_type;
uint8_t pointer;
routes_type routes;
generic_route_option_type(uint8_t ptr = 0,
routes_type rts = routes_type())
: pointer(ptr), routes(rts) {}
};
/**
* The type of the Loose Source and Record Route
*/
typedef generic_route_option_type lsrr_type;
/**
* The type of the Strict Source and Record Route
*/
typedef generic_route_option_type ssrr_type;
/**
* The type of the Record Route
*/
typedef generic_route_option_type record_route_type;
/**
* \brief Constructor for building the IP PDU.
@@ -300,42 +370,133 @@ namespace Tins {
void version(small_uint<4> ver);
/**
* \brief Sets an IP option.
*
* \param copied The copied flag for this option.
* \param op_class The option class to be set.
* \param number The options number to be set.
* \param data The data of this options.
* \param data_size The data size.
* \brief Adds an IP option.
*
* The option is added after the last option in the option
* fields.
*
* \param option The option to be added
*/
void set_option(uint8_t copied, OptionClass op_class, Option number, const uint8_t* data = 0, uint32_t data_size = 0);
void add_option(const ip_option &option);
/**
* \brief Searchs for an option that matchs the given flag.
* \param opt_class The option class to be searched.
* \param opt_number The option number to be searched.
* \return A pointer to the option, or 0 if it was not found.
* \param id The option identifier to be searched.
*/
const IPOption *search_option(OptionClass opt_class, Option opt_number) const;
const ip_option *search_option(option_identifier id) const;
// Option setters
/**
* \brief Adds an End Of List option.
*/
void eol();
/**
* \brief Sets the End of List option.
* \brief Adds a NOP option.
*/
void set_eol_option();
void noop();
/**
* \brief Sets the NOP option.
*/
void set_noop_option();
/**
* \brief Sets the security option.
* \brief Adds a security option.
*
* \param data The data for this option
* \param data_len The length of the data.
* \param data The data to be stored in this option.
*/
void set_sec_option(const uint8_t* data, uint32_t data_len);
/* Add more option setters */
void security(const security_type &data);
/**
* \brief Adds a Loose Source and Record Route option.
*
* \param data The data to be stored in this option.
*/
void lsrr(const lsrr_type &data) {
add_route_option(131, data);
}
/**
* \brief Adds a Strict Source and Record Route option.
*
* \param data The data to be stored in this option.
*/
void ssrr(const ssrr_type &data) {
add_route_option(137, data);
}
/**
* \brief Adds a Record Route option.
*
* \param data The data to be stored in this option.
*/
void record_route(const record_route_type &data) {
add_route_option(7, data);
}
/**
* \brief Adds a Stream Identifier option.
*
* \param stream_id The stream id to be stored in this option.
*/
void stream_identifier(uint16_t stream_id);
// Option getters
/**
* \brief Searchs and returns a security option.
*
* If no such option exists, an option_not_found exception
* is thrown.
*
* \return security_type containing the option found.
*/
security_type security() const;
/**
* \brief Searchs and returns a Loose Source and Record Route
* option.
*
* If no such option exists, an option_not_found exception
* is thrown.
*
* \return lsrr_type containing the option found.
*/
lsrr_type lsrr() const {
return search_route_option(131);
}
/**
* \brief Searchs and returns a Strict Source and Record Route
* option.
*
* If no such option exists, an option_not_found exception
* is thrown.
*
* \return ssrr_type containing the option found.
*/
ssrr_type ssrr() const {
return search_route_option(137);
}
/**
* \brief Searchs and returns a Record Route option.
*
* If no such option exists, an option_not_found exception
* is thrown.
*
* \return record_route_type containing the option found.
*/
record_route_type record_route() const {
return search_route_option(7);
}
/**
* \brief Searchs and returns a Stream Identifier option.
*
* If no such option exists, an option_not_found exception
* is thrown.
*
* \return uint16_t containing the option found.
*/
uint16_t stream_identifier() const;
/* Virtual methods */
@@ -418,9 +579,12 @@ namespace Tins {
void init_ip_fields();
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
uint8_t* write_option(const ip_option &opt, uint8_t* buffer);
void add_route_option(option_identifier id, const generic_route_option_type &data);
generic_route_option_type search_route_option(option_identifier id) const;
iphdr _ip;
std::list<IPOption> _ip_options;
std::list<ip_option> _ip_options;
uint32_t _options_size, _padded_options_size;
};
};

125
include/pdu_option.h Normal file
View File

@@ -0,0 +1,125 @@
/*
* libtins is a net packet wrapper library for crafting and
* interpreting sniffed packets.
*
* Copyright (C) 2011 Nasel
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef TINS_PDU_OPTION_H
#define TINS_PDU_OPTION_H
#include <vector>
#include <iterator>
#include <stdint.h>
namespace Tins {
/**
* \brief Exception thrown when an option is not found.
*/
class option_not_found : public std::exception {
public:
const char* what() const throw() {
return "Option not found";
}
};
/**
* \class PDUOption
* \brief Represents a PDU option field.
*
* Several PDUs, such as TCP, IP, Dot11 or DHCP contain options. All
* of them behave exactly the same way. This class represents those
* options.
*
* The OptionType template parameter indicates the type that will be
* used to store this option's identifier.
*
* The Container template parameter indicates the container which will
* be used to store this option's data. The container <b>must</b>
* store data sequentially. std::vector<uint8_t> is the default
* container.
*/
template<typename OptionType, class Container = std::vector<uint8_t> >
class PDUOption {
public:
typedef Container container_type;
typedef typename container_type::value_type data_type;
typedef OptionType option_type;
/**
* \brief Constructs a PDUOption.
* \param opt The option type.
* \param length The option's data length.
* \param data The option's data(if any).
*/
PDUOption(option_type opt = option_type(), size_t length = 0, const data_type *data = 0)
: option_(opt) {
value_.push_back(length);
if(data)
value_.insert(value_.end(), data, data + length);
}
/**
* \brief Constructs a PDUOption from iterators, which
* indicate the data to be stored in it.
*
* \param opt The option type.
* \param start The beginning of the option data.
* \param end The end of the option data.
*/
template<typename ForwardIterator>
PDUOption(option_type opt, ForwardIterator start, ForwardIterator end)
: option_(opt) {
value_.push_back(std::distance(start, end));
value_.insert(value_.end(), start, end);
}
/**
* Retrieves this option's type.
* \return uint8_t containing this option's size.
*/
option_type option() const {
return option_;
}
/**
* Retrieves this option's data.
*
* If this method is called when data_size() == 0,
* dereferencing the returned pointer will result in undefined
* behaviour.
*
* \return const value_type& containing this option's value.
*/
const data_type *data_ptr() const {
return &*(++value_.begin());
//return &value_[1];
}
/**
* Retrieves the length of this option's data.
*/
size_t data_size() const {
return value_.empty() ? 0 : (value_.size() - 1);
}
private:
option_type option_;
container_type value_;
};
} // namespace Tins
#endif // TINS_PDU_OPTION_H

View File

@@ -31,6 +31,7 @@
#include "pdu.h"
#include "endianness.h"
#include "small_uint.h"
#include "pdu_option.h"
namespace Tins {
/**
@@ -89,98 +90,18 @@ namespace Tins {
CHK_16FLETCHER
};
/**
* \brief Class that represents a TCP option field.
*/
class TCPOption {
public:
/**
* \brief Constructs a TCPOption.
* \param opt The option type.
* \param length The option's data length.
* \param data The option's data(if any).
*/
TCPOption(uint8_t opt = 0, uint8_t length = 0, const uint8_t *data = 0)
: option_(opt) {
value_.push_back(length);
if(data)
value_.insert(value_.end(), data, data + length);
}
/**
* Constructs a TCPOption from iterators, which indicate
* the data to be stored in it.
* \param opt The option type.
* \param start The beginning of the option data.
* \param end The end of the option data.
*/
template<typename ForwardIterator>
TCPOption(uint8_t opt, ForwardIterator start, ForwardIterator end)
: option_(opt), value_(start, end) {
}
/**
* Retrieves this option's type.
* \return uint8_t containing this option's size.
*/
uint8_t option() const {
return option_;
}
/**
* Retrieves this option's data.
*
* If this method is called when data_size() == 0,
* dereferencing the returned pointer will result in undefined
* behaviour.
*
* \return const value_type& containing this option's value.
*/
const uint8_t *data_ptr() const {
return &value_[1];
}
/**
* Retrieves the length of this option's data.
*/
size_t data_size() const {
return value_.size() - 1;
}
/**
* \brief Writes the option into a buffer.
* \param buffer The buffer in which to write the option.
* \return The buffer pointer incremented by the size of this option.
*/
uint8_t *write(uint8_t *buffer);
private:
typedef std::vector<uint8_t> data_type;
uint8_t option_;
data_type value_;
};
typedef PDUOption<uint8_t> tcp_option;
/**
* The type used to store the options.
*/
typedef std::vector<TCPOption> options_type;
typedef std::list<tcp_option> options_type;
/**
* The type used to store the sack option.
*/
typedef std::vector<uint32_t> sack_type;
/**
* \brief Exception thrown when an option is not found.
*/
class OptionNotFound : public std::exception {
public:
const char* what() const throw() {
return "Option not found";
}
};
/**
* \brief TCP constructor.
*
@@ -425,11 +346,11 @@ namespace Tins {
/**
* \brief Adds a TCP option.
*
* \param tcp_option The option type flag to be set.
* \param option The option type flag to be set.
* \param length The length of this option(optional).
* \param data Pointer to this option's data(optional).
*/
void add_option(Option tcp_option, uint8_t length = 0, const uint8_t *data = 0);
void add_option(Option option, uint8_t length = 0, const uint8_t *data = 0);
/**
* \brief Returns the header size.
@@ -453,7 +374,7 @@ namespace Tins {
* \param opt_flag The flag to be searched.
* \return A pointer to the option, or 0 if it was not found.
*/
const TCPOption *search_option(Option opt) const;
const tcp_option *search_option(Option opt) const;
/**
* \sa PDU::clone_pdu
@@ -501,17 +422,15 @@ namespace Tins {
template<class T>
T generic_search(Option opt) const {
const TCPOption *option = search_option(opt);
const tcp_option *option = search_option(opt);
if(option && option->data_size() == sizeof(T))
return *(const T*)(&option->data_ptr()[0]);
throw OptionNotFound();
throw option_not_found();
}
/** \brief Serialices this TCP PDU.
* \param buffer The buffer in which the PDU will be serialized.
* \param total_sz The size available in the buffer.
* \param parent The PDU that's one level below this one on the stack.
*/
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
uint8_t *write_option(const tcp_option &opt, uint8_t *buffer);
tcphdr _tcp;
options_type _options;

View File

@@ -31,8 +31,6 @@ using std::list;
using std::runtime_error;
namespace Tins {
const uint32_t DHCP::MAX_DHCP_SIZE = 312;
// Magic cookie: uint32_t.
DHCP::DHCP() : _size(sizeof(uint32_t)) {
opcode(BOOTREQUEST);
@@ -63,148 +61,132 @@ DHCP::DHCP(const uint8_t *buffer, uint32_t total_sz)
}
if(total_sz < args[1])
throw std::runtime_error("Not enough size for a DHCP header in the buffer.");
add_option((Options)args[0], args[1], buffer);
add_option(dhcp_option((Options)args[0], args[1], buffer));
buffer += args[1];
total_sz -= args[1];
}
}
DHCP::DHCPOption::DHCPOption(uint8_t opt, uint8_t len, const uint8_t *val)
: option(opt), value(val, val ? (val + len) : val) {
void DHCP::add_option(const dhcp_option &option) {
_options.push_back(option);
_size += option.data_size() + (sizeof(uint8_t) << 1);
}
bool DHCP::add_option(Options opt, uint8_t len, const uint8_t *val) {
uint32_t opt_size = len + (sizeof(uint8_t) << 1);
if(_size + opt_size > MAX_DHCP_SIZE)
return false;
_options.push_back(DHCPOption((uint8_t)opt, len, val));
_size += opt_size;
return true;
}
const DHCP::DHCPOption *DHCP::search_option(Options opt) const{
const DHCP::dhcp_option *DHCP::search_option(Options opt) const {
for(options_type::const_iterator it = _options.begin(); it != _options.end(); ++it) {
if(it->option == opt)
if(it->option() == opt)
return &(*it);
}
return 0;
}
bool DHCP::add_type_option(Flags type) {
void DHCP::type(Flags type) {
uint8_t int_type = type;
return add_option(DHCP_MESSAGE_TYPE, sizeof(uint8_t), &int_type);
add_option(dhcp_option(DHCP_MESSAGE_TYPE, sizeof(uint8_t), &int_type));
}
bool DHCP::add_end_option() {
return add_option(DHCP_MESSAGE_TYPE, 0, 0);
void DHCP::end() {
add_option(dhcp_option(DHCP_MESSAGE_TYPE));
}
bool DHCP::search_type_option(uint8_t *value) {
return generic_search(DHCP_MESSAGE_TYPE, value);
uint8_t DHCP::type() const {
return generic_search(DHCP_MESSAGE_TYPE, type2type<uint8_t>());
}
bool DHCP::add_server_identifier(ipaddress_type ip) {
void DHCP::server_identifier(ipaddress_type ip) {
uint32_t ip_int = ip;
return add_option(DHCP_SERVER_IDENTIFIER, sizeof(uint32_t), (const uint8_t*)&ip_int);
add_option(dhcp_option(DHCP_SERVER_IDENTIFIER, sizeof(uint32_t), (const uint8_t*)&ip_int));
}
bool DHCP::search_server_identifier(ipaddress_type *value) {
return generic_search(DHCP_SERVER_IDENTIFIER, value);
DHCP::ipaddress_type DHCP::server_identifier() const {
return generic_search(DHCP_SERVER_IDENTIFIER, type2type<ipaddress_type>());
}
bool DHCP::add_lease_time(uint32_t time) {
void DHCP::lease_time(uint32_t time) {
time = Endian::host_to_be(time);
return add_option(DHCP_LEASE_TIME, sizeof(uint32_t), (const uint8_t*)&time);
add_option(dhcp_option(DHCP_LEASE_TIME, sizeof(uint32_t), (const uint8_t*)&time));
}
bool DHCP::search_lease_time(uint32_t *value) {
return generic_search(DHCP_LEASE_TIME, value);
uint32_t DHCP::lease_time() const {
return Endian::host_to_be(generic_search(DHCP_LEASE_TIME, type2type<uint32_t>()));
}
bool DHCP::add_renewal_time(uint32_t time) {
void DHCP::renewal_time(uint32_t time) {
time = Endian::host_to_be(time);
return add_option(DHCP_RENEWAL_TIME, sizeof(uint32_t), (const uint8_t*)&time);
add_option(dhcp_option(DHCP_RENEWAL_TIME, sizeof(uint32_t), (const uint8_t*)&time));
}
bool DHCP::search_renewal_time(uint32_t *value) {
return generic_search(DHCP_RENEWAL_TIME, value);
uint32_t DHCP::renewal_time() const {
return Endian::host_to_be(generic_search(DHCP_RENEWAL_TIME, type2type<uint32_t>()));
}
bool DHCP::add_subnet_mask(ipaddress_type mask) {
void DHCP::subnet_mask(ipaddress_type mask) {
uint32_t mask_int = mask;
return add_option(SUBNET_MASK, sizeof(uint32_t), (const uint8_t*)&mask_int);
add_option(dhcp_option(SUBNET_MASK, sizeof(uint32_t), (const uint8_t*)&mask_int));
}
bool DHCP::search_subnet_mask(ipaddress_type *value) {
return generic_search(SUBNET_MASK, value);
DHCP::ipaddress_type DHCP::subnet_mask() const {
return generic_search(SUBNET_MASK, type2type<ipaddress_type>());
}
bool DHCP::add_routers_option(const list<ipaddress_type> &routers) {
uint32_t size;
uint8_t *buffer = serialize_list(routers, size);
bool ret = add_option(ROUTERS, size, buffer);
delete[] buffer;
return ret;
void DHCP::routers(const list<ipaddress_type> &routers) {
serialization_type buffer = serialize_list(routers);
add_option(dhcp_option(ROUTERS, buffer.begin(), buffer.end()));
}
bool DHCP::search_routers_option(std::list<ipaddress_type> *routers) {
return generic_search(ROUTERS, routers);
std::list<DHCP::ipaddress_type> DHCP::routers() const {
return generic_search(ROUTERS, type2type<std::list<ipaddress_type> >());
}
bool DHCP::add_dns_option(const list<ipaddress_type> &dns) {
uint32_t size;
uint8_t *buffer = serialize_list(dns, size);
bool ret = add_option(DOMAIN_NAME_SERVERS, size, buffer);
delete[] buffer;
return ret;
void DHCP::domain_name_servers(const list<ipaddress_type> &dns) {
serialization_type buffer = serialize_list(dns);
add_option(dhcp_option(DOMAIN_NAME_SERVERS, buffer.begin(), buffer.end()));
}
bool DHCP::search_dns_option(std::list<ipaddress_type> *dns) {
return generic_search(DOMAIN_NAME_SERVERS, dns);
std::list<DHCP::ipaddress_type> DHCP::domain_name_servers() const {
return generic_search(DOMAIN_NAME_SERVERS, type2type<std::list<ipaddress_type> >());
}
bool DHCP::add_broadcast_option(ipaddress_type addr) {
void DHCP::broadcast(ipaddress_type addr) {
uint32_t int_addr = addr;
return add_option(BROADCAST_ADDRESS, sizeof(uint32_t), (uint8_t*)&int_addr);
add_option(dhcp_option(BROADCAST_ADDRESS, sizeof(uint32_t), (uint8_t*)&int_addr));
}
bool DHCP::search_broadcast_option(ipaddress_type *value) {
return generic_search(BROADCAST_ADDRESS, value);
DHCP::ipaddress_type DHCP::broadcast() const {
return generic_search(BROADCAST_ADDRESS, type2type<ipaddress_type>());
}
bool DHCP::add_requested_ip_option(ipaddress_type addr) {
void DHCP::requested_ip(ipaddress_type addr) {
uint32_t int_addr = addr;
return add_option(DHCP_REQUESTED_ADDRESS, sizeof(uint32_t), (uint8_t*)&int_addr);
add_option(dhcp_option(DHCP_REQUESTED_ADDRESS, sizeof(uint32_t), (uint8_t*)&int_addr));
}
bool DHCP::search_requested_ip_option(ipaddress_type *value) {
return generic_search(DHCP_REQUESTED_ADDRESS, value);
DHCP::ipaddress_type DHCP::requested_ip() const {
return generic_search(DHCP_REQUESTED_ADDRESS, type2type<ipaddress_type>());
}
bool DHCP::add_domain_name(const string &name) {
return add_option(DOMAIN_NAME, name.size(), (const uint8_t*)name.c_str());
void DHCP::domain_name(const string &name) {
add_option(dhcp_option(DOMAIN_NAME, name.size(), (const uint8_t*)name.c_str()));
}
bool DHCP::search_domain_name(std::string *value) {
return generic_search(DOMAIN_NAME, value);
std::string DHCP::domain_name() const {
return generic_search(DOMAIN_NAME, type2type<std::string>());
}
bool DHCP::add_rebind_time(uint32_t time) {
void DHCP::rebind_time(uint32_t time) {
time = Endian::host_to_be(time);
return add_option(DHCP_REBINDING_TIME, sizeof(uint32_t), (uint8_t*)&time);
add_option(dhcp_option(DHCP_REBINDING_TIME, sizeof(uint32_t), (uint8_t*)&time));
}
bool DHCP::search_rebind_time(uint32_t *value) {
return generic_search(DHCP_REBINDING_TIME, value);
uint32_t DHCP::rebind_time() const {
return Endian::host_to_be(generic_search(DHCP_REBINDING_TIME, type2type<uint32_t>()));
}
uint8_t *DHCP::serialize_list(const list<ipaddress_type> &ip_list, uint32_t &sz) {
uint8_t *buffer = new uint8_t[ip_list.size() * sizeof(uint32_t)];
uint32_t *ptr = (uint32_t*)buffer;
PDU::serialization_type DHCP::serialize_list(const list<ipaddress_type> &ip_list) {
serialization_type buffer(ip_list.size() * sizeof(uint32_t));
uint32_t *ptr = (uint32_t*)&buffer[0];
for(list<ipaddress_type>::const_iterator it = ip_list.begin(); it != ip_list.end(); ++it)
*(ptr++) = *it;
sz = sizeof(uint32_t) * ip_list.size();
return buffer;
}
@@ -221,52 +203,39 @@ void DHCP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *pa
// Magic cookie
*((uint32_t*)&result[0]) = Endian::host_to_be<uint32_t>(0x63825363);
for(options_type::const_iterator it = _options.begin(); it != _options.end(); ++it) {
*(ptr++) = it->option;
*(ptr++) = it->value.size();
std::copy(it->value.begin(), it->value.end(), ptr);
ptr += it->value.size();
*(ptr++) = it->option();
*(ptr++) = it->data_size();
std::copy(it->data_ptr(), it->data_ptr() + it->data_size(), ptr);
ptr += it->data_size();
}
}
BootP::write_serialization(buffer, total_sz, parent);
}
bool DHCP::generic_search(Options opt, std::list<ipaddress_type> *container) {
const DHCPOption *option = search_option(opt);
std::list<DHCP::ipaddress_type> DHCP::generic_search(Options opt, type2type<std::list<ipaddress_type> >) const {
const dhcp_option *option = search_option(opt);
if(!option)
return false;
const uint32_t *ptr = (const uint32_t*)&option->value[0];
uint32_t len = option->value.size();
throw option_not_found();
const uint32_t *ptr = (const uint32_t*)option->data_ptr();
uint32_t len = option->data_size();
if((len % sizeof(uint32_t)) != 0)
return false;
throw option_not_found();
std::list<ipaddress_type> container;
while(len) {
container->push_back(ipaddress_type(*(ptr++)));
container.push_back(ipaddress_type(*(ptr++)));
len -= sizeof(uint32_t);
}
return true;
return container;
}
bool DHCP::generic_search(Options opt, std::string *str) {
const DHCPOption *option = search_option(opt);
std::string DHCP::generic_search(Options opt, type2type<std::string>) const {
const dhcp_option *option = search_option(opt);
if(!option)
return false;
*str = string(option->value.begin(), option->value.end());
return true;
throw option_not_found();
return string(option->data_ptr(), option->data_ptr() + option->data_size());
}
bool DHCP::generic_search(Options opt, uint32_t *value) {
if(generic_search<uint32_t>(opt, value)) {
*value = Endian::host_to_be(*value);
return true;
}
return false;
}
bool DHCP::generic_search(Options opt, ipaddress_type *value) {
uint32_t ip_int;
if(generic_search(opt, &ip_int)) {
*value = IPv4Address(Endian::host_to_be(ip_int));
return true;
}
return false;
DHCP::ipaddress_type DHCP::generic_search(Options opt, type2type<ipaddress_type>) const {
return ipaddress_type(generic_search(opt, type2type<uint32_t>()));
}
}

View File

@@ -85,19 +85,14 @@ void Dot11::parse_tagged_parameters(const uint8_t *buffer, uint32_t total_sz) {
}
}
Dot11::Dot11Option::Dot11Option(uint8_t opt, uint8_t len, const uint8_t *val)
: option_id(opt), value(val, val + len) {
}
void 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(Dot11Option((uint8_t)opt, len, val));
_options.push_back(dot11_option((uint8_t)opt, len, val));
_options_size += opt_size;
}
const Dot11::Dot11Option *Dot11::search_option(TaggedOption opt) const {
for(std::list<Dot11Option>::const_iterator it = _options.begin(); it != _options.end(); ++it)
const Dot11::dot11_option *Dot11::search_option(TaggedOption opt) const {
for(std::list<dot11_option>::const_iterator it = _options.begin(); it != _options.end(); ++it)
if(it->option() == (uint8_t)opt)
return &(*it);
return 0;
@@ -188,7 +183,7 @@ void Dot11::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *p
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<Dot11Option>::const_iterator it = _options.begin(); it != _options.end(); ++it) {
for(std::list<dot11_option>::const_iterator it = _options.begin(); it != _options.end(); ++it) {
*(buffer++) = it->option();
*(buffer++) = it->data_size();
std::copy(it->data_ptr(), it->data_ptr() + it->data_size(), buffer);
@@ -255,8 +250,8 @@ void Dot11::copy_80211_fields(const Dot11 *other) {
std::memcpy(&_header, &other->_header, sizeof(_header));
_iface = other->_iface;
_options_size = other->_options_size;
for(std::list<Dot11Option>::const_iterator it = other->_options.begin(); it != other->_options.end(); ++it)
_options.push_back(Dot11Option(it->option(), it->data_size(), it->data_ptr()));
for(std::list<dot11_option>::const_iterator it = other->_options.begin(); it != other->_options.end(); ++it)
_options.push_back(dot11_option(it->option(), it->data_size(), it->data_ptr()));
}
/* Dot11ManagementFrame */
@@ -352,7 +347,7 @@ uint8_t *Dot11ManagementFrame::serialize_rates(const rates_type &rates) {
return buffer;
}
Dot11ManagementFrame::rates_type Dot11ManagementFrame::deserialize_rates(const Dot11Option *option) {
Dot11ManagementFrame::rates_type Dot11ManagementFrame::deserialize_rates(const dot11_option *option) {
rates_type output;
const uint8_t *ptr = option->data_ptr(), *end = ptr + option->data_size();
while(ptr != end) {
@@ -574,49 +569,49 @@ void Dot11ManagementFrame::challenge_text(const std::string &text) {
// Getters
RSNInformation Dot11ManagementFrame::rsn_information() {
const Dot11::Dot11Option *option = search_option(RSN);
const Dot11::dot11_option *option = search_option(RSN);
if(!option || option->data_size() < (sizeof(uint16_t) << 1) + sizeof(uint32_t))
throw std::runtime_error("RSN information not set");
return RSNInformation(option->data_ptr(), option->data_size());
}
string Dot11ManagementFrame::ssid() const {
const Dot11::Dot11Option *option = search_option(SSID);
const Dot11::dot11_option *option = search_option(SSID);
if(!option || option->data_size() == 0)
throw std::runtime_error("SSID not set");
return string((const char*)option->data_ptr(), option->data_size());
}
Dot11ManagementFrame::rates_type Dot11ManagementFrame::supported_rates() const {
const Dot11::Dot11Option *option = search_option(SUPPORTED_RATES);
const Dot11::dot11_option *option = search_option(SUPPORTED_RATES);
if(!option || option->data_size() == 0)
throw std::runtime_error("Supported rates not set");
return deserialize_rates(option);
}
Dot11ManagementFrame::rates_type Dot11ManagementFrame::extended_supported_rates() const {
const Dot11::Dot11Option *option = search_option(EXT_SUPPORTED_RATES);
const Dot11::dot11_option *option = search_option(EXT_SUPPORTED_RATES);
if(!option || option->data_size() == 0)
throw std::runtime_error("Extended supported rates not set");
return deserialize_rates(option);
}
uint8_t Dot11ManagementFrame::qos_capability() const {
const Dot11::Dot11Option *option = search_option(QOS_CAPABILITY);
const Dot11::dot11_option *option = search_option(QOS_CAPABILITY);
if(!option || option->data_size() != 1)
throw std::runtime_error("QOS capability not set");
return *option->data_ptr();
}
std::pair<uint8_t, uint8_t> Dot11ManagementFrame::power_capability() const {
const Dot11::Dot11Option *option = search_option(POWER_CAPABILITY);
const Dot11::dot11_option *option = search_option(POWER_CAPABILITY);
if(!option || option->data_size() != 2)
throw std::runtime_error("Power capability not set");
return std::make_pair(*option->data_ptr(), *(option->data_ptr() + 1));
}
Dot11ManagementFrame::channels_type Dot11ManagementFrame::supported_channels() const {
const Dot11::Dot11Option *option = search_option(SUPPORTED_CHANNELS);
const Dot11::dot11_option *option = search_option(SUPPORTED_CHANNELS);
// We need a multiple of two
if(!option || ((option->data_size() & 0x1) == 1))
throw std::runtime_error("Supported channels not set");
@@ -630,7 +625,7 @@ Dot11ManagementFrame::channels_type Dot11ManagementFrame::supported_channels() c
}
Dot11ManagementFrame::request_info_type Dot11ManagementFrame::request_information() const {
const Dot11::Dot11Option *option = search_option(REQUEST_INFORMATION);
const Dot11::dot11_option *option = search_option(REQUEST_INFORMATION);
if(!option || option->data_size() == 0)
throw std::runtime_error("Request information not set");
request_info_type output;
@@ -640,7 +635,7 @@ Dot11ManagementFrame::request_info_type Dot11ManagementFrame::request_informatio
}
Dot11ManagementFrame::fh_params_set Dot11ManagementFrame::fh_parameter_set() const {
const Dot11::Dot11Option *option = search_option(FH_SET);
const Dot11::dot11_option *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());
@@ -652,21 +647,21 @@ Dot11ManagementFrame::fh_params_set Dot11ManagementFrame::fh_parameter_set() con
}
uint8_t Dot11ManagementFrame::ds_parameter_set() const {
const Dot11::Dot11Option *option = search_option(DS_SET);
const Dot11::dot11_option *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);
const Dot11::dot11_option *option = search_option(IBSS_SET);
if(!option || option->data_size() != sizeof(uint16_t))
throw std::runtime_error("IBSS parameters set not set");
return Endian::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);
const Dot11::dot11_option *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;
@@ -684,7 +679,7 @@ Dot11ManagementFrame::ibss_dfs_params Dot11ManagementFrame::ibss_dfs() const {
}
Dot11ManagementFrame::country_params Dot11ManagementFrame::country() const {
const Dot11::Dot11Option *option = search_option(COUNTRY);
const Dot11::dot11_option *option = search_option(COUNTRY);
if(!option || option->data_size() < country_params::minimum_size)
throw std::runtime_error("Country option not set");
country_params output;
@@ -702,7 +697,7 @@ Dot11ManagementFrame::country_params Dot11ManagementFrame::country() const {
}
std::pair<uint8_t, uint8_t> Dot11ManagementFrame::fh_parameters() const {
const Dot11::Dot11Option *option = search_option(HOPPING_PATTERN_PARAMS);
const Dot11::dot11_option *option = search_option(HOPPING_PATTERN_PARAMS);
if(!option || option->data_size() != sizeof(uint8_t) * 2)
throw std::runtime_error("FH parameters option not set");
const uint8_t *ptr = option->data_ptr();
@@ -711,7 +706,7 @@ std::pair<uint8_t, uint8_t> Dot11ManagementFrame::fh_parameters() const {
}
Dot11ManagementFrame::fh_pattern_type Dot11ManagementFrame::fh_pattern_table() const {
const Dot11::Dot11Option *option = search_option(HOPPING_PATTERN_TABLE);
const Dot11::dot11_option *option = search_option(HOPPING_PATTERN_TABLE);
if(!option || option->data_size() < fh_pattern_type::minimum_size)
throw std::runtime_error("FH pattern option not set");
fh_pattern_type output;
@@ -727,14 +722,14 @@ Dot11ManagementFrame::fh_pattern_type Dot11ManagementFrame::fh_pattern_table() c
}
uint8_t Dot11ManagementFrame::power_constraint() const {
const Dot11::Dot11Option *option = search_option(POWER_CONSTRAINT);
const Dot11::dot11_option *option = search_option(POWER_CONSTRAINT);
if(!option || option->data_size() != 1)
throw std::runtime_error("Power constraint option not set");
return *option->data_ptr();
}
Dot11ManagementFrame::channel_switch_type Dot11ManagementFrame::channel_switch() const {
const Dot11::Dot11Option *option = search_option(CHANNEL_SWITCH);
const Dot11::dot11_option *option = search_option(CHANNEL_SWITCH);
if(!option || option->data_size() != sizeof(uint8_t) * 3)
throw std::runtime_error("Channel switch option not set");
const uint8_t *ptr = option->data_ptr();
@@ -746,7 +741,7 @@ Dot11ManagementFrame::channel_switch_type Dot11ManagementFrame::channel_switch()
}
Dot11ManagementFrame::quiet_type Dot11ManagementFrame::quiet() const {
const Dot11::Dot11Option *option = search_option(QUIET);
const Dot11::dot11_option *option = search_option(QUIET);
if(!option || option->data_size() != (sizeof(uint8_t) * 2 + sizeof(uint16_t) * 2))
throw std::runtime_error("Quiet option not set");
const uint8_t *ptr = option->data_ptr();
@@ -761,7 +756,7 @@ Dot11ManagementFrame::quiet_type Dot11ManagementFrame::quiet() const {
}
std::pair<uint8_t, uint8_t> Dot11ManagementFrame::tpc_report() const {
const Dot11::Dot11Option *option = search_option(TPC_REPORT);
const Dot11::dot11_option *option = search_option(TPC_REPORT);
if(!option || option->data_size() != sizeof(uint8_t) * 2)
throw std::runtime_error("TPC Report option not set");
const uint8_t *ptr = option->data_ptr();
@@ -770,14 +765,14 @@ std::pair<uint8_t, uint8_t> Dot11ManagementFrame::tpc_report() const {
}
uint8_t Dot11ManagementFrame::erp_information() const {
const Dot11::Dot11Option *option = search_option(ERP_INFORMATION);
const Dot11::dot11_option *option = search_option(ERP_INFORMATION);
if(!option || option->data_size() != sizeof(uint8_t))
throw std::runtime_error("ERP Information option not set");
return *option->data_ptr();
}
Dot11ManagementFrame::bss_load_type Dot11ManagementFrame::bss_load() const {
const Dot11::Dot11Option *option = search_option(BSS_LOAD);
const Dot11::dot11_option *option = search_option(BSS_LOAD);
if(!option || option->data_size() != sizeof(uint8_t) + 2 * sizeof(uint16_t))
throw std::runtime_error("BSS Load option not set");
bss_load_type output;
@@ -790,7 +785,7 @@ Dot11ManagementFrame::bss_load_type Dot11ManagementFrame::bss_load() const {
}
Dot11ManagementFrame::tim_type Dot11ManagementFrame::tim() const {
const Dot11::Dot11Option *option = search_option(TIM);
const Dot11::dot11_option *option = search_option(TIM);
if(!option || option->data_size() < 4 * sizeof(uint8_t))
throw std::runtime_error("TIM option not set");
const uint8_t *ptr = option->data_ptr(), *end = ptr + option->data_size();
@@ -805,7 +800,7 @@ Dot11ManagementFrame::tim_type Dot11ManagementFrame::tim() const {
}
std::string Dot11ManagementFrame::challenge_text() const {
const Dot11::Dot11Option *option = search_option(CHALLENGE_TEXT);
const Dot11::dot11_option *option = search_option(CHALLENGE_TEXT);
if(!option || option->data_size() == 0)
throw std::runtime_error("Challenge text option not set");
return std::string(option->data_ptr(), option->data_ptr() + option->data_size());

View File

@@ -53,7 +53,7 @@ IP::IP(address_type ip_dst, address_type ip_src, PDU *child)
IP::IP(const uint8_t *buffer, uint32_t total_sz)
: PDU(Constants::IP::PROTO_IP)
{
static const char *msg("Not enough size for an IP header in the buffer.");
const char *msg = "Not enough size for an IP header in the buffer.";
if(total_sz < sizeof(iphdr))
throw std::runtime_error(msg);
std::memcpy(&_ip, buffer, sizeof(iphdr));
@@ -71,10 +71,11 @@ IP::IP(const uint8_t *buffer, uint32_t total_sz)
_padded_options_size = head_len() * sizeof(uint32_t) - sizeof(iphdr);
/* While the end of the options is not reached read an option */
while (ptr_buffer < buffer && (*ptr_buffer != 0)) {
IPOption opt_to_add;
memcpy(&opt_to_add.type, ptr_buffer, sizeof(uint8_t));
//ip_option opt_to_add;
option_identifier opt_type;
memcpy(&opt_type, ptr_buffer, sizeof(uint8_t));
ptr_buffer++;
switch (opt_to_add.type.number) {
switch (opt_type.number) {
/* Multibyte options with length as second byte */
case SEC:
case LSSR:
@@ -97,18 +98,24 @@ IP::IP(const uint8_t *buffer, uint32_t total_sz)
throw std::runtime_error(msg);
{
const uint8_t data_size = *ptr_buffer - 1;
const uint8_t data_size = *ptr_buffer - 2;
if(data_size > 0) {
ptr_buffer++;
if(buffer - ptr_buffer < data_size)
throw std::runtime_error(msg);
opt_to_add.optional_data.assign(ptr_buffer, ptr_buffer + data_size);
_ip_options.push_back(ip_option(opt_type, ptr_buffer, ptr_buffer + data_size));
}
else
_ip_options.push_back(ip_option(opt_type));
}
ptr_buffer += opt_to_add.optional_data.size();
ptr_buffer += _ip_options.back().data_size() + 1;
break;
default:
_ip_options.push_back(ip_option(opt_type));
break;
}
this->_ip_options.push_back(opt_to_add);
this->_options_size += opt_to_add.optional_data.size() + 1;
_options_size += _ip_options.back().data_size() + 2;
}
// check this line PLX
total_sz -= head_len() * sizeof(uint32_t);
@@ -132,11 +139,11 @@ IP::IP(const uint8_t *buffer, uint32_t total_sz)
void IP::init_ip_fields() {
memset(&_ip, 0, sizeof(iphdr));
this->_ip.version = 4;
this->ttl(DEFAULT_TTL);
this->id(1);
this->_options_size = 0;
this->_padded_options_size = 0;
_ip.version = 4;
ttl(DEFAULT_TTL);
id(1);
_options_size = 0;
_padded_options_size = 0;
}
/* Setters */
@@ -187,67 +194,126 @@ void IP::version(small_uint<4> ver) {
_ip.version = ver;
}
void IP::set_eol_option() {
this->set_option(0, IP::CONTROL, IP::END);
void IP::eol() {
add_option(option_identifier(IP::END, IP::CONTROL, 0));
}
void IP::set_noop_option() {
this->set_option(0, IP::CONTROL, IP::NOOP);
void IP::noop() {
add_option(option_identifier(IP::NOOP, IP::CONTROL, 0));
}
void IP::set_sec_option(const uint8_t* data, uint32_t data_len) {
this->set_option(1, IP::CONTROL, IP::SEC, data, data_len);
void IP::security(const security_type &data) {
uint8_t array[9];
uint16_t *ptr = reinterpret_cast<uint16_t*>(array);
uint32_t value = data.transmission_control;
*ptr++ = Endian::host_to_be(data.security);
*ptr++ = Endian::host_to_be(data.compartments);
*ptr++ = Endian::host_to_be(data.handling_restrictions);
array[8] = (value & 0xff);
array[7] = ((value >> 8) & 0xff);
array[6] = ((value >> 16) & 0xff);
add_option(
ip_option(
130,
sizeof(array),
array
)
);
}
void IP::set_option(uint8_t copied,
OptionClass op_class,
Option number,
const uint8_t* data,
uint32_t data_size)
{
IPOption option;
option.type.copied = copied;
option.type.op_class = op_class;
option.type.number = number;
if (data_size) {
option.optional_data.push_back(data_size);
std::copy(data, data + data_size,
std::back_inserter(option.optional_data)
);
data_size++;
void IP::stream_identifier(uint16_t stream_id) {
stream_id = Endian::host_to_be(stream_id);
add_option(
ip_option(
136,
sizeof(uint16_t),
(const uint8_t*)&stream_id
)
);
}
void IP::add_route_option(option_identifier id, const generic_route_option_type &data) {
std::vector<uint8_t> opt_data(1 + sizeof(uint32_t) * data.routes.size());
opt_data[0] = data.pointer;
for(size_t i(0); i < data.routes.size(); ++i) {
uint32_t ip = data.routes[i];
opt_data[1 + i * 4] = ip & 0xff;
opt_data[1 + i * 4 + 1] = (ip >> 8) & 0xff;
opt_data[1 + i * 4 + 2] = (ip >> 16) & 0xff;
opt_data[1 + i * 4 + 3] = (ip >> 24) & 0xff;
}
add_option(
ip_option(
id,
opt_data.size(),
&opt_data[0]
)
);
}
IP::generic_route_option_type IP::search_route_option(option_identifier id) const {
const ip_option *option = search_option(id);
if(!option || option->data_size() < 1 + sizeof(uint32_t) ||
((option->data_size() - 1) % sizeof(uint32_t)) != 0)
throw option_not_found();
generic_route_option_type output;
output.pointer = *option->data_ptr();
const uint32_t *route = (const uint32_t*)(option->data_ptr() + 1),
*end = route + (option->data_size() - 1) / sizeof(uint32_t);
while(route < end)
output.routes.push_back(address_type(*route++));
return output;
}
IP::security_type IP::security() const {
const ip_option *option = search_option(130);
if(!option || option->data_size() < 9)
throw option_not_found();
security_type output;
const uint16_t *ptr = reinterpret_cast<const uint16_t*>(option->data_ptr());
output.security = Endian::be_to_host(*ptr++);
output.compartments = Endian::be_to_host(*ptr++);
output.handling_restrictions = Endian::be_to_host(*ptr++);
uint32_t tcc = option->data_ptr()[6];
tcc = (tcc << 8) | option->data_ptr()[7];
tcc = (tcc << 8) | option->data_ptr()[8];
output.transmission_control = tcc;
return output;
}
uint16_t IP::stream_identifier() const {
const ip_option *option = search_option(136);
if(!option || option->data_size() != sizeof(uint16_t))
throw option_not_found();
return Endian::be_to_host(*(const uint16_t*)option->data_ptr());
}
void IP::add_option(const ip_option &option) {
_ip_options.push_back(option);
_options_size += 1 + (!option.optional_data.empty() ? (data_size) : 0);
_options_size += 1 + option.data_size();
uint8_t padding = _options_size & 3;
_padded_options_size = padding ? (_options_size - padding + 4) : _options_size;
}
const IP::IPOption *IP::search_option(OptionClass opt_class, Option opt_number) const {
for(std::list<IPOption>::const_iterator it = _ip_options.begin(); it != _ip_options.end(); ++it) {
if(it->type.op_class == (uint8_t)opt_class && it->type.number == (uint8_t)opt_number)
const IP::ip_option *IP::search_option(option_identifier id) const {
for(std::list<ip_option>::const_iterator it = _ip_options.begin(); it != _ip_options.end(); ++it) {
if(it->option() == id)
return &(*it);
}
return 0;
}
uint8_t* IP::IPOption::write(uint8_t* buffer) {
memcpy(buffer, &type, 1);
buffer += 1;
if (!optional_data.empty()) {
std::copy(optional_data.begin(), optional_data.end(), buffer);
buffer += optional_data.size();
}
uint8_t* IP::write_option(const ip_option &opt, uint8_t* buffer) {
option_identifier opt_type = opt.option();
memcpy(buffer, &opt_type, 1);
buffer++;
*(buffer++) = opt.data_size() + 2;
std::copy(opt.data_ptr(), opt.data_ptr() + opt.data_size(), buffer);
buffer += opt.data_size();
return buffer;
}
const uint8_t* IP::IPOption::data_ptr() const {
return !optional_data.empty() ? (&optional_data[1]) : 0;
}
uint8_t IP::IPOption::data_size() const {
return !optional_data.empty() ? (optional_data.size() - 1) : 0;
}
/* Virtual method overriding. */
uint32_t IP::header_size() const {
@@ -296,9 +362,8 @@ void IP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU* pare
memcpy(buffer, &_ip, sizeof(_ip));
uint8_t* ptr_buffer = buffer + sizeof(_ip);
for(list<IPOption>::iterator it = _ip_options.begin(); it != _ip_options.end(); ++it)
ptr_buffer = it->write(ptr_buffer);
for(list<ip_option>::iterator it = _ip_options.begin(); it != _ip_options.end(); ++it)
ptr_buffer = write_option(*it, ptr_buffer);
memset(buffer + sizeof(_ip) + _options_size, 0, _padded_options_size - _options_size);
if(parent && !_ip.check) {

View File

@@ -157,9 +157,9 @@ void TCP::sack(const sack_type &edges) {
}
TCP::sack_type TCP::sack() const {
const TCPOption *option = search_option(SACK);
const tcp_option *option = search_option(SACK);
if(!option || (option->data_size() % sizeof(uint32_t)) != 0)
throw OptionNotFound();
throw option_not_found();
const uint32_t *ptr = (const uint32_t*)option->data_ptr();
const uint32_t *end = ptr + (option->data_size() / sizeof(uint32_t));
sack_type edges(end - ptr);
@@ -176,9 +176,9 @@ void TCP::timestamp(uint32_t value, uint32_t reply) {
}
std::pair<uint32_t, uint32_t> TCP::timestamp() const {
const TCPOption *option = search_option(TSOPT);
const tcp_option *option = search_option(TSOPT);
if(!option || option->data_size() != (sizeof(uint32_t) << 1))
throw OptionNotFound();
throw option_not_found();
uint64_t buffer = *(const uint64_t*)option->data_ptr();
buffer = Endian::be_to_host(buffer);
return std::make_pair((buffer >> 32) & 0xffffffff, buffer & 0xffffffff);
@@ -254,13 +254,13 @@ void TCP::set_flag(Flags tcp_flag, small_uint<1> value) {
};
}
void TCP::add_option(Option tcp_option, uint8_t length, const uint8_t *data) {
void TCP::add_option(Option option, uint8_t length, const uint8_t *data) {
uint8_t padding;
_options.push_back(TCPOption(tcp_option, length, data));
_options.push_back(tcp_option(option, length, data));
_options_size += sizeof(uint8_t);
// SACK_OK contains length but not data....
if(length || tcp_option == SACK_OK)
if(length || option == SACK_OK)
_options_size += sizeof(uint8_t);
if(data)
@@ -280,7 +280,7 @@ void TCP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *par
buffer += sizeof(tcphdr);
_tcp.doff = (sizeof(tcphdr) + _total_options_size) / sizeof(uint32_t);
for(options_type::iterator it = _options.begin(); it != _options.end(); ++it)
buffer = it->write(buffer);
buffer = write_option(*it, buffer);
if(_options_size < _total_options_size) {
uint8_t padding = _options_size;
@@ -305,7 +305,7 @@ void TCP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *par
_tcp.check = 0;
}
const TCP::TCPOption *TCP::search_option(Option opt) const {
const TCP::tcp_option *TCP::search_option(Option opt) const {
for(options_type::const_iterator it = _options.begin(); it != _options.end(); ++it) {
if(it->option() == opt)
return &(*it);
@@ -313,18 +313,18 @@ const TCP::TCPOption *TCP::search_option(Option opt) const {
return 0;
}
/* TCPOptions */
/* tcp_options */
uint8_t *TCP::TCPOption::write(uint8_t *buffer) {
if(option_ == 0 || option_ == 1) {
*buffer = option_;
uint8_t *TCP::write_option(const tcp_option &opt, uint8_t *buffer) {
if(opt.option() == 0 || opt.option() == 1) {
*buffer = opt.option();
return buffer + 1;
}
else {
buffer[0] = option_;
buffer[1] = data_size() + (sizeof(uint8_t) << 1);
if(!value_.empty())
std::copy(value_.begin() + 1, value_.end(), buffer + 2);
buffer[0] = opt.option();
buffer[1] = opt.data_size() + (sizeof(uint8_t) << 1);
if(opt.data_size() != 0)
std::copy(opt.data_ptr(), opt.data_ptr() + opt.data_size(), buffer + 2);
return buffer + buffer[1];
}
}

View File

@@ -107,7 +107,8 @@ src/ipaddress.o: src/ipaddress.cpp ../include/ipaddress.h \
../include/hwaddress.h:
src/ip.o: src/ip.cpp ../include/ip.h ../include/pdu.h \
../include/small_uint.h ../include/endianness.h ../include/ipaddress.h \
../include/ipaddress.h ../include/utils.h ../include/hwaddress.h
../include/pdu_option.h ../include/ipaddress.h ../include/utils.h \
../include/hwaddress.h
../include/ip.h:
@@ -119,6 +120,8 @@ src/ip.o: src/ip.cpp ../include/ip.h ../include/pdu.h \
../include/ipaddress.h:
../include/pdu_option.h:
../include/ipaddress.h:
../include/utils.h:
@@ -162,8 +165,8 @@ src/snap.o: src/snap.cpp ../include/snap.h ../include/pdu.h \
../include/hwaddress.h:
src/tcp.o: src/tcp.cpp ../include/tcp.h ../include/pdu.h \
../include/endianness.h ../include/small_uint.h ../include/utils.h \
../include/ipaddress.h ../include/hwaddress.h
../include/endianness.h ../include/small_uint.h ../include/pdu_option.h \
../include/utils.h ../include/ipaddress.h ../include/hwaddress.h
../include/tcp.h:
@@ -173,6 +176,8 @@ src/tcp.o: src/tcp.cpp ../include/tcp.h ../include/pdu.h \
../include/small_uint.h:
../include/pdu_option.h:
../include/utils.h:
../include/ipaddress.h:
@@ -612,9 +617,10 @@ include/tests/dot11.h:
include/tests/dot11.h:
../src/arp.o: ../src/arp.cpp ../include/arp.h ../include/pdu.h \
../include/endianness.h ../include/hwaddress.h ../include/ipaddress.h \
../include/ip.h ../include/small_uint.h ../include/ethernetII.h \
../include/network_interface.h ../include/rawpdu.h \
../include/constants.h ../include/network_interface.h
../include/ip.h ../include/small_uint.h ../include/pdu_option.h \
../include/ethernetII.h ../include/network_interface.h \
../include/rawpdu.h ../include/constants.h \
../include/network_interface.h
../include/arp.h:
@@ -630,6 +636,8 @@ include/tests/dot11.h:
../include/small_uint.h:
../include/pdu_option.h:
../include/ethernetII.h:
../include/network_interface.h:
@@ -740,7 +748,7 @@ include/tests/dot11.h:
../include/pdu.h ../include/endianness.h ../include/hwaddress.h \
../include/network_interface.h ../include/ipaddress.h \
../include/packet_sender.h ../include/rawpdu.h ../include/ip.h \
../include/small_uint.h ../include/arp.h
../include/small_uint.h ../include/pdu_option.h ../include/arp.h
../include/ethernetII.h:
@@ -762,6 +770,8 @@ include/tests/dot11.h:
../include/small_uint.h:
../include/pdu_option.h:
../include/arp.h:
../src/icmp.o: ../src/icmp.cpp ../include/icmp.h ../include/pdu.h \
../include/endianness.h ../include/rawpdu.h ../include/utils.h \
@@ -808,9 +818,9 @@ include/tests/dot11.h:
../include/endianness.h:
../src/ip.o: ../src/ip.cpp ../include/ip.h ../include/pdu.h \
../include/small_uint.h ../include/endianness.h ../include/ipaddress.h \
../include/tcp.h ../include/udp.h ../include/icmp.h ../include/rawpdu.h \
../include/utils.h ../include/hwaddress.h ../include/packet_sender.h \
../include/constants.h
../include/pdu_option.h ../include/tcp.h ../include/udp.h \
../include/icmp.h ../include/rawpdu.h ../include/utils.h \
../include/hwaddress.h ../include/packet_sender.h ../include/constants.h
../include/ip.h:
@@ -822,6 +832,8 @@ include/tests/dot11.h:
../include/ipaddress.h:
../include/pdu_option.h:
../include/tcp.h:
../include/udp.h:
@@ -922,7 +934,7 @@ include/tests/dot11.h:
../src/snap.o: ../src/snap.cpp ../include/snap.h ../include/pdu.h \
../include/endianness.h ../include/small_uint.h ../include/constants.h \
../include/arp.h ../include/hwaddress.h ../include/ipaddress.h \
../include/ip.h ../include/eapol.h
../include/ip.h ../include/pdu_option.h ../include/eapol.h
../include/snap.h:
@@ -942,6 +954,8 @@ include/tests/dot11.h:
../include/ip.h:
../include/pdu_option.h:
../include/eapol.h:
../src/sniffer.o: ../src/sniffer.cpp ../include/sniffer.h \
../include/pdu.h ../include/ethernetII.h ../include/endianness.h \
@@ -964,9 +978,9 @@ include/tests/dot11.h:
../include/radiotap.h:
../src/tcp.o: ../src/tcp.cpp ../include/tcp.h ../include/pdu.h \
../include/endianness.h ../include/small_uint.h ../include/ip.h \
../include/ipaddress.h ../include/constants.h ../include/rawpdu.h \
../include/utils.h ../include/hwaddress.h
../include/endianness.h ../include/small_uint.h ../include/pdu_option.h \
../include/ip.h ../include/ipaddress.h ../include/constants.h \
../include/rawpdu.h ../include/utils.h ../include/hwaddress.h
../include/tcp.h:
@@ -976,6 +990,8 @@ include/tests/dot11.h:
../include/small_uint.h:
../include/pdu_option.h:
../include/ip.h:
../include/ipaddress.h:
@@ -992,7 +1008,7 @@ include/tests/dot11.h:
../include/ethernetII.h ../include/endianness.h ../include/hwaddress.h \
../include/network_interface.h ../include/ipaddress.h \
../include/radiotap.h ../include/tcp.h ../include/small_uint.h \
../include/ip.h
../include/pdu_option.h ../include/ip.h
../include/rawpdu.h:
@@ -1018,11 +1034,13 @@ include/tests/dot11.h:
../include/small_uint.h:
../include/pdu_option.h:
../include/ip.h:
../src/udp.o: ../src/udp.cpp ../include/udp.h ../include/pdu.h \
../include/endianness.h ../include/constants.h ../include/utils.h \
../include/ipaddress.h ../include/hwaddress.h ../include/ip.h \
../include/small_uint.h ../include/rawpdu.h
../include/small_uint.h ../include/pdu_option.h ../include/rawpdu.h
../include/udp.h:
@@ -1042,12 +1060,14 @@ include/tests/dot11.h:
../include/small_uint.h:
../include/pdu_option.h:
../include/rawpdu.h:
../src/utils.o: ../src/utils.cpp ../include/utils.h \
../include/ipaddress.h ../include/hwaddress.h ../include/pdu.h \
../include/ip.h ../include/pdu.h ../include/small_uint.h \
../include/endianness.h ../include/icmp.h ../include/arp.h \
../include/endianness.h ../include/network_interface.h \
../include/endianness.h ../include/pdu_option.h ../include/icmp.h \
../include/arp.h ../include/endianness.h ../include/network_interface.h \
../include/packet_sender.h
../include/utils.h:
@@ -1066,6 +1086,8 @@ include/tests/dot11.h:
../include/endianness.h:
../include/pdu_option.h:
../include/icmp.h:
../include/arp.h:

View File

@@ -186,44 +186,37 @@ TEST_F(DHCPTest, File) {
}
void DHCPTest::test_option(const DHCP &dhcp, DHCP::Options opt, uint32_t len, uint8_t *value) {
const DHCP::DHCPOption *option = dhcp.search_option(opt);
const DHCP::dhcp_option *option = dhcp.search_option(opt);
ASSERT_TRUE(option != 0);
EXPECT_EQ(option->option, opt);
ASSERT_EQ(option->value.size(), len);
if(len)
EXPECT_TRUE(std::equal(option->value.begin(), option->value.end(), value));
EXPECT_EQ(option->option(), opt);
ASSERT_EQ(option->data_size(), len);
EXPECT_TRUE(std::equal(option->data_ptr(), option->data_ptr() + option->data_size(), value));
}
TEST_F(DHCPTest, TypeOption) {
DHCP dhcp;
uint8_t value = DHCP::REQUEST, value_found;
dhcp.add_type_option(DHCP::REQUEST);
ASSERT_TRUE(dhcp.search_type_option(&value_found));
EXPECT_EQ(value, value_found);
dhcp.type(DHCP::REQUEST);
EXPECT_EQ(dhcp.type(), DHCP::REQUEST);
}
TEST_F(DHCPTest, ServerIdentifierOption) {
DHCP dhcp;
IPv4Address ip = "192.168.0.1", ip_found;
dhcp.add_server_identifier(ip);
ASSERT_TRUE(dhcp.search_server_identifier(&ip_found));
EXPECT_EQ(ip, ip_found);
dhcp.server_identifier("192.168.0.1");
EXPECT_EQ(DHCP::ipaddress_type("192.168.0.1"), dhcp.server_identifier());
}
TEST_F(DHCPTest, LeaseTimeOption) {
DHCP dhcp;
uint32_t ltime = 0x34f1, ltime_found;
dhcp.add_lease_time(ltime);
ASSERT_TRUE(dhcp.search_lease_time(&ltime_found));
EXPECT_EQ(ltime, ltime_found);
uint32_t ltime = 0x34f1;
dhcp.lease_time(ltime);
EXPECT_EQ(ltime, dhcp.lease_time());
}
TEST_F(DHCPTest, SubnetMaskOption) {
DHCP dhcp;
IPv4Address ip = "192.168.0.1", ip_found;
dhcp.add_subnet_mask(ip);
ASSERT_TRUE(dhcp.search_subnet_mask(&ip_found));
EXPECT_EQ(ip, ip_found);
dhcp.subnet_mask(ip);
EXPECT_EQ(ip, dhcp.subnet_mask());
}
TEST_F(DHCPTest, RoutersOption) {
@@ -231,10 +224,9 @@ TEST_F(DHCPTest, RoutersOption) {
list<IPv4Address> routers;
routers.push_back("192.168.0.253");
routers.push_back("10.123.45.67");
dhcp.add_routers_option(routers);
dhcp.routers(routers);
list<IPv4Address> routers2;
ASSERT_TRUE(dhcp.search_routers_option(&routers2));
list<IPv4Address> routers2 = dhcp.routers();
ASSERT_EQ(routers.size(), routers2.size());
while(routers.size()) {
EXPECT_EQ(routers.front(), routers2.front());
@@ -248,10 +240,9 @@ TEST_F(DHCPTest, DNSOption) {
list<IPv4Address> dns;
dns.push_back("192.168.0.253");
dns.push_back("10.123.45.67");
dhcp.add_dns_option(dns);
dhcp.domain_name_servers(dns);
list<IPv4Address> dns2;
ASSERT_TRUE(dhcp.search_dns_option(&dns2));
list<IPv4Address> dns2 = dhcp.domain_name_servers();
ASSERT_EQ(dns.size(), dns2.size());
while(dns.size()) {
EXPECT_EQ(dns.front(), dns2.front());
@@ -263,17 +254,15 @@ TEST_F(DHCPTest, DNSOption) {
TEST_F(DHCPTest, DomainNameOption) {
DHCP dhcp;
string domain = "libtins.test.domain", domain_found;
dhcp.add_domain_name(domain);
ASSERT_TRUE(dhcp.search_domain_name(&domain_found));
EXPECT_TRUE(domain == domain_found);
dhcp.domain_name(domain);
EXPECT_EQ(domain, dhcp.domain_name());
}
TEST_F(DHCPTest, BroadcastOption) {
DHCP dhcp;
IPv4Address ip = "192.168.0.1", ip_found;
dhcp.add_broadcast_option(ip);
ASSERT_TRUE(dhcp.search_broadcast_option(&ip_found));
EXPECT_EQ(ip, ip_found);
dhcp.broadcast(ip);
EXPECT_EQ(ip, dhcp.broadcast());
}
void DHCPTest::test_equals(const DHCP &dhcp1, const DHCP &dhcp2) {
@@ -290,23 +279,22 @@ void DHCPTest::test_equals(const DHCP &dhcp1, const DHCP &dhcp2) {
EXPECT_EQ(dhcp1.chaddr(), dhcp2.chaddr());
EXPECT_TRUE(memcmp(dhcp1.sname(), dhcp2.sname(), 64) == 0);
EXPECT_TRUE(memcmp(dhcp1.file(), dhcp2.file(), 128) == 0);
const std::list<DHCP::DHCPOption> options1(dhcp1.options());
const std::list<DHCP::DHCPOption> options2(dhcp2.options());
const DHCP::options_type options1(dhcp1.options());
const DHCP::options_type options2(dhcp2.options());
ASSERT_EQ(options1.size(), options2.size());
std::list<DHCP::DHCPOption>::const_iterator it1, it2;
DHCP::options_type::const_iterator it1, it2;
it1 = options1.begin();
it2 = options2.begin();
while(it1 != options1.end()) {
EXPECT_EQ(it1->option, it2->option);
ASSERT_EQ(it1->value.size(), it2->value.size());
EXPECT_TRUE(std::equal(it1->value.begin(), it1->value.end(), it2->value.begin()));
EXPECT_EQ(it1->option(), it2->option());
ASSERT_EQ(it1->data_size(), it2->data_size());
EXPECT_TRUE(std::equal(it1->data_ptr(), it1->data_ptr() + it1->data_size(), it2->data_ptr()));
it1++; it2++;
}
}
TEST_F(DHCPTest, ConstructorFromBuffer) {
DHCP dhcp1(expected_packet, sizeof(expected_packet));
IPv4Address ip;
std::list<IPv4Address> routers;
IPv4Address expected_routers[] = { "192.168.0.1", "127.0.0.1" };
@@ -321,9 +309,8 @@ TEST_F(DHCPTest, ConstructorFromBuffer) {
EXPECT_EQ(dhcp1.yiaddr(), IPv4Address("243.22.34.98"));
EXPECT_EQ(dhcp1.giaddr(), IPv4Address("123.43.55.254"));
EXPECT_EQ(dhcp1.siaddr(), IPv4Address("167.32.11.154"));
ASSERT_TRUE(dhcp1.search_server_identifier(&ip));
EXPECT_EQ(ip, IPv4Address("192.168.4.2"));
ASSERT_TRUE(dhcp1.search_routers_option(&routers));
EXPECT_EQ(dhcp1.server_identifier(), IPv4Address("192.168.4.2"));
routers = dhcp1.routers();
ASSERT_EQ(routers.size(), sizeof(expected_routers) / sizeof(IPv4Address));
ASSERT_TRUE(std::equal(routers.begin(), routers.end(), expected_routers));

View File

@@ -152,7 +152,7 @@ TEST_F(Dot11Test, Addr1) {
TEST_F(Dot11Test, AddTaggedOption) {
Dot11 dot11;
dot11.add_tagged_option(Dot11::SSID, hwaddr.size(), hwaddr.begin());
const Dot11::Dot11Option *option;
const Dot11::dot11_option *option;
ASSERT_TRUE((option = dot11.search_option(Dot11::SSID)));
EXPECT_EQ(option->data_size(), hwaddr.size());
EXPECT_EQ(option->option(), Dot11::SSID);

View File

@@ -16,10 +16,12 @@ public:
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' };
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) {
@@ -52,7 +54,7 @@ TEST_F(IPTest, NestedCopy) {
test_equals(ip1, ip2);
}
TEST_F(IPTest, IPIntConstructor) {
TEST_F(IPTest, Constructor) {
IP ip("192.168.0.1", "192.168.0.100");
EXPECT_EQ(ip.dst_addr(), "192.168.0.1");
EXPECT_EQ(ip.src_addr(), "192.168.0.100");
@@ -60,15 +62,6 @@ TEST_F(IPTest, IPIntConstructor) {
EXPECT_EQ(ip.id(), 1);
}
TEST_F(IPTest, IPStringConstructor) {
string ip1 = "154.33.200.55", ip2 = "192.10.11.52";
IP ip(ip1, ip2);
EXPECT_EQ(ip.dst_addr(), ip1);
EXPECT_EQ(ip.src_addr(), ip2);
EXPECT_EQ(ip.version(), 4);
EXPECT_EQ(ip.id(), 1);
}
TEST_F(IPTest, HeadLen) {
IP ip;
ip.head_len(14);
@@ -150,11 +143,61 @@ TEST_F(IPTest, Version) {
}
TEST_F(IPTest, SecOption) {
IP ip;
ip.security(IP::security_type(0x746a, 26539, 0x77ab, 0x68656c));
IP::security_type found = ip.security();
EXPECT_EQ(found.security, 0x746a);
EXPECT_EQ(found.compartments, 26539);
EXPECT_EQ(found.handling_restrictions, 0x77ab);
EXPECT_EQ(found.transmission_control, 0x68656c);
}
TEST_F(IPTest, LSRROption) {
IP ip;
IP::lsrr_type lsrr(0x2d);
lsrr.routes.push_back("192.168.2.3");
lsrr.routes.push_back("192.168.5.1");
ip.lsrr(lsrr);
IP::lsrr_type found = ip.lsrr();
EXPECT_EQ(found.pointer, lsrr.pointer);
EXPECT_EQ(found.routes, lsrr.routes);
}
TEST_F(IPTest, SSRROption) {
IP ip;
IP::ssrr_type ssrr(0x2d);
ssrr.routes.push_back("192.168.2.3");
ssrr.routes.push_back("192.168.5.1");
ip.ssrr(ssrr);
IP::ssrr_type found = ip.ssrr();
EXPECT_EQ(found.pointer, ssrr.pointer);
EXPECT_EQ(found.routes, ssrr.routes);
}
TEST_F(IPTest, RecordRouteOption) {
IP ip;
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);
IP::record_route_type found = ip.record_route();
EXPECT_EQ(found.pointer, record_route.pointer);
EXPECT_EQ(found.routes, record_route.routes);
}
TEST_F(IPTest, StreamIDOption) {
IP ip;
ip.stream_identifier(0x91fa);
EXPECT_EQ(0x91fa, ip.stream_identifier());
}
TEST_F(IPTest, AddOption) {
IP ip;
const uint8_t data[] = { 0x15, 0x17, 0x94, 0x66, 0xff };
ip.set_sec_option(data, sizeof(data));
const IP::IPOption *option;
ASSERT_TRUE((option = ip.search_option(IP::CONTROL, IP::SEC)));
IP::option_identifier id(IP::SEC, IP::CONTROL, 1);
ip.add_option(IP::ip_option(id, data, data + sizeof(data)));
const IP::ip_option *option;
ASSERT_TRUE((option = ip.search_option(id)));
ASSERT_EQ(option->data_size(), sizeof(data));
EXPECT_TRUE(memcmp(option->data_ptr(), data, sizeof(data)) == 0);
}
@@ -171,23 +214,22 @@ void IPTest::test_equals(const IP &ip1, const IP &ip2) {
}
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' };
IP ip(expected_packet, sizeof(expected_packet));
EXPECT_EQ(ip1.dst_addr(), "192.168.9.43");
EXPECT_EQ(ip1.src_addr(), "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(std::equal(option->data_ptr(), option->data_ptr() + option->data_size(), opt_sec));
EXPECT_EQ(ip.dst_addr(), "192.168.9.43");
EXPECT_EQ(ip.src_addr(), "84.52.254.5");
EXPECT_EQ(ip.id(), 0x7a);
EXPECT_EQ(ip.tos(), 0x7f);
EXPECT_EQ(ip.frag_off(), 0x43);
EXPECT_EQ(ip.protocol(), 1);
EXPECT_EQ(ip.ttl(), 0x15);
EXPECT_EQ(ip.version(), 2);
IP::security_type sec = ip.security();
EXPECT_EQ(sec.security, 0x746a);
EXPECT_EQ(sec.compartments, 26539);
EXPECT_EQ(sec.handling_restrictions, 0x77ab);
EXPECT_EQ(sec.transmission_control, 0x68656c);
}
TEST_F(IPTest, Serialize) {