1
0
mirror of https://github.com/mfontanini/libtins synced 2026-01-30 13:34:27 +01:00

Added some serialization tests to every PDU.

This commit is contained in:
Matias Fontanini
2012-08-26 12:50:30 -03:00
parent ba17ca3045
commit 1b08d1af71
19 changed files with 331 additions and 166 deletions

View File

@@ -35,14 +35,14 @@ const uint32_t DHCP::MAX_DHCP_SIZE = 312;
/* Magic cookie: uint32_t.
* end of options: 1 byte. */
DHCP::DHCP() : _size(sizeof(uint32_t) + 1) {
DHCP::DHCP() : _size(sizeof(uint32_t)) {
opcode(BOOTREQUEST);
htype(1); //ethernet
hlen(EthernetII::ADDR_SIZE);
}
DHCP::DHCP(const uint8_t *buffer, uint32_t total_sz)
: BootP(buffer, total_sz, 0), _size(sizeof(uint32_t) + 1)
: BootP(buffer, total_sz, 0), _size(sizeof(uint32_t))
{
buffer += BootP::header_size() - vend_size();
total_sz -= BootP::header_size() - vend_size();
@@ -55,23 +55,18 @@ DHCP::DHCP(const uint8_t *buffer, uint32_t total_sz)
for(unsigned i(0); i < 2; ++i) {
args[i] = *(buffer++);
total_sz--;
if(args[0] == END || args[0] == PAD)
if(args[0] == END || args[0] == PAD) {
args[1] = 0;
i = 2;
}
else if(!total_sz)
throw std::runtime_error("Not enough size for a DHCP header in the buffer.");
}
// If the END-OF-OPTIONS was not found...
if(args[0] != END && args[0] != PAD) {
// Not enough size for this option
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);
buffer += args[1];
total_sz -= args[1];
}
// Otherwise, break the loop.
else
total_sz = 0;
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);
buffer += args[1];
total_sz -= args[1];
}
}
@@ -102,6 +97,10 @@ bool DHCP::add_type_option(Flags type) {
return add_option(DHCP_MESSAGE_TYPE, sizeof(uint8_t), &int_type);
}
bool DHCP::add_end_option() {
return add_option(DHCP_MESSAGE_TYPE, 0, 0);
}
bool DHCP::search_type_option(uint8_t *value) {
return generic_search(DHCP_MESSAGE_TYPE, value);
}
@@ -239,7 +238,7 @@ void DHCP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *pa
ptr += it->value.size();
}
// End of options
result[_size-1] = END;
//result[_size-1] = END;
vend(result, _size);
}
BootP::write_serialization(buffer, total_sz, parent);

View File

@@ -41,6 +41,7 @@ DNS::DNS(const uint8_t *buffer, uint32_t total_sz) : PDU(255), extra_size(0) {
const uint8_t *end(buffer + total_sz);
uint16_t nquestions(questions());
buffer += sizeof(dnshdr);
total_sz -= sizeof(dnshdr);
for(uint16_t i(0); i < nquestions; ++i) {
const uint8_t *ptr(buffer);
while(ptr < end && *ptr)
@@ -105,10 +106,10 @@ const uint8_t *DNS::build_resource_list(list<ResourceRecord*> &lst, const uint8_
ptr += sizeof(uint16_t);
}
else {
const uint8_t *str_end(ptr), *end(ptr + sz);
while(str_end < end && *str_end)
const uint8_t *str_end(ptr);
while(str_end < ptr_end && *str_end)
str_end++;
if(str_end == end)
if(str_end == ptr_end)
throw std::runtime_error("Not enough size for a resource domain name.");
//str_end++;
res.reset(new NamedResourceRecord(string(ptr, str_end)));
@@ -123,7 +124,7 @@ const uint8_t *DNS::build_resource_list(list<ResourceRecord*> &lst, const uint8_
// Store the option size.
res->data.resize(
Utils::host_to_be(*reinterpret_cast<const uint16_t*>(ptr))
Utils::be_to_host(*reinterpret_cast<const uint16_t*>(ptr))
);
ptr += sizeof(uint16_t);
if(ptr + res->data.size() > ptr_end)
@@ -131,7 +132,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 if(res->data.size() == sizeof(uint32_t))
*(uint32_t*)&res->data[0] = Utils::host_to_be(*(uint32_t*)ptr);
*(uint32_t*)&res->data[0] = Utils::be_to_host(*(uint32_t*)ptr);
else
throw std::runtime_error("Not enough size for resource data");

View File

@@ -47,10 +47,6 @@ Tins::IP::IP(IPv4Address ip_dst, IPv4Address ip_src, PDU *child) :
this->src_addr(ip_src);
}
Tins::IP::IP() : PDU(IPPROTO_IP) {
init_ip_fields();
}
Tins::IP::IP(const uint8_t *buffer, uint32_t total_sz)
: PDU(Constants::IP::PROTO_IP)
{

View File

@@ -49,10 +49,6 @@ IPv4Address::operator uint32_t() const {
return Utils::host_to_be(ip_addr);
}
IPv4Address::operator std::string() const {
return Utils::ip_to_string(ip_addr);
}
std::string IPv4Address::to_string() const {
return Utils::ip_to_string(ip_addr);
}

View File

@@ -31,6 +31,7 @@
#include <cassert>
#include <errno.h>
#include <cstring>
#include <vector>
#include <ctime>
#include "packetsender.h"
@@ -102,11 +103,11 @@ bool Tins::PacketSender::send_l2(PDU *pdu, struct sockaddr* link_addr, uint32_t
if(!open_l2_socket())
return false;
uint32_t sz;
int sock = _sockets[ETHER_SOCKET];
uint8_t *buffer = pdu->serialize(sz);
bool ret_val = (sendto(sock, buffer, sz, 0, link_addr, len_addr) != -1);
delete[] buffer;
PDU::serialization_type buffer = pdu->serialize();
if(buffer.size() == 0)
return false;
bool ret_val = (sendto(sock, &buffer[0], buffer.size(), 0, link_addr, len_addr) != -1);
return ret_val;
}
@@ -128,11 +129,9 @@ bool Tins::PacketSender::send_l3(PDU *pdu, struct sockaddr* link_addr, uint32_t
if(!open_l3_socket(type))
ret_val = false;
if (ret_val) {
uint32_t sz;
int sock = _sockets[type];
uint8_t *buffer = pdu->serialize(sz);
ret_val = (sendto(sock, buffer, sz, 0, link_addr, len_addr) != -1);
delete[] buffer;
PDU::serialization_type buffer = pdu->serialize();
ret_val = (sendto(sock, &buffer[0], buffer.size(), 0, link_addr, len_addr) != -1);
}
return ret_val;
}

View File

@@ -25,32 +25,33 @@
#include "pdu.h"
#include "rawpdu.h"
namespace Tins {
Tins::PDU::PDU(uint32_t flag, PDU *next_pdu) : _flag(flag), _inner_pdu(next_pdu) {
PDU::PDU(uint32_t flag, PDU *next_pdu) : _flag(flag), _inner_pdu(next_pdu) {
}
Tins::PDU::PDU(const PDU &other) : _inner_pdu(0) {
PDU::PDU(const PDU &other) : _inner_pdu(0) {
_flag = other.flag();
copy_inner_pdu(other);
}
Tins::PDU &Tins::PDU::operator=(const PDU &other) {
PDU &PDU::operator=(const PDU &other) {
_flag = other.flag();
copy_inner_pdu(other);
return *this;
}
Tins::PDU::~PDU() {
PDU::~PDU() {
delete _inner_pdu;
}
void Tins::PDU::copy_inner_pdu(const PDU &pdu) {
void PDU::copy_inner_pdu(const PDU &pdu) {
if(pdu.inner_pdu())
inner_pdu(pdu.inner_pdu()->clone_pdu());
}
uint32_t Tins::PDU::size() const {
uint32_t PDU::size() const {
uint32_t sz = header_size() + trailer_size();
const PDU *ptr(_inner_pdu);
while(ptr) {
@@ -60,23 +61,24 @@ uint32_t Tins::PDU::size() const {
return sz;
}
void Tins::PDU::flag(uint32_t new_flag) {
void PDU::flag(uint32_t new_flag) {
_flag = new_flag;
}
void Tins::PDU::inner_pdu(PDU *next_pdu) {
void PDU::inner_pdu(PDU *next_pdu) {
delete _inner_pdu;
_inner_pdu = next_pdu;
}
uint8_t *Tins::PDU::serialize(uint32_t &sz) {
sz = size();
uint8_t *buffer = new uint8_t[sz];
serialize(buffer, sz, 0);
PDU::serialization_type PDU::serialize() {
std::vector<uint8_t> buffer(size());
serialize(&buffer[0], buffer.size(), 0);
// Copy elision, do your magic
return buffer;
}
void Tins::PDU::serialize(uint8_t *buffer, uint32_t total_sz, const PDU *parent) {
void PDU::serialize(uint8_t *buffer, uint32_t total_sz, const PDU *parent) {
uint32_t sz = header_size() + trailer_size();
/* Must not happen... */
assert(total_sz >= sz);
@@ -85,7 +87,7 @@ void Tins::PDU::serialize(uint8_t *buffer, uint32_t total_sz, const PDU *parent)
write_serialization(buffer, total_sz, parent);
}
Tins::PDU *Tins::PDU::clone_inner_pdu(const uint8_t *ptr, uint32_t total_sz) {
PDU *PDU::clone_inner_pdu(const uint8_t *ptr, uint32_t total_sz) {
PDU *child = 0;
if(inner_pdu()) {
child = inner_pdu()->clone_packet(ptr, total_sz);
@@ -97,7 +99,7 @@ Tins::PDU *Tins::PDU::clone_inner_pdu(const uint8_t *ptr, uint32_t total_sz) {
return child;
}
Tins::PDU *Tins::PDU::clone_packet() const {
PDU *PDU::clone_packet() const {
PDU *ret = clone_pdu();
if(ret) {
PDU *ptr = 0, *last = ret;
@@ -109,3 +111,4 @@ Tins::PDU *Tins::PDU::clone_packet() const {
}
return ret;
}
}