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

Fixed some bugs. Added a better dependency system for Makefiles.

This commit is contained in:
Matias Fontanini
2012-08-13 00:29:38 -03:00
parent 87e9c4051e
commit e2223bf406
20 changed files with 1530 additions and 159 deletions

View File

@@ -37,8 +37,16 @@ namespace Tins {
*/
class EthernetII : public PDU {
public:
/**
* \brief The hardware address type.
*/
typedef HWAddress<6> address_type;
/**
* \brief The hardware address size.
*/
static const size_t ADDR_SIZE;
/**
* \brief This PDU's flag.
*/
@@ -47,12 +55,7 @@ namespace Tins {
/**
* \brief Represents the ethernetII broadcast address.
*/
static const uint8_t* BROADCAST;
/**
* \brief Ethernet II hardware address size.
*/
static const unsigned ADDR_SIZE = 6;
static const address_type BROADCAST;
/**
* \brief Constructor for creating an ethernet PDU
@@ -61,8 +64,8 @@ namespace Tins {
* destination's and source's MAC.
*
* \param iface string containing the interface's name from where to send the packet.
* \param dst_hw_addr uint8_t array of 6 bytes containing the destination's MAC(optional).
* \param src_hw_addr uint8_t array of 6 bytes containing the source's MAC(optional).
* \param dst_hw_addr address_type containing the destination's MAC(optional).
* \param src_hw_addr address_type containing the source's MAC(optional).
* \param child PDU* with the PDU contained by the ethernet PDU (optional).
*/
EthernetII(const NetworkInterface& iface = NetworkInterface(),
@@ -73,6 +76,7 @@ namespace Tins {
/**
* \brief Constructor which creates an EthernetII object from a buffer and adds all identifiable
* PDUs found in the buffer as children of this one.
*
* \param buffer The buffer from which this PDU will be constructed.
* \param total_sz The total size of the buffer.
*/
@@ -80,23 +84,24 @@ namespace Tins {
/* Getters */
/**
* \brief Getter for the destination's mac address.
* \brief Getter for the destination's hardware address.
*
* \return Returns the destination's mac address as a constant uint8_t pointer.
* \return address_type containing the destination hardware
* address.
*/
address_type dst_addr() const { return _eth.dst_mac; }
/**
* \brief Getter for the source's mac address.
* \brief Getter for the source's hardware address.
*
* \return Returns the source's mac address as a constant uint8_t pointer.
* \return address_type containing the source hardware address.
*/
address_type src_addr() const { return _eth.src_mac; }
/**
* \brief Getter for the interface.
*
* \return Returns the interface's index as an uint32_t.
* \return Returns the interface in which this PDU will be sent.
*/
const NetworkInterface &iface() const { return _iface; }
@@ -109,30 +114,30 @@ namespace Tins {
/* Setters */
/**
* \brief Setter for the destination's MAC.
* \brief Setter for the destination hardware address.
*
* \param new_dst_mac uint8_t array of 6 bytes containing the new destination's MAC.
* \param new_dst_addr the destination hardware address to be set.
*/
void dst_addr(const address_type &new_dst_mac);
void dst_addr(const address_type &new_dst_addr);
/**
* \brief Setter for the source's MAC.
* \brief Setter for the source hardware address.
*
* \param new_src_mac uint8_t array of 6 bytes containing the new source's MAC.
* \param new_src_addr the source hardware address to be set.
*/
void src_addr(const address_type &new_src_mac);
void src_addr(const address_type &new_src_addr);
/**
* \brief Setter for the interface.
*
* \param new_iface string reference containing the new interface name.
* \param new_iface the interface to be set.
*/
void iface(const NetworkInterface& new_iface);
/**
* \brief Setter for the payload type.
*
* \param new_payload_type uint16_t with the new value of the payload type field.
* \param new_payload_type the new value of the payload type field.
*/
void payload_type(uint16_t new_payload_type);
@@ -192,8 +197,8 @@ namespace Tins {
* Struct that represents the Ethernet II header
*/
struct ethhdr {
uint8_t dst_mac[ADDR_SIZE];
uint8_t src_mac[ADDR_SIZE];
uint8_t dst_mac[address_type::address_size];
uint8_t src_mac[address_type::address_size];
uint16_t payload_type;
} __attribute__((__packed__));

View File

@@ -31,14 +31,50 @@
#include <sstream>
namespace Tins {
/**
* \class HWAddress
* \brief Represents a hardware address.
*/
template<size_t n, typename Storage = uint8_t>
class HWAddress {
public:
/**
* \brief The type of the elements stored in the hardware address.
*
* This is the same as the template parameter Storage.
*/
typedef Storage storage_type;
/**
* \brief The random access iterator type.
*/
typedef storage_type* iterator;
/**
* \brief Const iterator type.
*/
typedef const storage_type* const_iterator;
/**
* \brief Non-member constant indicating the amount of storage_type
* elements in this address.
*/
static const size_t address_size = n;
/**
* \brief Constructor from a const storage_type*.
*
* If no pointer or a null pointer is provided, the address is
* initialized to 00:00:.....
* This constructor is very usefull when passing zero initialized
* addresses as arguments to other functions. You can use a
* literal 0, which will be implicitly converted to the empty address.
*
* If a pointer is provided, address_size storage_type elements
* are copied from the pointer, into the internal address representation.
*
* \param ptr The pointer from which to construct this address.
*/
HWAddress(const storage_type* ptr = 0) {
if(ptr)
std::copy(ptr, ptr + address_size, buffer);
@@ -46,15 +82,51 @@ public:
std::fill(begin(), end(), storage_type());
}
/**
* \brief Constructs an address from a hex-notation address.
*
* This constructor will parse strings in the form:
*
* "00:01:da:fa:..."
*
* And initialize the internal representation accordingly.
*
* \param address The hex-notation address to be parsed.
*/
HWAddress(const std::string &address) {
convert(address, buffer);
}
/**
* \brief Overload provided basically for string literals.
*
* This constructor takes a const char array of i elements in
* hex-notation. \sa HWAddress::HWAddress(const std::string &address)
*
* This is mostly used when providing string literals. If this where
* a const char*, then there would be an ambiguity when providing
* a null pointer.
*
* \param address The array of chars containing the hex-notation
* cstring to be parsed.
*/
template<size_t i>
HWAddress(const char (&address)[i]) {
convert(address, buffer);
}
/**
* \brief Copy construct from a HWAddress of length i.
*
* If i is lower or equal than address_size, then i storage_type
* elements are copied, and the last (n - i) are initialized to
* the default storage_type value(0 most of the times).
*
* If i is larger than address_size, then only the first address_size
* elements are copied.
*
* \param rhs The HWAddress to be constructed from.
*/
template<size_t i>
HWAddress(const HWAddress<i> &rhs) {
std::copy(
@@ -64,44 +136,95 @@ public:
);
}
HWAddress& operator=(const std::string &address) {
convert(address, buffer);
}
/**
* \brief Retrieves an iterator pointing to the begining of the
* address.
*
* \return iterator.
*/
iterator begin() {
return buffer;
}
/**
* \brief Retrieves a const iterator pointing to the begining of
* the address.
*
* \return const_iterator.
*/
const_iterator begin() const {
return buffer;
}
/**
* \brief Retrieves an iterator pointing one-past-the-end of the
* address.
*
* \return iterator.
*/
iterator end() {
return buffer + address_size;
}
/**
* \brief Retrieves a const iterator pointing one-past-the-end of
* the address.
*
* \return const_iterator.
*/
const_iterator end() const {
return buffer + address_size;
}
/**
* \brief Compares this HWAddress for equality.
*
* \param rhs The HWAddress to be compared to.
*
* \return bool indicating whether addresses are equal.
*/
bool operator==(const HWAddress &rhs) const {
return std::equal(begin(), end(), rhs.begin());
}
/**
* \brief Compares this HWAddress for in-equality.
*
* \param rhs The HWAddress to be compared to.
*
* \return bool indicating whether addresses are distinct.
*/
bool operator!=(const HWAddress &rhs) const {
return !(*this == rhs);
}
/**
* \brief Retrieves the size of this address.
*
* This effectively returns the address_size constant.
*/
const size_t size() const {
return address_size;
}
/**
* \brief Convert this address to a hex-notation std::string address.
*
* \return std::string containing the hex-notation address.
*/
std::string to_string() const {
std::ostringstream oss;
oss << *this;
return oss.str();
}
/**
* \brief Writes this HWAddress in hex-notation to a std::ostream.
*
* \param os The stream in which to write the address.
* \param addr The parameter to be written.
* \return std::ostream& pointing to the os parameter.
*/
friend std::ostream &operator<<(std::ostream &os, const HWAddress &addr) {
std::transform(
addr.begin(),
@@ -112,8 +235,23 @@ public:
return os << storage_to_string(addr.buffer[HWAddress::address_size-1]);
}
/**
* \brief Helper function which copies the address into an output
* iterator.
*
* This is the same as:
*
* std::copy(begin(), end(), iter);
*
* But since some PDUs return a HWAddress<> by value, this function
* can be used to avoid temporaries.
*
* \param iter The output iterator in which to store this address.
* \return OutputIterator pointing to one-past the last position
* written.
*/
template<typename OutputIterator>
OutputIterator copy(OutputIterator iter) {
OutputIterator copy(OutputIterator iter) const {
return std::copy(begin(), end(), iter);
}
private:

View File

@@ -32,7 +32,7 @@
namespace Tins {
/**
/**
* \brief Class representing an Ethernet II PDU.
*/
class IEEE802_3 : public PDU {
@@ -50,7 +50,7 @@ namespace Tins {
/**
* \brief Represents the IEEE802_3 broadcast address.
*/
static const uint8_t* BROADCAST;
static const address_type BROADCAST;
/**
* \brief Constructor for creating an IEEE802_3 PDU

View File

@@ -111,12 +111,12 @@ namespace Tins {
uint8_t* write(uint8_t* buffer);
/**
* \brief Getter for IP options' data pointer.
* Getter for IP options' data pointer.
*/
const uint8_t* data_ptr() const;
/**
* \brief Getter for the data size field
* Getter for the data size field
*/
uint8_t data_size() const;
private:
@@ -214,12 +214,14 @@ namespace Tins {
*/
IPv4Address src_addr() const { return Utils::net_to_host_l(_ip.saddr); }
/** \brief Getter for the destination address field.
/**
* \brief Getter for the destination address field.
* \return The destination address for this IP PDU.
*/
IPv4Address dst_addr() const { return Utils::net_to_host_l(_ip.daddr); }
/** \brief Getter for the version field.
/**
* \brief Getter for the version field.
* \return The version for this IP PDU.
*/
uint8_t version() const { return _ip.version; }

View File

@@ -195,38 +195,38 @@ namespace Tins {
* \brief Getter for the group destination bit.
* \return Whether the group bit is set or not.
*/
inline bool group() {return _header.dsap & 0x01; }
bool group() {return _header.dsap & 0x01; }
/**
* \brief Getter for the dsap field.
* \return The dsap field value
*/
inline uint8_t dsap() {return _header.dsap; }
uint8_t dsap() {return _header.dsap; }
/**
* \brief Getter for the response bit.
* \return Whether the response bit is set or not.
*/
inline bool response() {return (_header.ssap & 0x01); }
bool response() {return (_header.ssap & 0x01); }
/**
* \brief Getter for the ssap field.
* \return The ssap field.
*/
inline uint8_t ssap() {return _header.ssap; }
uint8_t ssap() {return _header.ssap; }
/**
* \brief Getter for the LLC frame format type.
* \return The LLC frame format.
*/
inline uint8_t type() {return _type; }
uint8_t type() {return _type; }
/**
* \brief Getter for sender send sequence number.
*
* \return The sender send sequence number if format is INFORMATION else 0.
*/
inline uint8_t send_seq_number() {
uint8_t send_seq_number() {
return (type() == INFORMATION) ? (control_field.info.send_seq_num) : 0;
}
@@ -236,7 +236,7 @@ namespace Tins {
* \return The sender receive sequence number if format is
* INFORMATION or SUPERVISORY else 0.
*/
inline uint8_t receive_seq_number() {
uint8_t receive_seq_number() {
switch (type()) {
case INFORMATION:
return control_field.info.recv_seq_num;
@@ -253,7 +253,7 @@ namespace Tins {
* \brief Getter for the poll/final flag.
* \return Whether the poll/final flag is set.
*/
inline bool poll_final() {
bool poll_final() {
switch (type()) {
case UNNUMBERED:
return control_field.unnumbered.poll_final_bit;
@@ -271,7 +271,7 @@ namespace Tins {
*
* \return The supervisory function if format is SUPERVISORY else 0.
*/
inline uint8_t supervisory_function() {
uint8_t supervisory_function() {
if (type() == SUPERVISORY)
return control_field.super.supervisory_func;
return 0;
@@ -282,7 +282,7 @@ namespace Tins {
*
* \return The modifier function if format is UNNUMBERED else 0.
*/
inline uint8_t modifier_function() {
uint8_t modifier_function() {
if (type() == UNNUMBERED)
return (control_field.unnumbered.mod_func1 << 3) + control_field.unnumbered.mod_func2;
return 0;

View File

@@ -141,63 +141,63 @@ namespace Tins {
*
* \return The destination port in an uint16_t.
*/
inline uint16_t dport() const { return Utils::net_to_host_s(_tcp.dport); }
uint16_t dport() const { return Utils::net_to_host_s(_tcp.dport); }
/**
* \brief Getter for the source port field.
*
* \return The source port in an uint16_t.
*/
inline uint16_t sport() const { return Utils::net_to_host_s(_tcp.sport); }
uint16_t sport() const { return Utils::net_to_host_s(_tcp.sport); }
/**
* \brief Getter for the sequence number field.
*
* \return The sequence number in an uint32_t.
*/
inline uint32_t seq() const { return Utils::net_to_host_l(_tcp.seq); }
uint32_t seq() const { return Utils::net_to_host_l(_tcp.seq); }
/**
* \brief Getter for the acknowledge number field.
*
* \return The acknowledge number in an uint32_t.
*/
inline uint32_t ack_seq() const { return Utils::net_to_host_l(_tcp.ack_seq); }
uint32_t ack_seq() const { return Utils::net_to_host_l(_tcp.ack_seq); }
/**
* \brief Getter for the window size field.
*
* \return The window size in an uint32_t.
*/
inline uint16_t window() const { return Utils::net_to_host_s(_tcp.window); }
uint16_t window() const { return Utils::net_to_host_s(_tcp.window); }
/**
* \brief Getter for the checksum field.
*
* \return The checksum field in an uint16_t.
*/
inline uint16_t check() const { return Utils::net_to_host_s(_tcp.check); }
uint16_t check() const { return Utils::net_to_host_s(_tcp.check); }
/**
* \brief Getter for the urgent pointer field.
*
* \return The urgent pointer in an uint16_t.
*/
inline uint16_t urg_ptr() const { return Utils::net_to_host_s(_tcp.urg_ptr); }
uint16_t urg_ptr() const { return Utils::net_to_host_s(_tcp.urg_ptr); }
/**
* \brief Getter for the data offset field.
*
* \return Data offset in an uint8_t.
*/
inline uint8_t data_offset() const { return this->_tcp.doff; }
uint8_t data_offset() const { return this->_tcp.doff; }
/**
* \brief Getter for the option list.
*
* \return The options list.
*/
inline const std::list<TCPOption> &options() const { return _options; }
const std::list<TCPOption> &options() const { return _options; }
/**
* \brief Gets the value of a flag.

View File

@@ -27,6 +27,8 @@
#include "dhcp.h"
#include "eapol.h"
#include "ethernetII.h"
#include "ieee802_3.h"
#include "llc.h"
#include "icmp.h"
#include "dot11.h"
#include "ip.h"

View File

@@ -37,42 +37,55 @@
#include "network_interface.h"
namespace Tins {
/** \brief Network utils namespace.
/**
* \brief Network utils namespace.
*
* This namespace provides utils to convert between integer IP addresses
* and dotted notation strings, hw addresses, "net to host" integer
* conversions, interface listing, etc.
* and dotted notation strings, "net to host" integer conversions,
* interface listing, etc.
*/
namespace Utils {
/**
* \brief Struct that represents an interface's information.
*/
struct InterfaceInfo {
IPv4Address ip_addr, netmask, bcast_addr;
uint8_t hw_addr[6];
};
/**
* \brief Struct that represents an entry in /proc/net/route
* Struct that represents an entry in /proc/net/route
*/
struct RouteEntry {
/**
* This interface's name.
*/
std::string interface;
IPv4Address destination, gateway, mask;
/**
* This route entry's destination.
*/
IPv4Address destination;
/**
* This route entry's gateway.
*/
IPv4Address gateway;
/**
* This route entry's subnet mask.
*/
IPv4Address mask;
};
/** \brief Convert a dotted-ip-notation string to an integer.
/**
* \brief Convert a dotted-ip-notation string to an integer.
*
* \param ip A dotted ip notation string
*/
uint32_t ip_to_int(const std::string &ip) throw (std::runtime_error);
/** \brief Convert an integer ip to a dotted-ip-notation string.
/**
* \brief Convert an integer ip to a dotted-ip-notation string.
*
* \param ip An integer ip.
*/
std::string ip_to_string(uint32_t ip);
/** \brief Resolves a domain name and returns its corresponding ip address.
/**
* \brief Resolves a domain name and returns its corresponding ip address.
*
* If an ip address is given, its integer representation is returned.
* Otherwise, the domain name is resolved and its ip address is returned.