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

Started fixing endianess issues.

This commit is contained in:
Matias Fontanini
2012-08-15 12:04:13 -03:00
parent 68ab7b094a
commit 892bc0ecd3
18 changed files with 301 additions and 142 deletions

View File

@@ -86,7 +86,7 @@ namespace Tins {
*
* \return Returns the sender's IP address in an uint32_t.
*/
IPv4Address sender_ip_addr() const { return Utils::net_to_host_l(_arp.ar_sip); }
IPv4Address sender_ip_addr() const { return Utils::be_to_host(_arp.ar_sip); }
/**
* \brief Getter for the target's hardware address.
@@ -100,21 +100,21 @@ namespace Tins {
*
* \return Returns the target's IP address in an uint32_t.
*/
IPv4Address target_ip_addr() const { return Utils::net_to_host_l(_arp.ar_tip); }
IPv4Address target_ip_addr() const { return Utils::be_to_host(_arp.ar_tip); }
/**
* \brief Getter for the hardware address format.
*
* \return Returns the hardware address' format in an uint16_t.
*/
uint16_t hw_addr_format() const { return Utils::net_to_host_s(_arp.ar_hrd); }
uint16_t hw_addr_format() const { return Utils::be_to_host(_arp.ar_hrd); }
/**
* \brief Getter for the protocol address format.
*
* \return Returns the protocol address' format in an uint16_t.
*/
uint16_t prot_addr_format() const { return Utils::net_to_host_s(_arp.ar_pro); }
uint16_t prot_addr_format() const { return Utils::be_to_host(_arp.ar_pro); }
/**
* \brief Getter for the hardware address length.
@@ -135,7 +135,7 @@ namespace Tins {
*
* \return Returns the ARP opcode in an uint16_t.
*/
uint16_t opcode() const { return Utils::net_to_host_s(_arp.ar_op); }
uint16_t opcode() const { return Utils::be_to_host(_arp.ar_op); }
/** \brief Getter for the header size.
* \return Returns the ARP header size.

View File

@@ -116,48 +116,47 @@ namespace Tins {
* \brief Getter for the xid field.
* \return The xid field for this BootP PDU.
*/
uint32_t xid() const { return Utils::net_to_host_l(_bootp.xid); }
uint32_t xid() const { return Utils::be_to_host(_bootp.xid); }
/**
* \brief Getter for the secs field.
* \return The secs field for this BootP PDU.
*/
uint16_t secs() const { return Utils::net_to_host_s(_bootp.secs); }
uint16_t secs() const { return Utils::be_to_host(_bootp.secs); }
/** \brief Getter for the padding field.
* \return The padding field for this BootP PDU.
*/
uint16_t padding() const { return Utils::net_to_host_s(_bootp.padding); }
uint16_t padding() const { return Utils::be_to_host(_bootp.padding); }
/**
* \brief Getter for the ciaddr field.
* \return The ciaddr field for this BootP PDU.
*/
IPv4Address ciaddr() const { return Utils::net_to_host_l(_bootp.ciaddr); }
IPv4Address ciaddr() const { return Utils::be_to_host(_bootp.ciaddr); }
/**
* \brief Getter for the yiaddr field.
* \return The yiaddr field for this BootP PDU.
*/
IPv4Address yiaddr() const { return Utils::net_to_host_l(_bootp.yiaddr); }
IPv4Address yiaddr() const { return Utils::be_to_host(_bootp.yiaddr); }
/**
* \brief Getter for the siaddr field.
* \return The siaddr field for this BootP PDU.
*/
IPv4Address siaddr() const { return Utils::net_to_host_l(_bootp.siaddr); }
IPv4Address siaddr() const { return Utils::be_to_host(_bootp.siaddr); }
/**
* \brief Getter for the giaddr field.
* \return The giaddr field for this BootP PDU.
*/
IPv4Address giaddr() const { return Utils::net_to_host_l(_bootp.giaddr); }
IPv4Address giaddr() const { return Utils::be_to_host(_bootp.giaddr); }
/**
* \brief Getter for the chaddr field.
* \return The chddr field for this BootP PDU.
*/
//const uint8_t *chaddr() const { return _bootp.chaddr; }
chaddr_type chaddr() const { return _bootp.chaddr; }
/**

View File

@@ -133,6 +133,9 @@ namespace Tins {
dname(nm), addr(ad), type(t), qclass(c), ttl(tt) {}
};
typedef std::list<Query> queries_type;
typedef std::list<Resource> resources_type;
/**
* \brief Default constructor.
*
@@ -172,7 +175,7 @@ namespace Tins {
*
* \return uint16_t containing the value of the id field.
*/
uint16_t id() const { return Utils::net_to_host_s(dns.id); }
uint16_t id() const { return Utils::be_to_host(dns.id); }
/**
* \brief Setter for the query response field.
@@ -255,28 +258,28 @@ namespace Tins {
*
* \return uint16_t containing the value of the questions field.
*/
uint16_t questions() const { return Utils::net_to_host_s(dns.questions); }
uint16_t questions() const { return Utils::be_to_host(dns.questions); }
/**
* \brief Setter for the answers field.
*
* \return uint16_t containing the value of the answers field.
*/
uint16_t answers() const { return Utils::net_to_host_s(dns.answers); }
uint16_t answers() const { return Utils::be_to_host(dns.answers); }
/**
* \brief Setter for the authority field.
*
* \return uint16_t containing the value of the authority field.
*/
uint16_t authority() const { return Utils::net_to_host_s(dns.authority); }
uint16_t authority() const { return Utils::be_to_host(dns.authority); }
/**
* \brief Setter for the additional field.
*
* \return uint16_t containing the value of the additional field.
*/
uint16_t additional() const { return Utils::net_to_host_s(dns.additional); }
uint16_t additional() const { return Utils::be_to_host(dns.additional); }
/**
* \brief Getter for the PDU's type.
@@ -401,7 +404,7 @@ namespace Tins {
* \param ip The ip address of the resolved name.
*/
void add_answer(const std::string &name, QueryType type, QueryClass qclass,
uint32_t ttl, uint32_t ip);
uint32_t ttl, IPv4Address ip);
/**
* \brief Add a query response.
@@ -459,14 +462,14 @@ namespace Tins {
* \return std::list<Query> containing the queries in this
* record.
*/
std::list<Query> dns_queries() const;
queries_type dns_queries() const;
/**
* \brief Getter for this PDU's DNS answers
* \return std::list<Resource> containing the answers in this
* record.
*/
std::list<Resource> dns_answers();
resources_type dns_answers();
/**
* \sa PDU::clone_pdu

View File

@@ -230,28 +230,28 @@ namespace Tins {
*
* \return Returns the checksum as an unit16_t.
*/
uint16_t check() const { return Utils::net_to_host_s(this->_icmp.check); }
uint16_t check() const { return Utils::be_to_host(this->_icmp.check); }
/**
* \brief Getter for the echo id.
*
* \return Returns the echo id.
*/
uint16_t id() const { return Utils::net_to_host_s(_icmp.un.echo.id); }
uint16_t id() const { return Utils::be_to_host(_icmp.un.echo.id); }
/**
* \brief Getter for the echo sequence number.
*
* \return Returns the echo sequence number.
*/
uint16_t sequence() const { return Utils::net_to_host_s(_icmp.un.echo.sequence); }
uint16_t sequence() const { return Utils::be_to_host(_icmp.un.echo.sequence); }
/**
* \brief Getter for the gateway field.
*
* \return Returns the gateways in an unit32_t.
*/
uint32_t gateway() const { return Utils::net_to_host_l(this->_icmp.un.gateway); }
uint32_t gateway() const { return Utils::be_to_host(this->_icmp.un.gateway); }
/**
* \brief Getter for the pointer field.
@@ -265,7 +265,7 @@ namespace Tins {
*
* \return Returns the mtu value in an uint16_t.
*/
uint16_t mtu() const { return Utils::net_to_host_s(this->_icmp.un.frag.mtu); }
uint16_t mtu() const { return Utils::be_to_host(this->_icmp.un.frag.mtu); }
/**
* \brief Returns the header size.

View File

@@ -170,21 +170,21 @@ namespace Tins {
*
* \return The total length of this IP PDU.
*/
uint16_t tot_len() const { return Utils::net_to_host_s(_ip.tot_len); }
uint16_t tot_len() const { return Utils::be_to_host(_ip.tot_len); }
/**
* \brief Getter for the id field.
*
* \return The id for this IP PDU.
*/
uint16_t id() const { return Utils::net_to_host_s(_ip.id); }
uint16_t id() const { return Utils::be_to_host(_ip.id); }
/**
* \brief Getter for the fragment offset field.
*
* \return The fragment offset for this IP PDU.
*/
uint16_t frag_off() const { return Utils::net_to_host_s(_ip.frag_off); }
uint16_t frag_off() const { return Utils::be_to_host(_ip.frag_off); }
/**
* \brief Getter for the time to live field.
@@ -205,20 +205,20 @@ namespace Tins {
*
* \return The checksum for this IP PDU.
*/
uint16_t check() const { return Utils::net_to_host_s(_ip.check); }
uint16_t check() const { return Utils::be_to_host(_ip.check); }
/**
* \brief Getter for the source address field.
*
* \return The source address for this IP PDU.
*/
IPv4Address src_addr() const { return Utils::net_to_host_l(_ip.saddr); }
IPv4Address src_addr() const { return Utils::be_to_host(_ip.saddr); }
/**
* \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); }
IPv4Address dst_addr() const { return Utils::be_to_host(_ip.daddr); }
/**
* \brief Getter for the version field.

View File

@@ -141,49 +141,49 @@ namespace Tins {
*
* \return The destination port in an uint16_t.
*/
uint16_t dport() const { return Utils::net_to_host_s(_tcp.dport); }
uint16_t dport() const { return Utils::be_to_host(_tcp.dport); }
/**
* \brief Getter for the source port field.
*
* \return The source port in an uint16_t.
*/
uint16_t sport() const { return Utils::net_to_host_s(_tcp.sport); }
uint16_t sport() const { return Utils::be_to_host(_tcp.sport); }
/**
* \brief Getter for the sequence number field.
*
* \return The sequence number in an uint32_t.
*/
uint32_t seq() const { return Utils::net_to_host_l(_tcp.seq); }
uint32_t seq() const { return Utils::be_to_host(_tcp.seq); }
/**
* \brief Getter for the acknowledge number field.
*
* \return The acknowledge number in an uint32_t.
*/
uint32_t ack_seq() const { return Utils::net_to_host_l(_tcp.ack_seq); }
uint32_t ack_seq() const { return Utils::be_to_host(_tcp.ack_seq); }
/**
* \brief Getter for the window size field.
*
* \return The window size in an uint32_t.
*/
uint16_t window() const { return Utils::net_to_host_s(_tcp.window); }
uint16_t window() const { return Utils::be_to_host(_tcp.window); }
/**
* \brief Getter for the checksum field.
*
* \return The checksum field in an uint16_t.
*/
uint16_t check() const { return Utils::net_to_host_s(_tcp.check); }
uint16_t check() const { return Utils::be_to_host(_tcp.check); }
/**
* \brief Getter for the urgent pointer field.
*
* \return The urgent pointer in an uint16_t.
*/
uint16_t urg_ptr() const { return Utils::net_to_host_s(_tcp.urg_ptr); }
uint16_t urg_ptr() const { return Utils::be_to_host(_tcp.urg_ptr); }
/**
* \brief Getter for the data offset field.

View File

@@ -63,19 +63,19 @@ namespace Tins {
* \brief Getter for the destination port.
* \return The datagram's destination port.
*/
uint16_t dport() const { return Utils::net_to_host_s(_udp.dport); }
uint16_t dport() const { return Utils::be_to_host(_udp.dport); }
/**
* \brief Getter for the source port.
* \return The datagram's source port.
*/
uint16_t sport() const { return Utils::net_to_host_s(_udp.sport); }
uint16_t sport() const { return Utils::be_to_host(_udp.sport); }
/**
* \brief Getter for the length of the datagram.
* \return The length of the datagram.
*/
uint16_t length() const { return Utils::net_to_host_s(_udp.len); }
uint16_t length() const { return Utils::be_to_host(_udp.len); }
/**
* \brief Set the destination port.

View File

@@ -26,6 +26,7 @@
#ifndef WIN32
#include <ifaddrs.h>
#include <endian.h>
#endif
#include <string>
#include <set>
@@ -153,6 +154,120 @@ namespace Tins {
template<class ForwardIterator>
void route_entries(ForwardIterator output);
/**
* \brief Changes a 16-bit integral value's endianess.
*
* \param data The data to convert.
*/
inline uint16_t change_endian(uint16_t data) {
return ((data & 0xff00) >> 8) | ((data & 0x00ff) << 8);
}
/**
* \brief Changes a 32-bit integral value's endianess.
*
* \param data The data to convert.
*/
inline uint32_t change_endian(uint32_t data) {
return (((data & 0xff000000) >> 24) | ((data & 0x00ff0000) >> 8) |
((data & 0x0000ff00) << 8) | ((data & 0x000000ff) << 24));
}
/**
* \brief Changes a 64-bit integral value's endianess.
*
* \param data The data to convert.
*/
inline uint64_t change_endian(uint64_t data) {
return (((uint64_t)(change_endian((uint32_t)((data << 32) >> 32))) << 32) |
(change_endian(((uint32_t)(data >> 32)))));
}
#if __BYTE_ORDER == __LITTLE_ENDIAN
/**
* \brief Convert any integral type to big endian.
*
* \param data The data to convert.
*/
template<typename T>
inline T to_be(T data) {
return change_endian(data);
}
/**
* \brief Convert any integral type to little endian.
*
* On little endian platforms, the parameter is simply returned.
*
* \param data The data to convert.
*/
template<typename T>
inline T to_le(T data) {
return data;
}
/**
* \brief Convert any big endian value to the host's endianess.
*
* \param data The data to convert.
*/
template<typename T>
inline T be_to_host(T data) {
return change_endian(data);
}
/**
* \brief Convert any little endian value to the host's endianess.
*
* \param data The data to convert.
*/
template<typename T>
inline T le_to_host(T data) {
return data;
}
#elif __BYTE_ORDER == __BIG_ENDIAN
/**
* \brief Convert any integral type to big endian.
*
* \param data The data to convert.
*/
template<typename T>
inline T to_be(T data) {
return data;
}
/**
* \brief Convert any integral type to little endian.
*
* On little endian platforms, the parameter is simply returned.
*
* \param data The data to convert.
*/
template<typename T>
inline T to_le(T data) {
return change_endian(data);
}
/**
* \brief Convert any big endian value to the host's endianess.
*
* \param data The data to convert.
*/
template<typename T>
inline T be_to_host(T data) {
return data;
}
/**
* \brief Convert any little endian value to the host's endianess.
*
* \param data The data to convert.
*/
template<typename T>
inline T le_to_host(T data) {
return change_endian(data);
}
#endif
/** \brief Convert 16 bit integer into network byte order.
*
@@ -215,7 +330,7 @@ namespace Tins {
* \param flag The flag to use in the protocol field of the pseudo header.
* \return The pseudo header checksum.
*/
uint32_t pseudoheader_checksum(uint32_t source_ip, uint32_t dest_ip, uint32_t len, uint32_t flag);
uint32_t pseudoheader_checksum(IPv4Address source_ip, IPv4Address dest_ip, uint32_t len, uint32_t flag);
/** \brief Generic function to iterate through interface and collect
* data.

View File

@@ -52,7 +52,7 @@ ARP::ARP(IPv4Address target_ip, IPv4Address sender_ip,
}
ARP::ARP(const uint8_t *buffer, uint32_t total_sz)
: PDU(Utils::net_to_host_s(Constants::Ethernet::ARP))
: PDU(Utils::to_be<uint16_t>(Constants::Ethernet::ARP))
{
if(total_sz < sizeof(arphdr))
throw runtime_error("Not enough size for an ARP header in the buffer.");
@@ -79,11 +79,11 @@ void ARP::target_ip_addr(IPv4Address new_tgt_ip_addr) {
}
void ARP::hw_addr_format(uint16_t new_hw_addr_fmt) {
this->_arp.ar_hrd = Utils::net_to_host_s(new_hw_addr_fmt);
this->_arp.ar_hrd = Utils::to_be(new_hw_addr_fmt);
}
void ARP::prot_addr_format(uint16_t new_prot_addr_fmt) {
this->_arp.ar_pro = Utils::net_to_host_s(new_prot_addr_fmt);
this->_arp.ar_pro = Utils::to_be(new_prot_addr_fmt);
}
void ARP::hw_addr_length(uint8_t new_hw_addr_len) {
@@ -95,7 +95,7 @@ void ARP::prot_addr_length(uint8_t new_prot_addr_len) {
}
void ARP::opcode(Flags new_opcode) {
this->_arp.ar_op = Utils::net_to_host_s(new_opcode);
this->_arp.ar_op = Utils::to_be<uint16_t>(new_opcode);
}
uint32_t ARP::header_size() const {

View File

@@ -81,15 +81,15 @@ void BootP::hops(uint8_t new_hops) {
}
void BootP::xid(uint32_t new_xid) {
_bootp.xid = Utils::net_to_host_l(new_xid);
_bootp.xid = Utils::to_be(new_xid);
}
void BootP::secs(uint16_t new_secs) {
_bootp.secs = Utils::net_to_host_s(new_secs);
_bootp.secs = Utils::to_be(new_secs);
}
void BootP::padding(uint16_t new_padding) {
_bootp.padding = Utils::net_to_host_s(new_padding);
_bootp.padding = Utils::to_be(new_padding);
}
void BootP::ciaddr(IPv4Address new_ciaddr) {
@@ -126,7 +126,6 @@ void BootP::vend(uint8_t *new_vend, uint32_t size) {
void BootP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) {
assert(total_sz >= sizeof(bootphdr) + _vend_size);
std::memcpy(buffer, &_bootp, sizeof(bootphdr));
//std::memcpy(buffer + sizeof(bootphdr), _vend, _vend_size);
std::copy(_vend, _vend + _vend_size, buffer + sizeof(bootphdr));
}

View File

@@ -47,7 +47,7 @@ DHCP::DHCP(const uint8_t *buffer, uint32_t total_sz)
buffer += BootP::header_size() - vend_size();
total_sz -= BootP::header_size() - vend_size();
uint8_t args[2] = {0};
if(total_sz < sizeof(uint32_t) || *(uint32_t*)buffer != Utils::net_to_host_l(0x63825363))
if(total_sz < sizeof(uint32_t) || *(uint32_t*)buffer != Utils::to_be<uint32_t>(0x63825363))
throw std::runtime_error("Not enough size for a DHCP header in the buffer.");
buffer += sizeof(uint32_t);
total_sz -= sizeof(uint32_t);
@@ -106,7 +106,7 @@ bool DHCP::search_type_option(uint8_t *value) {
}
bool DHCP::add_server_identifier(uint32_t ip) {
ip = Utils::net_to_host_l(ip);
ip = Utils::to_be(ip);
return add_option(DHCP_SERVER_IDENTIFIER, sizeof(uint32_t), (const uint8_t*)&ip);
}
@@ -115,7 +115,7 @@ bool DHCP::search_server_identifier(uint32_t *value) {
}
bool DHCP::add_lease_time(uint32_t time) {
time = Utils::net_to_host_l(time);
time = Utils::to_be(time);
return add_option(DHCP_LEASE_TIME, sizeof(uint32_t), (const uint8_t*)&time);
}
@@ -124,7 +124,7 @@ bool DHCP::search_lease_time(uint32_t *value) {
}
bool DHCP::add_renewal_time(uint32_t time) {
time = Utils::net_to_host_l(time);
time = Utils::to_be(time);
return add_option(DHCP_RENEWAL_TIME, sizeof(uint32_t), (const uint8_t*)&time);
}
@@ -133,7 +133,7 @@ bool DHCP::search_renewal_time(uint32_t *value) {
}
bool DHCP::add_subnet_mask(uint32_t mask) {
mask = Utils::net_to_host_l(mask);
mask = Utils::to_be(mask);
return add_option(SUBNET_MASK, sizeof(uint32_t), (const uint8_t*)&mask);
}
@@ -166,7 +166,7 @@ bool DHCP::search_dns_option(std::list<uint32_t> *dns) {
}
bool DHCP::add_broadcast_option(uint32_t addr) {
addr = Utils::net_to_host_l(addr);
addr = Utils::to_be(addr);
return add_option(BROADCAST_ADDRESS, sizeof(uint32_t), (uint8_t*)&addr);
}
@@ -175,7 +175,7 @@ bool DHCP::search_broadcast_option(uint32_t *value) {
}
bool DHCP::add_requested_ip_option(uint32_t addr) {
addr = Utils::net_to_host_l(addr);
addr = Utils::to_be(addr);
return add_option(DHCP_REQUESTED_ADDRESS, sizeof(uint32_t), (uint8_t*)&addr);
}
@@ -192,7 +192,7 @@ bool DHCP::search_domain_name(std::string *value) {
}
bool DHCP::add_rebind_time(uint32_t time) {
time = Utils::net_to_host_l(time);
time = Utils::to_be(time);
return add_option(DHCP_REBINDING_TIME, sizeof(uint32_t), (uint8_t*)&time);
}
@@ -204,7 +204,7 @@ uint8_t *DHCP::serialize_list(const list<uint32_t> &int_list, uint32_t &sz) {
uint8_t *buffer = new uint8_t[int_list.size() * sizeof(uint32_t)];
uint32_t *ptr = (uint32_t*)buffer;
for(list<uint32_t>::const_iterator it = int_list.begin(); it != int_list.end(); ++it)
*(ptr++) = Utils::net_to_host_l(*it);
*(ptr++) = Utils::to_be(*it);
sz = sizeof(uint32_t) * int_list.size();
return buffer;
}
@@ -220,7 +220,7 @@ void DHCP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *pa
result = new uint8_t[_size];
uint8_t *ptr = result + sizeof(uint32_t);
// Magic cookie
*((uint32_t*)result) = Utils::net_to_host_l(0x63825363);
*((uint32_t*)result) = Utils::to_be<uint32_t>(0x63825363);
for(options_type::const_iterator it = _options.begin(); it != _options.end(); ++it) {
*(ptr++) = it->option;
*(ptr++) = it->value.size();
@@ -251,7 +251,7 @@ bool DHCP::generic_search(Options opt, std::list<uint32_t> *container) {
if((len % sizeof(uint32_t)) != 0)
return false;
while(len) {
container->push_back(Utils::net_to_host_l(*(ptr++)));
container->push_back(Utils::to_be(*(ptr++)));
len -= sizeof(uint32_t);
}
return true;
@@ -261,14 +261,13 @@ bool DHCP::generic_search(Options opt, std::string *str) {
const DHCPOption *option = search_option(opt);
if(!option)
return false;
//*str = string((const char*)option->value, option->length);
*str = string(option->value.begin(), option->value.end());
return true;
}
bool DHCP::generic_search(Options opt, uint32_t *value) {
if(generic_search<uint32_t>(opt, value)) {
*value = Utils::net_to_host_l(*value);
*value = Utils::to_be(*value);
return true;
}
return false;

View File

@@ -97,10 +97,11 @@ const uint8_t *DNS::build_resource_list(list<ResourceRecord*> &lst, const uint8_
if(ptr + sizeof(uint16_t) > ptr_end)
throw std::runtime_error("Not enough size for a given resource.");
std::auto_ptr<ResourceRecord> res;
// Probably convert to be this constant
if((*ptr & 0xc0)) {
uint16_t offset(*reinterpret_cast<const uint16_t*>(ptr));
offset = Utils::net_to_host_s(offset) & 0x3fff;
res.reset(new OffsetedResourceRecord(Utils::net_to_host_s(offset)));
offset = Utils::be_to_host(offset) & 0x3fff;
res.reset(new OffsetedResourceRecord(Utils::to_be(offset)));
ptr += sizeof(uint16_t);
}
else {
@@ -122,7 +123,7 @@ const uint8_t *DNS::build_resource_list(list<ResourceRecord*> &lst, const uint8_
// Store the option size.
res->data.resize(
Utils::net_to_host_s(*reinterpret_cast<const uint16_t*>(ptr))
Utils::to_be(*reinterpret_cast<const uint16_t*>(ptr))
);
ptr += sizeof(uint16_t);
if(ptr + res->data.size() > ptr_end)
@@ -130,7 +131,7 @@ const uint8_t *DNS::build_resource_list(list<ResourceRecord*> &lst, const uint8_
if(contains_dname(res->info.type))
std::copy(ptr, ptr + res->data.size(), res->data.begin());
else
*(uint32_t*)&res->data[0] = Utils::net_to_host_l(*(uint32_t*)ptr);
*(uint32_t*)&res->data[0] = Utils::to_be(*(uint32_t*)ptr);
ptr += res->data.size();
extra_size += ptr - this_opt_start;
@@ -145,7 +146,7 @@ uint32_t DNS::header_size() const {
}
void DNS::id(uint16_t new_id) {
dns.id = Utils::net_to_host_s(new_id);
dns.id = Utils::to_be(new_id);
}
void DNS::type(QRType new_qr) {
@@ -189,8 +190,9 @@ void DNS::rcode(uint8_t new_rcode) {
}
bool DNS::contains_dname(uint16_t type) {
return type == Utils::net_to_host_s(MX) || type == Utils::net_to_host_s(CNAME) ||
type == Utils::net_to_host_s(PTR) || type == Utils::net_to_host_s(NS);
type = Utils::be_to_host(type);
return type == MX || type == CNAME ||
type == PTR || type == NS;
}
void DNS::add_query(const string &name, QueryType type, QueryClass qclass) {
@@ -199,11 +201,11 @@ void DNS::add_query(const string &name, QueryType type, QueryClass qclass) {
queries.push_back(
Query(new_str,
Utils::net_to_host_s(type),
Utils::net_to_host_s(qclass))
Utils::to_be<uint16_t>(type),
Utils::to_be<uint16_t>(qclass))
);
extra_size += new_str.size() + 1 + (sizeof(uint16_t) << 1);
dns.questions = Utils::net_to_host_s(queries.size());
dns.questions = Utils::to_be<uint16_t>(queries.size());
}
void DNS::add_query(const Query &query) {
@@ -214,10 +216,10 @@ void DNS::add_query(const Query &query) {
);
}
void DNS::add_answer(const string &name, QueryType type, QueryClass qclass, uint32_t ttl, uint32_t ip) {
ResourceRecord *res = make_record(name, type, qclass, ttl, ip);
void DNS::add_answer(const string &name, QueryType type, QueryClass qclass, uint32_t ttl, IPv4Address ip) {
ResourceRecord *res = make_record(name, type, qclass, ttl, (uint32_t)ip);
ans.push_back(res);
dns.answers = Utils::net_to_host_s(ans.size());
dns.answers = Utils::to_be<uint16_t>(ans.size());
}
void DNS::add_answer(const std::string &name, QueryType type, QueryClass qclass,
@@ -226,31 +228,31 @@ void DNS::add_answer(const std::string &name, QueryType type, QueryClass qclass,
parse_domain_name(dname, new_str);
ResourceRecord *res = make_record(name, type, qclass, ttl, new_str);
ans.push_back(res);
dns.answers = Utils::net_to_host_s(ans.size());
dns.answers = Utils::to_be<uint16_t>(ans.size());
}
void DNS::add_answer(const std::string &name, QueryType type, QueryClass qclass,
uint32_t ttl, const uint8_t *data, uint32_t sz) {
ResourceRecord *res = make_record(name, type, qclass, ttl, data, sz);
ans.push_back(res);
dns.answers = Utils::net_to_host_s(ans.size());
dns.answers = Utils::to_be<uint16_t>(ans.size());
}
void DNS::add_authority(const string &name, QueryType type,
QueryClass qclass, uint32_t ttl, const uint8_t *data, uint32_t sz) {
ResourceRecord *res = make_record(name, type, qclass, ttl, data, sz);
arity.push_back(res);
dns.authority = Utils::net_to_host_s(arity.size());
dns.authority = Utils::to_be<uint16_t>(arity.size());
}
void DNS::add_additional(const string &name, QueryType type, QueryClass qclass, uint32_t ttl, uint32_t ip) {
ResourceRecord *res = make_record(name, type, qclass, ttl, ip);
addit.push_back(res);
dns.additional = Utils::net_to_host_s(addit.size());
dns.additional = Utils::to_be<uint16_t>(addit.size());
}
DNS::ResourceRecord *DNS::make_record(const std::string &name, QueryType type, QueryClass qclass, uint32_t ttl, uint32_t ip) {
ip = Utils::net_to_host_l(ip);
ip = Utils::to_be(ip);
return make_record(name, type, qclass, ttl, reinterpret_cast<uint8_t*>(&ip), sizeof(ip));
}
@@ -264,12 +266,12 @@ DNS::ResourceRecord *DNS::make_record(const std::string &name, QueryType type, Q
uint16_t index = find_domain_name(nm);
ResourceRecord *res;
if(index)
res = new OffsetedResourceRecord(Utils::net_to_host_s(index), ptr, len);
res = new OffsetedResourceRecord(Utils::to_be(index), ptr, len);
else
res = new NamedResourceRecord(nm, ptr, len);
res->info.type = Utils::net_to_host_s(type);
res->info.qclass = Utils::net_to_host_s(qclass);
res->info.ttl = Utils::net_to_host_l(ttl);
res->info.type = Utils::to_be<uint16_t>(type);
res->info.qclass = Utils::to_be<uint16_t>(qclass);
res->info.ttl = Utils::to_be(ttl);
extra_size += res->size();
return res;
}
@@ -384,7 +386,7 @@ uint32_t DNS::build_suffix_map(uint32_t index, const list<ResourceRecord*> &lst)
index += sizeof(ResourceRecord::Info) + sizeof(uint16_t);
uint32_t sz((*it)->data_size());
const uint8_t *ptr = (*it)->data_pointer();
if((*it)->info.type == Utils::net_to_host_s(MX)) {
if(Utils::be_to_host((*it)->info.type) == MX) {
ptr += 2;
sz -= 2;
index += 2;
@@ -418,7 +420,7 @@ void DNS::compose_name(const uint8_t *ptr, uint32_t sz, std::string &out) {
if(i && ptr[i])
out.push_back('.');
if((ptr[i] & 0xc0)) {
uint16_t index = Utils::net_to_host_s(*((uint16_t*)(ptr + i)));
uint16_t index = Utils::be_to_host(*((uint16_t*)(ptr + i)));
index &= 0x3fff;
SuffixMap::iterator it(suffixes.find(index));
SuffixIndices::iterator suff_it(suffix_indices.find(index));
@@ -446,7 +448,7 @@ void DNS::compose_name(const uint8_t *ptr, uint32_t sz, std::string &out) {
else {
uint8_t suff_sz(ptr[i]);
i++;
if(i + suff_sz < sz)
if(i + suff_sz <= sz)
out.append(ptr + i, ptr + i + suff_sz);
i += suff_sz;
}
@@ -472,31 +474,31 @@ void DNS::convert_resources(const ResourcesType &lst, std::list<Resource> &res)
if(sz == 4)
addr = Utils::ip_to_string(*(uint32_t*)ptr);
else {
if((*it)->info.type == Utils::net_to_host_s(MX)) {
if(Utils::be_to_host((*it)->info.type) == MX) {
ptr += 2;
sz -= 2;
}
compose_name(ptr, sz, addr);
}
res.push_back(
Resource(dname, addr, Utils::net_to_host_s((*it)->info.type),
Utils::net_to_host_s((*it)->info.qclass), Utils::net_to_host_l((*it)->info.ttl))
Resource(dname, addr, Utils::be_to_host((*it)->info.type),
Utils::to_be((*it)->info.qclass), Utils::be_to_host((*it)->info.ttl))
);
}
}
list<DNS::Query> DNS::dns_queries() const {
list<Query> output;
DNS::queries_type DNS::dns_queries() const {
queries_type output;
for(std::list<Query>::const_iterator it(queries.begin()); it != queries.end(); ++it) {
string dn;
unparse_domain_name(it->name, dn);
output.push_back(Query(dn, Utils::net_to_host_s(it->type), Utils::net_to_host_s(it->qclass)));
output.push_back(Query(dn, Utils::be_to_host(it->type), Utils::be_to_host(it->qclass)));
}
return output;
}
list<DNS::Resource> DNS::dns_answers() {
list<Resource> res;
DNS::resources_type DNS::dns_answers() {
resources_type res;
convert_resources(ans, res);
return res;
}
@@ -523,7 +525,7 @@ uint32_t DNS::ResourceRecord::write(uint8_t *buffer) const {
buffer += sz;
std::memcpy(buffer, &info, sizeof(info));
buffer += sizeof(info);
*((uint16_t*)buffer) = Utils::net_to_host_s(data.size());
*((uint16_t*)buffer) = Utils::to_be(data.size());
buffer += sizeof(uint16_t);
std::copy(data.begin(), data.end(), buffer);
return sz + sizeof(info) + sizeof(uint16_t) + data.size();

View File

@@ -66,23 +66,23 @@ void Tins::ICMP::type(Flags new_type) {
}
void Tins::ICMP::check(uint16_t new_check) {
_icmp.check = Utils::net_to_host_s(new_check);
_icmp.check = Utils::to_be(new_check);
}
void Tins::ICMP::id(uint16_t new_id) {
_icmp.un.echo.id = Utils::net_to_host_s(new_id);
_icmp.un.echo.id = Utils::to_be(new_id);
}
void Tins::ICMP::sequence(uint16_t new_seq) {
_icmp.un.echo.sequence = Utils::net_to_host_s(new_seq);
_icmp.un.echo.sequence = Utils::to_be(new_seq);
}
void Tins::ICMP::gateway(uint32_t new_gw) {
_icmp.un.gateway = Utils::net_to_host_l(new_gw);
_icmp.un.gateway = Utils::to_be(new_gw);
}
void Tins::ICMP::mtu(uint16_t new_mtu) {
_icmp.un.frag.mtu = Utils::net_to_host_s(new_mtu);
_icmp.un.frag.mtu = Utils::to_be(new_mtu);
}
void Tins::ICMP::pointer(uint8_t new_pointer) {
@@ -171,7 +171,7 @@ void Tins::ICMP::write_serialization(uint8_t *buffer, uint32_t total_sz, const P
Utils::do_checksum((uint8_t*)&_icmp, ((uint8_t*)&_icmp) + sizeof(icmphdr));
while (checksum >> 16)
checksum = (checksum & 0xffff) + (checksum >> 16);
_icmp.check = Utils::net_to_host_s(~checksum);
_icmp.check = Utils::to_be<uint16_t>(~checksum);
}
memcpy(buffer, &_icmp, sizeof(icmphdr));
_icmp.check = 0;

View File

@@ -145,15 +145,15 @@ void Tins::IP::tos(uint8_t new_tos) {
}
void Tins::IP::tot_len(uint16_t new_tot_len) {
_ip.tot_len = Utils::net_to_host_s(new_tot_len);
_ip.tot_len = Utils::to_be(new_tot_len);
}
void Tins::IP::id(uint16_t new_id) {
_ip.id = Utils::net_to_host_s(new_id);
_ip.id = Utils::to_be(new_id);
}
void Tins::IP::frag_off(uint16_t new_frag_off) {
_ip.frag_off = Utils::net_to_host_s(new_frag_off);
_ip.frag_off = Utils::to_be(new_frag_off);
}
void Tins::IP::ttl(uint8_t new_ttl) {
@@ -165,7 +165,7 @@ void Tins::IP::protocol(uint8_t new_protocol) {
}
void Tins::IP::check(uint16_t new_check) {
_ip.check = Utils::net_to_host_s(new_check);
_ip.check = Utils::to_be(new_check);
}
@@ -304,7 +304,7 @@ void Tins::IP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU
uint32_t checksum = Utils::do_checksum(buffer, buffer + sizeof(_ip) + _padded_options_size);
while (checksum >> 16)
checksum = (checksum & 0xffff) + (checksum >> 16);
((iphdr*)buffer)->check = Utils::net_to_host_s(~checksum);
((iphdr*)buffer)->check = Utils::to_be<uint16_t>(~checksum);
this->check(0);
}
}
@@ -332,7 +332,7 @@ Tins::PDU *Tins::IP::clone_packet(const uint8_t *ptr, uint32_t total_sz) {
if((child = PDU::clone_inner_pdu(ptr + sizeof(_ip), total_sz - sizeof(_ip))) == 0)
return 0;
}
cloned = new IP(ptr, std::min(total_sz, (uint32_t)(Utils::net_to_host_s(ip_ptr->tot_len) * sizeof(uint32_t))));
cloned = new IP(ptr, std::min(total_sz, (uint32_t)(Utils::be_to_host(ip_ptr->tot_len) * sizeof(uint32_t))));
cloned->inner_pdu(child);
return cloned;
}

View File

@@ -31,7 +31,9 @@
const uint16_t Tins::TCP::DEFAULT_WINDOW = 32678;
Tins::TCP::TCP(uint16_t dport, uint16_t sport) : PDU(Constants::IP::PROTO_TCP), _options_size(0), _total_options_size(0) {
Tins::TCP::TCP(uint16_t dport, uint16_t sport)
: PDU(Constants::IP::PROTO_TCP), _options_size(0), _total_options_size(0)
{
std::memset(&_tcp, 0, sizeof(tcphdr));
this->dport(dport);
this->sport(sport);
@@ -39,7 +41,9 @@ Tins::TCP::TCP(uint16_t dport, uint16_t sport) : PDU(Constants::IP::PROTO_TCP),
window(DEFAULT_WINDOW);
}
Tins::TCP::TCP(const uint8_t *buffer, uint32_t total_sz) : PDU(Constants::IP::PROTO_TCP) {
Tins::TCP::TCP(const uint8_t *buffer, uint32_t total_sz)
: PDU(Constants::IP::PROTO_TCP)
{
if(total_sz < sizeof(tcphdr))
throw std::runtime_error("Not enough size for an TCP header in the buffer.");
std::memcpy(&_tcp, buffer, sizeof(tcphdr));
@@ -84,31 +88,31 @@ Tins::TCP::TCP(const uint8_t *buffer, uint32_t total_sz) : PDU(Constants::IP::PR
}
void Tins::TCP::dport(uint16_t new_dport) {
_tcp.dport = Utils::net_to_host_s(new_dport);
_tcp.dport = Utils::to_be(new_dport);
}
void Tins::TCP::sport(uint16_t new_sport) {
_tcp.sport = Utils::net_to_host_s(new_sport);
_tcp.sport = Utils::to_be(new_sport);
}
void Tins::TCP::seq(uint32_t new_seq) {
_tcp.seq = Utils::net_to_host_l(new_seq);
_tcp.seq = Utils::to_be(new_seq);
}
void Tins::TCP::ack_seq(uint32_t new_ack_seq) {
_tcp.ack_seq = Utils::net_to_host_l(new_ack_seq);
_tcp.ack_seq = Utils::to_be(new_ack_seq);
}
void Tins::TCP::window(uint16_t new_window) {
_tcp.window = Utils::net_to_host_s(new_window);
_tcp.window = Utils::to_be(new_window);
}
void Tins::TCP::check(uint16_t new_check) {
_tcp.check = Utils::net_to_host_s(new_check);
_tcp.check = Utils::to_be(new_check);
}
void Tins::TCP::urg_ptr(uint16_t new_urg_ptr) {
_tcp.urg_ptr = Utils::net_to_host_s(new_urg_ptr);
_tcp.urg_ptr = Utils::to_be(new_urg_ptr);
}
void Tins::TCP::payload(uint8_t *new_payload, uint32_t new_payload_size) {
@@ -120,14 +124,14 @@ void Tins::TCP::data_offset(uint8_t new_doff) {
}
void Tins::TCP::add_mss_option(uint16_t value) {
value = Utils::net_to_host_s(value);
value = Utils::to_be(value);
add_option(MSS, 2, (uint8_t*)&value);
}
bool Tins::TCP::search_mss_option(uint16_t *value) {
if(!generic_search(MSS, value))
return false;
*value = Utils::net_to_host_s(*value);
*value = Utils::to_be(*value);
return true;
}
@@ -153,7 +157,7 @@ void Tins::TCP::add_sack_option(const std::list<uint32_t> &edges) {
value = new uint32_t[edges.size()];
uint32_t *ptr = value;
for(std::list<uint32_t>::const_iterator it = edges.begin(); it != edges.end(); ++it)
*(ptr++) = Utils::net_to_host_l(*it);
*(ptr++) = Utils::to_be(*it);
}
add_option(SACK, (uint8_t)(sizeof(uint32_t) * edges.size()), (const uint8_t*)value);
delete[] value;
@@ -166,12 +170,12 @@ bool Tins::TCP::search_sack_option(std::list<uint32_t> *edges) {
const uint32_t *ptr = (const uint32_t*)&option->value[0];
const uint32_t *end = ptr + (option->value.size() / sizeof(uint32_t));
while(ptr < end)
edges->push_back(Utils::net_to_host_l(*(ptr++)));
edges->push_back(Utils::to_be(*(ptr++)));
return true;
}
void Tins::TCP::add_timestamp_option(uint32_t value, uint32_t reply) {
uint64_t buffer = ((uint64_t)Utils::net_to_host_l(reply) << 32) | Utils::net_to_host_l(value);
uint64_t buffer = ((uint64_t)Utils::to_be(reply) << 32) | Utils::to_be(value);
add_option(TSOPT, 8, (uint8_t*)&buffer);
}
@@ -180,8 +184,8 @@ bool Tins::TCP::search_timestamp_option(uint32_t *value, uint32_t *reply) {
if(!option || option->value.size() != (sizeof(uint32_t) << 1))
return false;
const uint32_t *ptr = (const uint32_t*)&option->value[0];
*value = Utils::net_to_host_l(*(ptr++));
*reply = Utils::net_to_host_l(*(ptr));
*value = Utils::to_be(*(ptr++));
*reply = Utils::to_be(*(ptr));
return true;
}
@@ -293,13 +297,14 @@ void Tins::TCP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PD
const Tins::IP *ip_packet = dynamic_cast<const Tins::IP*>(parent);
memcpy(tcp_start, &_tcp, sizeof(tcphdr));
if(!_tcp.check && ip_packet) {
uint32_t checksum = Utils::pseudoheader_checksum(Utils::net_to_host_l(ip_packet->src_addr()),
Utils::net_to_host_l(ip_packet->dst_addr()),
uint32_t checksum = Utils::pseudoheader_checksum(ip_packet->src_addr(),
ip_packet->dst_addr(),
size(), Constants::IP::PROTO_TCP) +
Utils::do_checksum(tcp_start, tcp_start + total_sz);
while (checksum >> 16)
checksum = (checksum & 0xffff) + (checksum >> 16);
((tcphdr*)tcp_start)->check = Utils::net_to_host_s(~checksum);
((tcphdr*)tcp_start)->check = Utils::to_be<uint16_t>(~checksum);
}
_tcp.check = 0;
}

View File

@@ -27,14 +27,18 @@
#include "ip.h"
#include "rawpdu.h"
Tins::UDP::UDP(uint16_t dport, uint16_t sport, PDU *child) : PDU(Constants::IP::PROTO_UDP, child) {
Tins::UDP::UDP(uint16_t dport, uint16_t sport, PDU *child)
: PDU(Constants::IP::PROTO_UDP, child)
{
this->dport(dport);
this->sport(sport);
_udp.check = 0;
_udp.len = 0;
}
Tins::UDP::UDP(const uint8_t *buffer, uint32_t total_sz) : PDU(Constants::IP::PROTO_UDP) {
Tins::UDP::UDP(const uint8_t *buffer, uint32_t total_sz)
: PDU(Constants::IP::PROTO_UDP)
{
if(total_sz < sizeof(udphdr))
throw std::runtime_error("Not enough size for an UDP header in the buffer.");
std::memcpy(&_udp, buffer, sizeof(udphdr));
@@ -48,15 +52,15 @@ void Tins::UDP::payload(uint8_t *new_payload, uint32_t new_payload_size) {
}
void Tins::UDP::dport(uint16_t new_dport) {
_udp.dport = Utils::net_to_host_s(new_dport);
_udp.dport = Utils::to_be(new_dport);
}
void Tins::UDP::sport(uint16_t new_sport) {
_udp.sport = Utils::net_to_host_s(new_sport);
_udp.sport = Utils::to_be(new_sport);
}
void Tins::UDP::length(uint16_t new_len) {
_udp.len = Utils::net_to_host_s(new_len);
_udp.len = Utils::to_be(new_len);
}
uint32_t Tins::UDP::header_size() const {
@@ -74,7 +78,7 @@ void Tins::UDP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PD
Utils::do_checksum(buffer, buffer + total_sz);
while (checksum >> 16)
checksum = (checksum & 0xffff)+(checksum >> 16);
((udphdr*)buffer)->check = Utils::net_to_host_s(~checksum);
((udphdr*)buffer)->check = Utils::to_be<uint16_t>(~checksum);
}
_udp.check = 0;
}

View File

@@ -201,12 +201,14 @@ uint32_t Tins::Utils::do_checksum(const uint8_t *start, const uint8_t *end) {
return checksum + padding;
}
uint32_t Tins::Utils::pseudoheader_checksum(uint32_t source_ip, uint32_t dest_ip, uint32_t len, uint32_t flag) {
uint32_t Tins::Utils::pseudoheader_checksum(IPv4Address source_ip, IPv4Address dest_ip, uint32_t len, uint32_t flag) {
uint32_t checksum(0);
uint16_t *ptr = (uint16_t*)&source_ip;
uint32_t source_ip_int = Utils::to_be<uint32_t>(source_ip),
dest_ip_int = Utils::to_be<uint32_t>(dest_ip);
uint16_t *ptr = (uint16_t*)&source_ip_int;
checksum += (uint32_t)(*ptr) + (uint32_t)(*(ptr+1));
ptr = (uint16_t*)&dest_ip;
ptr = (uint16_t*)&dest_ip_int;
checksum += (uint32_t)(*ptr) + (uint32_t)(*(ptr+1));
checksum += flag + len;
return checksum;

View File

@@ -174,14 +174,45 @@ TEST_F(DNSTest, Question) {
DNS dns;
dns.add_query("www.example.com", DNS::A, DNS::IN);
dns.add_query("www.example2.com", DNS::MX, DNS::IN);
EXPECT_EQ(dns.questions(), 2);
ASSERT_EQ(dns.questions(), 2);
DNS::queries_type queries(dns.dns_queries());
for(DNS::queries_type::const_iterator it = queries.begin(); it != queries.end(); ++it) {
EXPECT_TRUE(it->name == "www.example.com" || it->name == "www.example2.com");
if(it->name == "www.example.com") {
EXPECT_EQ(it->type, DNS::A);
EXPECT_EQ(it->qclass, DNS::IN);
}
else if(it->name == "www.example2.com") {
EXPECT_EQ(it->type, DNS::MX);
EXPECT_EQ(it->qclass, DNS::IN);
}
}
}
TEST_F(DNSTest, Answers) {
DNS dns;
dns.add_answer("www.example.com", DNS::A, DNS::IN, 0x762, Utils::ip_to_int("127.0.0.1"));
dns.add_answer("www.example2.com", DNS::MX, DNS::IN, 0x762, Utils::ip_to_int("127.0.0.1"));
EXPECT_EQ(dns.answers(), 2);
dns.add_answer("www.example.com", DNS::A, DNS::IN, 0x762, IPv4Address("127.0.0.1"));
dns.add_answer("www.example2.com", DNS::MX, DNS::IN, 0x762, IPv4Address("127.0.0.1"));
ASSERT_EQ(dns.answers(), 2);
DNS::resources_type resources(dns.dns_answers());
for(DNS::resources_type::const_iterator it = resources.begin(); it != resources.end(); ++it) {
std::cout << it->dname << "\n";
EXPECT_TRUE(it->dname == "www.example.com" || it->dname == "www.example2.com");
if(it->dname == "www.example.com") {
EXPECT_EQ(it->type, DNS::A);
EXPECT_EQ(it->ttl, 0x762);
EXPECT_EQ(it->addr, "127.0.0.1");
EXPECT_EQ(it->qclass, DNS::IN);
}
else if(it->dname == "www.example2.com") {
EXPECT_EQ(it->type, DNS::MX);
EXPECT_EQ(it->ttl, 0x762);
EXPECT_EQ(it->addr, "127.0.0.1");
EXPECT_EQ(it->qclass, DNS::IN);
}
}
}