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

Fixed bugs in IP and DNS.

This commit is contained in:
Matias Fontanini
2012-08-04 18:46:22 -03:00
parent c5fce38c3a
commit e2ad917549
4 changed files with 186 additions and 20 deletions

View File

@@ -163,7 +163,7 @@ namespace Tins {
* *
* \return uint16_t containing the value of the id field. * \return uint16_t containing the value of the id field.
*/ */
uint16_t id() { return dns.id; } uint16_t id() const { return Utils::net_to_host_s(dns.id); }
/** /**
* \brief Setter for the query response field. * \brief Setter for the query response field.
@@ -171,14 +171,14 @@ namespace Tins {
* \return QRType containing the value of the query response * \return QRType containing the value of the query response
* field. * field.
*/ */
QRType type() { return static_cast<QRType>(dns.qr); } QRType type() const { return static_cast<QRType>(dns.qr); }
/** /**
* \brief Setter for the opcode field. * \brief Setter for the opcode field.
* *
* \return uint8_t containing the value of the opcode field. * \return uint8_t containing the value of the opcode field.
*/ */
uint8_t opcode() { return dns.opcode; } uint8_t opcode() const { return dns.opcode; }
/** /**
* \brief Setter for the authoritative answer field. * \brief Setter for the authoritative answer field.
@@ -186,14 +186,14 @@ namespace Tins {
* \return uint8_t containing the value of the authoritative * \return uint8_t containing the value of the authoritative
* answer field. * answer field.
*/ */
uint8_t authoritative_answer() { return dns.aa; } uint8_t authoritative_answer() const { return dns.aa; }
/** /**
* \brief Setter for the truncated field. * \brief Setter for the truncated field.
* *
* \return uint8_t containing the value of the truncated field. * \return uint8_t containing the value of the truncated field.
*/ */
uint8_t truncated() { return dns.tc; } uint8_t truncated() const { return dns.tc; }
/** /**
* \brief Setter for the recursion desired field. * \brief Setter for the recursion desired field.
@@ -201,7 +201,7 @@ namespace Tins {
* \return uint8_t containing the value of the recursion * \return uint8_t containing the value of the recursion
* desired field. * desired field.
*/ */
uint8_t recursion_desired() { return dns.rd; } uint8_t recursion_desired() const { return dns.rd; }
/** /**
* \brief Setter for the recursion available field. * \brief Setter for the recursion available field.
@@ -209,14 +209,14 @@ namespace Tins {
* \return uint8_t containing the value of the recursion * \return uint8_t containing the value of the recursion
* available field. * available field.
*/ */
uint8_t recursion_available() { return dns.ra; } uint8_t recursion_available() const { return dns.ra; }
/** /**
* \brief Setter for the z desired field. * \brief Setter for the z desired field.
* *
* \return uint8_t containing the value of the z field. * \return uint8_t containing the value of the z field.
*/ */
uint8_t z() { return dns.z; } uint8_t z() const { return dns.z; }
/** /**
* \brief Setter for the authenticated data field. * \brief Setter for the authenticated data field.
@@ -224,7 +224,7 @@ namespace Tins {
* \return uint8_t containing the value of the authenticated * \return uint8_t containing the value of the authenticated
* data field. * data field.
*/ */
uint8_t authenticated_data() { return dns.ad; } uint8_t authenticated_data() const { return dns.ad; }
/** /**
* \brief Setter for the checking disabled field. * \brief Setter for the checking disabled field.
@@ -232,42 +232,42 @@ namespace Tins {
* \return uint8_t containing the value of the checking * \return uint8_t containing the value of the checking
* disabled field. * disabled field.
*/ */
uint8_t checking_disabled() { return dns.cd; } uint8_t checking_disabled() const { return dns.cd; }
/** /**
* \brief Setter for the rcode field. * \brief Setter for the rcode field.
* *
* \return uint8_t containing the value of the rcode field. * \return uint8_t containing the value of the rcode field.
*/ */
uint8_t rcode() { return dns.rcode; } uint8_t rcode() const { return dns.rcode; }
/** /**
* \brief Setter for the questions field. * \brief Setter for the questions field.
* *
* \return uint16_t containing the value of the questions field. * \return uint16_t containing the value of the questions field.
*/ */
uint16_t questions() { return Utils::net_to_host_s(dns.questions); } uint16_t questions() const { return Utils::net_to_host_s(dns.questions); }
/** /**
* \brief Setter for the answers field. * \brief Setter for the answers field.
* *
* \return uint16_t containing the value of the answers field. * \return uint16_t containing the value of the answers field.
*/ */
uint16_t answers() { return Utils::net_to_host_s(dns.answers); } uint16_t answers() const { return Utils::net_to_host_s(dns.answers); }
/** /**
* \brief Setter for the authority field. * \brief Setter for the authority field.
* *
* \return uint16_t containing the value of the authority field. * \return uint16_t containing the value of the authority field.
*/ */
uint16_t authority() { return Utils::net_to_host_s(dns.authority); } uint16_t authority() const { return Utils::net_to_host_s(dns.authority); }
/** /**
* \brief Setter for the additional field. * \brief Setter for the additional field.
* *
* \return uint16_t containing the value of the additional field. * \return uint16_t containing the value of the additional field.
*/ */
uint16_t additional() { return Utils::net_to_host_s(dns.additional); } uint16_t additional() const { return Utils::net_to_host_s(dns.additional); }
/** /**
* \brief Getter for the PDU's type. * \brief Getter for the PDU's type.

View File

@@ -136,7 +136,7 @@ uint32_t Tins::DNS::header_size() const {
} }
void Tins::DNS::id(uint16_t new_id) { void Tins::DNS::id(uint16_t new_id) {
dns.id = new_id; dns.id = Utils::net_to_host_s(new_id);
} }
void Tins::DNS::type(QRType new_qr) { void Tins::DNS::type(QRType new_qr) {
@@ -406,7 +406,7 @@ void Tins::DNS::build_suffix_map() {
void Tins::DNS::compose_name(const uint8_t *ptr, uint32_t sz, std::string &out) { void Tins::DNS::compose_name(const uint8_t *ptr, uint32_t sz, std::string &out) {
uint32_t i(0); uint32_t i(0);
while(i < sz) { while(i < sz) {
if(i) if(i && ptr[i])
out.push_back('.'); out.push_back('.');
if((ptr[i] & 0xc0)) { if((ptr[i] & 0xc0)) {
uint16_t index = Utils::net_to_host_s(*((uint16_t*)(ptr + i))); uint16_t index = Utils::net_to_host_s(*((uint16_t*)(ptr + i)));

View File

@@ -65,10 +65,11 @@ Tins::IP::IP(const uint8_t *buffer, uint32_t total_sz)
if(total_sz < head_len() * sizeof(uint32_t)) if(total_sz < head_len() * sizeof(uint32_t))
throw std::runtime_error(msg); throw std::runtime_error(msg);
buffer += head_len() * sizeof(uint32_t); buffer += head_len() * sizeof(uint32_t);
this->_options_size = 0; this->_options_size = 0;
this->_padded_options_size = head_len() * sizeof(uint32_t) - sizeof(iphdr); this->_padded_options_size = head_len() * sizeof(uint32_t) - sizeof(iphdr);
/* While the end of the options is not reached read an option */ /* While the end of the options is not reached read an option */
while (total_sz && ptr_buffer < buffer && (*ptr_buffer != 0)) { while (ptr_buffer < buffer && (*ptr_buffer != 0)) {
IPOption opt_to_add; IPOption opt_to_add;
memcpy(&opt_to_add.type, ptr_buffer, sizeof(uint8_t)); memcpy(&opt_to_add.type, ptr_buffer, sizeof(uint8_t));
ptr_buffer++; ptr_buffer++;
@@ -91,21 +92,24 @@ Tins::IP::IP(const uint8_t *buffer, uint32_t total_sz)
case DPS: case DPS:
case UMP: case UMP:
case QS: case QS:
if(!total_sz || *ptr_buffer == 0) if(ptr_buffer == buffer || *ptr_buffer == 0)
throw std::runtime_error(msg); throw std::runtime_error(msg);
{ {
const uint8_t data_size = *ptr_buffer - 1; const uint8_t data_size = *ptr_buffer - 1;
if(data_size > 0) { if(data_size > 0) {
if(total_sz < data_size) if(buffer - ptr_buffer < data_size)
throw std::runtime_error(msg); throw std::runtime_error(msg);
opt_to_add.optional_data.assign(ptr_buffer, ptr_buffer + data_size); opt_to_add.optional_data.assign(ptr_buffer, ptr_buffer + data_size);
} }
} }
ptr_buffer += opt_to_add.optional_data.size(); ptr_buffer += opt_to_add.optional_data.size();
} }
this->_ip_options.push_back(opt_to_add); this->_ip_options.push_back(opt_to_add);
this->_options_size += opt_to_add.optional_data.size() + 1; this->_options_size += opt_to_add.optional_data.size() + 1;
} }
// check this line PLX
total_sz -= head_len() * sizeof(uint32_t); total_sz -= head_len() * sizeof(uint32_t);
if (total_sz) { if (total_sz) {
switch(_ip.protocol) { switch(_ip.protocol) {

162
tests/src/dns.cpp Normal file
View File

@@ -0,0 +1,162 @@
#include <gtest/gtest.h>
#include <iostream>
#include "dns.h"
#include "utils.h"
using namespace Tins;
class DNSTest : public testing::Test {
public:
static const uint8_t expected_packet[];
void test_equals(const DNS &dns1, const DNS &dns2);
void test_equals(const DNS::Query &q1, const DNS::Query &q2);
void test_equals(const DNS::Resource &q1, const DNS::Resource &q2);
};
const uint8_t DNSTest::expected_packet[] = {
'\x00', '\x13', '\xd7', '\x9a', '\x00', '\x01', '\x00', '\x01', '\x00', '\x00', '\x00', '\x00', '\x03', 'w', 'w', 'w', '\x07', 'e', 'x', 'a', 'm', 'p', 'l', 'e', '\x03', 'c', 'o', 'm', '\x00', '\x00', '\x01', '\x00', '\x01', '\x03', 'w', 'w', 'w', '\x07', 'e', 'x', 'a', 'm', 'p', 'l', 'e', '\x03', 'c', 'o', 'm', '\x00', '\x00', '\x01', '\x00', '\x01', '\x00', '\x00', '\x12', '4', '\x00', '\x04', '\xc0', '\xa8', '\x00', '\x01'
};
void DNSTest::test_equals(const DNS &dns1, const DNS &dns2) {
EXPECT_EQ(dns1.id(), dns2.id());
EXPECT_EQ(dns1.type(), dns2.type());
EXPECT_EQ(dns1.opcode(), dns2.opcode());
EXPECT_EQ(dns1.authoritative_answer(), dns2.authoritative_answer());
EXPECT_EQ(dns1.truncated(), dns2.truncated());
EXPECT_EQ(dns1.recursion_desired(), dns2.recursion_desired());
EXPECT_EQ(dns1.recursion_available(), dns2.recursion_available());
EXPECT_EQ(dns1.z(), dns2.z());
EXPECT_EQ(dns1.authenticated_data(), dns2.authenticated_data());
EXPECT_EQ(dns1.checking_disabled(), dns2.checking_disabled());
EXPECT_EQ(dns1.rcode(), dns2.rcode());
EXPECT_EQ(dns1.questions(), dns2.questions());
EXPECT_EQ(dns1.answers(), dns2.answers());
EXPECT_EQ(dns1.authority(), dns2.authority());
EXPECT_EQ(dns1.additional(), dns2.additional());
EXPECT_EQ(dns1.pdu_type(), dns2.pdu_type());
EXPECT_EQ(dns1.header_size(), dns2.header_size());
}
void DNSTest::test_equals(const DNS::Query &q1, const DNS::Query &q2) {
EXPECT_EQ(q1.name, q2.name);
EXPECT_EQ(q1.type, q2.type);
EXPECT_EQ(q1.qclass, q2.qclass);
}
void DNSTest::test_equals(const DNS::Resource &q1, const DNS::Resource &q2) {
EXPECT_EQ(q1.dname, q2.dname);
EXPECT_EQ(q1.addr, q2.addr);
EXPECT_EQ(q1.type, q2.type);
EXPECT_EQ(q1.qclass, q2.qclass);
EXPECT_EQ(q1.ttl, q2.ttl);
}
TEST_F(DNSTest, ConstructorFromBuffer) {
DNS dns(expected_packet, sizeof(expected_packet));
// id=0x13, qr=1, opcode=0xa, aa=1, tc=1, rd=1, ra=1, z=0, rcode=0xa
EXPECT_EQ(dns.id(), 0x13);
EXPECT_EQ(dns.type(), DNS::RESPONSE);
EXPECT_EQ(dns.opcode(), 0xa);
EXPECT_EQ(dns.authoritative_answer(), 1);
EXPECT_EQ(dns.truncated(), 1);
EXPECT_EQ(dns.recursion_desired(), 1);
EXPECT_EQ(dns.recursion_available(), 1);
EXPECT_EQ(dns.z(), 0);
EXPECT_EQ(dns.rcode(), 0xa);
EXPECT_EQ(dns.questions(), 1);
EXPECT_EQ(dns.answers(), 1);
std::list<DNS::Query> queries = dns.dns_queries();
ASSERT_EQ(queries.size(), 1);
test_equals(queries.front(), DNS::Query("www.example.com", DNS::A, DNS::IN));
std::list<DNS::Resource> answers = dns.dns_answers();
ASSERT_EQ(answers.size(), 1);
test_equals(answers.front(), DNS::Resource("www.example.com", "192.168.0.1", DNS::A, DNS::IN, 0x1234));
}
TEST_F(DNSTest, ID) {
DNS dns;
dns.id(0x7263);
EXPECT_EQ(dns.id(), 0x7263);
}
TEST_F(DNSTest, Type) {
DNS dns;
dns.type(DNS::RESPONSE);
EXPECT_EQ(dns.type(), DNS::RESPONSE);
}
TEST_F(DNSTest, Opcode) {
DNS dns;
dns.opcode(0xa);
EXPECT_EQ(dns.opcode(), 0xa);
}
TEST_F(DNSTest, AuthoritativeAnswer) {
DNS dns;
dns.authoritative_answer(1);
EXPECT_EQ(dns.authoritative_answer(), 1);
}
TEST_F(DNSTest, Truncated) {
DNS dns;
dns.truncated(1);
EXPECT_EQ(dns.truncated(), 1);
}
TEST_F(DNSTest, RecursionDesired) {
DNS dns;
dns.recursion_desired(1);
EXPECT_EQ(dns.recursion_desired(), 1);
}
TEST_F(DNSTest, RecursionAvailable) {
DNS dns;
dns.recursion_available(1);
EXPECT_EQ(dns.recursion_available(), 1);
}
TEST_F(DNSTest, Z) {
DNS dns;
dns.z(1);
EXPECT_EQ(dns.z(), 1);
}
TEST_F(DNSTest, AuthenticatedData) {
DNS dns;
dns.authenticated_data(1);
EXPECT_EQ(dns.authenticated_data(), 1);
}
TEST_F(DNSTest, CheckingDisabled) {
DNS dns;
dns.checking_disabled(1);
EXPECT_EQ(dns.checking_disabled(), 1);
}
TEST_F(DNSTest, RCode) {
DNS dns;
dns.rcode(0xa);
EXPECT_EQ(dns.rcode(), 0xa);
}
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);
}
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);
}