1
0
mirror of https://github.com/mfontanini/libtins synced 2026-01-28 12:44:25 +01:00

Added support for IPv6 addresses in DNS.

This commit is contained in:
Matias Fontanini
2012-11-20 23:57:02 -03:00
parent 2a0b248518
commit 08b4c92dac
5 changed files with 53 additions and 8 deletions

View File

@@ -42,6 +42,7 @@
namespace Tins {
class IPv4Address;
class IPv6Address;
/**
* \class DNS
@@ -240,6 +241,7 @@ namespace Tins {
typedef std::list<Query> queries_type;
typedef std::list<Resource> resources_type;
typedef IPv4Address address_type;
typedef IPv6Address address_v6_type;
/**
* \brief Default constructor.
@@ -485,6 +487,18 @@ namespace Tins {
*/
void add_answer(const std::string &name,
const DNSResourceRecord::info &info, address_type ip);
/**
* \brief Add a query response.
*
* \param name The resolved name.
* \param type The type of this answer.
* \param qclass The class of this answer.
* \param ttl The time-to-live of this answer.
* \param ip The ip address of the resolved name.
*/
void add_answer(const std::string &name,
const DNSResourceRecord::info &info, address_v6_type ip);
/**
* \brief Add a query response.

View File

@@ -72,6 +72,15 @@ public:
*/
IPv6Address(const std::string &addr);
/**
* \brief Constructor from a buffer.
*
* The ptr parameter must be at least address_size bytes long.
*
* \param ptr The buffer from which to construct this object.
*/
IPv6Address(const_iterator ptr);
/**
* \brief Retrieve the string representation of this address.
*

View File

@@ -34,6 +34,7 @@
#include <memory>
#include "dns.h"
#include "ip_address.h"
#include "ipv6_address.h"
using std::string;
using std::list;
@@ -166,6 +167,13 @@ void DNS::add_answer(const string &name, const DNSResourceRecord::info &info,
dns.answers = Endian::host_to_be<uint16_t>(ans.size());
}
void DNS::add_answer(const string &name, const DNSResourceRecord::info &info,
address_v6_type ip)
{
ans.push_back(make_record(name, info, ip.begin(), address_v6_type::address_size));
dns.answers = Endian::host_to_be<uint16_t>(ans.size());
}
void DNS::add_answer(const std::string &name, const DNSResourceRecord::info &info,
const std::string &dname)
{
@@ -433,14 +441,7 @@ void DNS::convert_resources(const ResourcesType &lst, std::list<Resource> &res)
if(Endian::be_to_host(it->information().type) == DNS::AAAA) {
if(sz != 16)
throw std::runtime_error("Malformed IPv6 address");
std::ostringstream oss;
oss << std::hex;
for(size_t i = 0; i < 16; i += 2) {
oss << (int)ptr[i] << (int)ptr[i+1];
if(i != 14)
oss << ':';
}
addr = oss.str();
addr = IPv6Address(ptr).to_string();
}
else
compose_name(ptr, sz, addr);

View File

@@ -41,6 +41,10 @@ namespace Tins {
std::fill(address, address + address_size, 0);
}
IPv6Address::IPv6Address(const_iterator ptr) {
std::copy(ptr, ptr + address_size, address);
}
IPv6Address::IPv6Address(const std::string &addr) {
if(inet_pton(AF_INET6, addr.c_str(), address) == 0)
throw malformed_address();

View File

@@ -1,6 +1,7 @@
#include <gtest/gtest.h>
#include <iostream>
#include "dns.h"
#include "ipv6_address.h"
#include "utils.h"
using namespace Tins;
@@ -235,3 +236,19 @@ TEST_F(DNSTest, AnswersWithSameName) {
EXPECT_EQ(it->query_class(), DNS::IN);
}
}
TEST_F(DNSTest, AnswersV6) {
DNS dns;
dns.add_answer("www.example.com", DNS::make_info(DNS::AAAA, DNS::IN, 0x762), IPv6Address("f9a8:239::1:1"));
dns.add_answer("www.example.com", DNS::make_info(DNS::AAAA, DNS::IN, 0x762), IPv6Address("f9a8:239::1:1"));
ASSERT_EQ(dns.answers_count(), 2);
DNS::resources_type resources = dns.answers();
for(DNS::resources_type::const_iterator it = resources.begin(); it != resources.end(); ++it) {
EXPECT_EQ(it->dname(), "www.example.com");
EXPECT_EQ(it->type(), DNS::AAAA);
EXPECT_EQ(it->ttl(), 0x762);
EXPECT_EQ(it->data(), "f9a8:239::1:1");
EXPECT_EQ(it->query_class(), DNS::IN);
}
}