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:
@@ -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__));
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
10
include/ip.h
10
include/ip.h
@@ -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; }
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user