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:
47
depends.d
47
depends.d
@@ -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:
|
||||
|
||||
292
include/dhcp.h
292
include/dhcp.h
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
260
include/ip.h
260
include/ip.h
@@ -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
125
include/pdu_option.h
Normal 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
|
||||
103
include/tcp.h
103
include/tcp.h
@@ -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;
|
||||
|
||||
183
src/dhcp.cpp
183
src/dhcp.cpp
@@ -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>()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
181
src/ip.cpp
181
src/ip.cpp
@@ -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) {
|
||||
|
||||
34
src/tcp.cpp
34
src/tcp.cpp
@@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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(<ime_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));
|
||||
|
||||
@@ -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);
|
||||
|
||||
108
tests/src/ip.cpp
108
tests/src/ip.cpp
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user