| #include <stdint.h> | 
 | #include <gtest/gtest.h> | 
 | #include <arpa/inet.h> | 
 | #include "apf_defs.h" | 
 | #include "apf_utils.h" | 
 | #include "apf_dns.h" | 
 |  | 
 | namespace apf { | 
 |  | 
 | TEST(ApfDnsTest, MatchSingleNameWithNoNameCompression) { | 
 |     // needle = _NMT._TCP.LOCAL | 
 |     const uint8_t needle_match[] = { | 
 |         0x04, 0x5f, 0x4e, 0x4d, 0x54, 0x04, 0x5f, 0x54, | 
 |         0x43, 0x50, 0x05, 0x4c, 0x4f, 0x43, 0x41, 0x4c, | 
 |         0x00 | 
 |     }; | 
 |     const uint8_t udp[] = { | 
 |         0x00, 0x00, 0x00, 0x00, // tid = 0x00, flags = 0x00, | 
 |         0x00, 0x01, // qdcount = 1 | 
 |         0x00, 0x00, // ancount = 0 | 
 |         0x00, 0x00, // nscount = 0 | 
 |         0x00, 0x00, // arcount = 0 | 
 |         0x04, 0x5f, 0x6e, 0x6d, 0x74, 0x04, 0x5f, 0x74, // qname1 = _nmt._tcp.local | 
 |         0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, | 
 |         0x00, | 
 |         0x00, 0x0c, 0x00, 0x01  // type = PTR, class = 0x0001 | 
 |     }; | 
 |     u32 ofs = 12; | 
 |     EXPECT_EQ(match_single_name(needle_match, needle_match + sizeof(needle_match), udp, sizeof(udp), &ofs), match); | 
 |     EXPECT_EQ(ofs, 29); | 
 |     // qname1 = _MMM._tcp.local | 
 |     const uint8_t needle_nomatch[] = { | 
 |         0x04, 0x5f, 0x4d, 0x4d, 0x4d, 0x04, 0x5f, 0x74, | 
 |         0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, | 
 |         0x00 | 
 |     }; | 
 |     ofs = 12; | 
 |     EXPECT_EQ(match_single_name(needle_nomatch, needle_nomatch + sizeof(needle_nomatch), udp, sizeof(udp), &ofs), nomatch); | 
 |     EXPECT_EQ(ofs, 29); | 
 | } | 
 |  | 
 | TEST(ApfDnsTest, MatchSingleNameWithoutNameCompression) { | 
 |     // needle = B.LOCAL | 
 |     const uint8_t needle_match[] = { | 
 |         0x01, 0x42, 0x05, 0x4c, 0x4f, 0x43, 0x41, 0x4c, | 
 |         0x00 | 
 |     }; | 
 |     const uint8_t udp[] = { | 
 |         0x00, 0x00, 0x00, 0x00, // tid = 0x00, flags = 0x00, | 
 |         0x00, 0x02, // qdcount = 2 | 
 |         0x00, 0x00, // ancount = 0 | 
 |         0x00, 0x00, // nscount = 0 | 
 |         0x00, 0x00, // arcount = 0 | 
 |         0x01, 0x61, 0x01, 0x62, 0x05, 0x6c, 0x6f, 0x63, // qname1 = a.b.local | 
 |         0x61, 0x6c, 0x00, | 
 |         0x00, 0x01, 0x00, 0x01,  // type = A, class = 0x0001 | 
 |         0xc0, 0x0e, // qname2 = b.local (name compression) | 
 |         0x00, 0x01, 0x00, 0x01 // type = A, class = 0x0001 | 
 |     }; | 
 |     u32 ofs = 27; | 
 |     EXPECT_EQ(match_single_name(needle_match, needle_match + sizeof(needle_match), udp, sizeof(udp), &ofs), match); | 
 |     EXPECT_EQ(ofs, 29); | 
 | } | 
 |  | 
 | TEST(ApfDnsTest, MatchSingleNameWithInfiniteloop) { | 
 |     // needle = B.LOCAL | 
 |     const uint8_t needle_match[] = { | 
 |         0x01, 0x42, 0x05, 0x4c, 0x4f, 0x43, 0x41, 0x4c, | 
 |         0x00 | 
 |     }; | 
 |     const uint8_t udp[] = { | 
 |         0x00, 0x00, 0x00, 0x00, // tid = 0x00, flags = 0x00, | 
 |         0x00, 0x02, // qdcount = 2 | 
 |         0x00, 0x00, // ancount = 0 | 
 |         0x00, 0x00, // nscount = 0 | 
 |         0x00, 0x00, // arcount = 0 | 
 |         0x01, 0x61, 0x01, 0x62, 0x05, 0x6c, 0x6f, 0x63, // qname1 = a.b.local | 
 |         0x61, 0x6c, 0x00, | 
 |         0x00, 0x01, 0x00, 0x01,  // type = A, class = 0x0001 | 
 |         0xc0, 0x1b, // corrupted pointer cause infinite loop | 
 |         0x00, 0x01, 0x00, 0x01 // type = A, class = 0x0001 | 
 |     }; | 
 |     u32 ofs = 27; | 
 |     EXPECT_EQ(match_single_name(needle_match, needle_match + sizeof(needle_match), udp, sizeof(udp), &ofs), error_packet); | 
 | } | 
 |  | 
 | TEST(ApfDnsTest, MatchNamesInQuestions) { | 
 |     // needles = { A.B.LOCAL } | 
 |     const uint8_t needles_match1[] = { | 
 |         0x01, 0x41, 0x01, 0x42, 0x05, 0x4c, 0x4f, 0x43, | 
 |         0x41, 0x4c, 0x00, 0x00 | 
 |     }; | 
 |     const uint8_t udp[] = { | 
 |         0x00, 0x00, 0x00, 0x00, // tid = 0x00, flags = 0x00, | 
 |         0x00, 0x02, // qdcount = 2 | 
 |         0x00, 0x00, // ancount = 0 | 
 |         0x00, 0x00, // nscount = 0 | 
 |         0x00, 0x00, // arcount = 0 | 
 |         0x01, 0x61, 0x01, 0x62, 0x05, 0x6c, 0x6f, 0x63, // qname1 = a.b.local | 
 |         0x61, 0x6c, 0x00, | 
 |         0x00, 0x01, 0x00, 0x01,// type = A, class = 0x0001 | 
 |         0xc0, 0x0e, // qname2 = b.local (name compression) | 
 |         0x00, 0x01, 0x00, 0x01 // type = A, class = 0x0001 | 
 |     }; | 
 |     EXPECT_EQ(match_names(needles_match1, needles_match1 + sizeof(needles_match1),  udp, sizeof(udp), 0x01), match); | 
 |     // needles = { A, B.LOCAL } | 
 |     const uint8_t needles_match2[] = { | 
 |         0x01, 0x41, 0x00, 0x01, 0x42, 0x05, 0x4c, 0x4f, | 
 |         0x43, 0x41, 0x4c, 0x00, 0x00 | 
 |     }; | 
 |     EXPECT_EQ(match_names(needles_match2, needles_match2 + sizeof(needles_match2), udp, sizeof(udp), 0x01), match); | 
 |     // needles = { C.LOCAL } | 
 |     const uint8_t needles_nomatch[] = { | 
 |         0x01, 0x43, 0x05, 0x4c, 0x4f, 0x43, 0x41, 0x4c, | 
 |         0x00, 0x00 | 
 |     }; | 
 |     EXPECT_EQ(match_names(needles_nomatch, needles_nomatch + sizeof(needles_nomatch), udp, sizeof(udp), 0x01), nomatch); | 
 | } | 
 |  | 
 | TEST(ApfDnsTest, MatchNamesInAnswers) { | 
 |     // needles = { A.B.LOCAL } | 
 |     const uint8_t needles_match1[] = { | 
 |         0x01, 0x41, 0x01, 0x42, 0x05, 0x4c, 0x4f, 0x43, | 
 |         0x41, 0x4c, 0x00, 0x00 | 
 |     }; | 
 |     const uint8_t udp[] = { | 
 |         0x00, 0x00, 0x84, 0x00, // tid = 0x00, flags = 0x8400, | 
 |         0x00, 0x00, // qdcount = 0 | 
 |         0x00, 0x02, // ancount = 2 | 
 |         0x00, 0x00, // nscount = 0 | 
 |         0x00, 0x00, // arcount = 0 | 
 |         0x01, 0x61, 0x01, 0x62, 0x05, 0x6c, 0x6f, 0x63, // name1 = a.b.local | 
 |         0x61, 0x6c, 0x00, | 
 |         0x00, 0x01, 0x80, 0x01, // type = A, class = 0x8001 | 
 |         0x00, 0x00, 0x00, 0x78, // ttl = 120 | 
 |         0x00, 0x04, 0xc0, 0xa8, 0x01, 0x09, // rdlengh = 4, rdata = 192.168.1.9 | 
 |         0xc0, 0x0e, // name2 = b.local (name compression) | 
 |         0x00, 0x01, 0x80, 0x01, // type = A, class = 0x8001 | 
 |         0x00, 0x00, 0x00, 0x78, // ttl = 120 | 
 |         0x00, 0x04, 0xc0, 0xa8, 0x01, 0x09 // rdlengh = 4, rdata = 192.168.1.9 | 
 |     }; | 
 |     EXPECT_EQ(match_names(needles_match1, needles_match1 + sizeof(needles_match1), udp, sizeof(udp), -1), match); | 
 |     // needles = { A, B.LOCAL } | 
 |     const uint8_t needles_match2[] = { | 
 |         0x01, 0x41, 0x00, 0x01, 0x42, 0x05, 0x4c, 0x4f, | 
 |         0x43, 0x41, 0x4c, 0x00, 0x00 | 
 |     }; | 
 |     EXPECT_EQ(match_names(needles_match2, needles_match2 + sizeof(needles_match2), udp, sizeof(udp), -1), match); | 
 |     // target names = { C.LOCAL } | 
 |     const uint8_t needle3[] = { | 
 |         0x01, 0x43, 0x05, 0x4c, 0x4f, 0x43, 0x41, 0x4c, | 
 |         0x00, 0x00 | 
 |     }; | 
 |     EXPECT_EQ(match_names(needle3, needle3 + sizeof(needle3), udp, sizeof(udp), -1), nomatch); | 
 | } | 
 |  | 
 | } // namespace apf |