TEST_F(DNSTest, Answers) { DNS dns; dns.add_answer( DNS::Resource("www.example.com", "127.0.0.1", DNS::A, DNS::IN, 0x762) ); dns.add_answer( DNS::Resource("www.example2.com", "mail.example.com", DNS::MX, DNS::IN, 0x762) ); 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_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(), 0x762U); EXPECT_EQ(it->data(), "127.0.0.1"); EXPECT_EQ(it->query_class(), DNS::IN); } else if(it->dname() == "www.example2.com") { EXPECT_EQ(it->type(), DNS::MX); EXPECT_EQ(it->ttl(), 0x762U); EXPECT_EQ(it->data(), "mail.example.com"); EXPECT_EQ(it->query_class(), DNS::IN); } } }
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_count(), dns2.questions_count()); EXPECT_EQ(dns1.answers_count(), dns2.answers_count()); EXPECT_EQ(dns1.authority_count(), dns2.authority_count()); EXPECT_EQ(dns1.additional_count(), dns2.additional_count()); EXPECT_EQ(dns1.pdu_type(), dns2.pdu_type()); EXPECT_EQ(dns1.header_size(), dns2.header_size()); EXPECT_EQ(bool(dns1.inner_pdu()), bool(dns2.inner_pdu())); }
TEST_F(DNSTest, AnswersWithSameName) { DNS dns; dns.add_answer("www.example.com", DNS::make_info(DNS::A, DNS::IN, 0x762), IPv4Address("127.0.0.1")); dns.add_answer("www.example.com", DNS::make_info(DNS::A, DNS::IN, 0x762), IPv4Address("127.0.0.2")); 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_TRUE(it->data() == "127.0.0.1" || it->data() == "127.0.0.2"); EXPECT_EQ(it->dname(), "www.example.com"); EXPECT_EQ(it->type(), DNS::A); EXPECT_EQ(it->ttl(), 0x762U); 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(), 0x762U); EXPECT_EQ(it->data(), "f9a8:239::1:1"); EXPECT_EQ(it->query_class(), DNS::IN); } }
bool callback(const PDU &pdu) { // The packet probably looks like this: // // EthernetII / IP / UDP / RawPDU // // So we retrieve each layer, and construct a // DNS PDU from the RawPDU layer contents. EthernetII eth = pdu.rfind_pdu<EthernetII>(); IP ip = eth.rfind_pdu<IP>(); UDP udp = ip.rfind_pdu<UDP>(); DNS dns = udp.rfind_pdu<RawPDU>().to<DNS>(); // Is it a DNS query? if(dns.type() == DNS::QUERY) { // Let's see if there's any query for an "A" record. for(const auto &query : dns.queries()) { if(query.type() == DNS::A) { // Here's one! Let's add an answer. dns.add_answer( DNS::Resource( query.dname(), "127.0.0.1", DNS::A, query.query_class(), // 777 is just a random TTL 777 ) ); } } // Have we added some answers? if(dns.answers_count() > 0) { // It's a response now dns.type(DNS::RESPONSE); // Recursion is available(just in case) dns.recursion_available(1); // Build our packet auto pkt = EthernetII(eth.src_addr(), eth.dst_addr()) / IP(ip.src_addr(), ip.dst_addr()) / UDP(udp.sport(), udp.dport()) / dns; // Send it! sender.send(pkt); } } return true; }