1 #include <stdint.h>
2 #include <gtest/gtest.h>
3 #include <arpa/inet.h>
4 #include "apf_defs.h"
5 #include "apf_utils.h"
6 #include "apf_dns.h"
7 
8 namespace apf {
9 
TEST(ApfDnsTest,MatchSingleNameWithNoNameCompression)10 TEST(ApfDnsTest, MatchSingleNameWithNoNameCompression) {
11     const uint8_t needle_match[] = {
12         0x04, '_', 'N', 'M', 'T',
13         0x04, '_', 'T', 'C', 'P',
14         0x05, 'L', 'O', 'C', 'A', 'L',
15         0x00 // needle = _NMT._TCP.LOCAL
16     };
17     const uint8_t udp_payload[] = {
18         0x00, 0x00, 0x00, 0x00, // tid = 0x00, flags = 0x00,
19         0x00, 0x01, // qdcount = 1
20         0x00, 0x00, // ancount = 0
21         0x00, 0x00, // nscount = 0
22         0x00, 0x00, // arcount = 0
23         0x04, '_', 'n', 'm', 't',
24         0x04, '_', 't', 'c', 'p',
25         0x05, 'l', 'o', 'c', 'a', 'l',
26         0x00, // qname1 = _nmt._tcp.local
27         0x00, 0x0c, 0x00, 0x01  // type = PTR, class = 0x0001
28     };
29     u32 ofs = 12;
30     EXPECT_EQ(match_single_name(needle_match, needle_match + sizeof(needle_match), udp_payload, sizeof(udp_payload), &ofs), match);
31     EXPECT_EQ(ofs, 29);
32     const uint8_t needle_match_star[] = {
33         0x04, '_', 'N', 'M', 'T',
34         0xff,
35         0x05, 'L', 'O', 'C', 'A', 'L',
36         0x00 // needle = _NMT.*.LOCAL
37     };
38     ofs = 12;
39     EXPECT_EQ(match_single_name(needle_match_star, needle_match_star + sizeof(needle_match_star), udp_payload, sizeof(udp_payload), &ofs), match);
40     EXPECT_EQ(ofs, 29);
41     const uint8_t needle_nomatch[] = {
42         0x04, '_', 'M', 'M', 'M',
43         0x04, '_', 't', 'c', 'p',
44         0x05, 'l', 'o', 'c', 'a', 'l',
45         0x00 // needle = _MMM._tcp.local
46     };
47     ofs = 12;
48     EXPECT_EQ(match_single_name(needle_nomatch, needle_nomatch + sizeof(needle_nomatch), udp_payload, sizeof(udp_payload), &ofs), nomatch);
49     EXPECT_EQ(ofs, 29);
50     const uint8_t needle_nomatch_star[] = {
51         0xff,
52         0x04, '_', 'u', 'd', 'p',
53         0x05, 'l', 'o', 'c', 'a', 'l',
54         0x00 // needle = *._udp.local
55     };
56     ofs = 12;
57     EXPECT_EQ(match_single_name(needle_nomatch_star, needle_nomatch_star + sizeof(needle_nomatch_star), udp_payload, sizeof(udp_payload), &ofs), nomatch);
58     EXPECT_EQ(ofs, 29);
59 }
60 
TEST(ApfDnsTest,MatchSingleNameWithoutNameCompression)61 TEST(ApfDnsTest, MatchSingleNameWithoutNameCompression) {
62     const uint8_t needle_match[] = {
63         0x01, 'B',
64         0x05, 'L', 'O', 'C', 'A', 'L',
65         0x00 // needle = B.LOCAL
66     };
67     const uint8_t udp_payload[] = {
68         0x00, 0x00, 0x00, 0x00, // tid = 0x00, flags = 0x00,
69         0x00, 0x02, // qdcount = 2
70         0x00, 0x00, // ancount = 0
71         0x00, 0x00, // nscount = 0
72         0x00, 0x00, // arcount = 0
73         0x01, 'a',
74         0x01, 'b',
75         0x05, 'l', 'o', 'c', 'a', 'l',
76         0x00, // qname1 = a.b.local
77         0x00, 0x01, 0x00, 0x01,  // type = A, class = 0x0001
78         0xc0, 0x0e, // qname2 = b.local (name compression)
79         0x00, 0x01, 0x00, 0x01 // type = A, class = 0x0001
80     };
81     u32 ofs = 27;
82     EXPECT_EQ(match_single_name(needle_match, needle_match + sizeof(needle_match), udp_payload, sizeof(udp_payload), &ofs), match);
83     EXPECT_EQ(ofs, 29);
84     const uint8_t needle_match_star[] = {
85         0x01, 'B',
86         0xff,
87         0x00 // needle = B.*
88     };
89     ofs = 27;
90     EXPECT_EQ(match_single_name(needle_match_star, needle_match_star + sizeof(needle_match_star), udp_payload, sizeof(udp_payload), &ofs), match);
91     EXPECT_EQ(ofs, 29);
92 }
93 
TEST(ApfDnsTest,MatchSingleNameWithInfiniteloop)94 TEST(ApfDnsTest, MatchSingleNameWithInfiniteloop) {
95     const uint8_t needle_match[] = {
96         0x01, 'B',
97         0x05, 'L', 'O', 'C', 'A', 'L',
98         0x00 // needle = B.LOCAL
99     };
100     const uint8_t udp_payload[] = {
101         0x00, 0x00, 0x00, 0x00, // tid = 0x00, flags = 0x00,
102         0x00, 0x02, // qdcount = 2
103         0x00, 0x00, // ancount = 0
104         0x00, 0x00, // nscount = 0
105         0x00, 0x00, // arcount = 0
106         0x01, 'a',
107         0x01, 'b',
108         0x05, 'l', 'o', 'c', 'a', 'l',
109         0x00, // qname1 = a.b.local
110         0x00, 0x01, 0x00, 0x01,  // type = A, class = 0x0001
111         0xc0, 0x1b, // corrupted pointer cause infinite loop
112         0x00, 0x01, 0x00, 0x01 // type = A, class = 0x0001
113     };
114     u32 ofs = 27;
115     EXPECT_EQ(match_single_name(needle_match, needle_match + sizeof(needle_match), udp_payload, sizeof(udp_payload), &ofs), error_packet);
116     const uint8_t needle_match_star[] = {
117         0x01, 'B',
118         0xff,
119         0x00 // needle = B.*
120     };
121     ofs = 27;
122     EXPECT_EQ(match_single_name(needle_match_star, needle_match_star + sizeof(needle_match_star), udp_payload, sizeof(udp_payload), &ofs), error_packet);
123 }
124 
TEST(ApfDnsTest,MatchNamesInQuestions)125 TEST(ApfDnsTest, MatchNamesInQuestions) {
126     // needles = { A.B.LOCAL }
127     const uint8_t needles_match1[] = {
128         0x01, 'A',
129         0x01, 'B',
130         0x05, 'L', 'O', 'C', 'A', 'L',
131         0x00,
132         0x00
133     };
134     const uint8_t udp_payload[] = {
135         0x00, 0x00, 0x00, 0x00, // tid = 0x00, flags = 0x00,
136         0x00, 0x02, // qdcount = 2
137         0x00, 0x00, // ancount = 0
138         0x00, 0x00, // nscount = 0
139         0x00, 0x00, // arcount = 0
140         0x01, 'a',
141         0x01, 'b',
142         0x05, 'l', 'o', 'c', 'a', 'l',
143         0x00, // qname1 = a.b.local
144         0x00, 0x01, 0x00, 0x01,// type = A, class = 0x0001
145         0xc0, 0x0e, // qname2 = b.local (name compression)
146         0x00, 0x01, 0x00, 0x01 // type = A, class = 0x0001
147     };
148     EXPECT_EQ(match_names(needles_match1, needles_match1 + sizeof(needles_match1),  udp_payload, sizeof(udp_payload), 0x01), match);
149     // needles = { A, B.LOCAL }
150     const uint8_t needles_match2[] = {
151         0x01, 'A',
152         0x00,
153         0x01, 'B',
154         0x05, 'L', 'O', 'C', 'A', 'L',
155         0x00,
156         0x00
157     };
158     EXPECT_EQ(match_names(needles_match2, needles_match2 + sizeof(needles_match2), udp_payload, sizeof(udp_payload), 0x01), match);
159     // needles = { *, B.* }
160     const uint8_t needles_match2_star[] = {
161         0xff,
162         0x00,
163         0x01, 'B',
164         0xff,
165         0x00,
166         0x00
167     };
168     EXPECT_EQ(match_names(needles_match2_star, needles_match2_star + sizeof(needles_match2_star), udp_payload, sizeof(udp_payload), 0x01), match);
169     // needles = { C.LOCAL }
170     const uint8_t needles_nomatch[] = {
171         0x01, 'C',
172         0x05, 'L', 'O', 'C', 'A', 'L',
173         0x00,
174         0x00
175     };
176     EXPECT_EQ(match_names(needles_nomatch, needles_nomatch + sizeof(needles_nomatch), udp_payload, sizeof(udp_payload), 0x01), nomatch);
177     // needles = { C.* }
178     const uint8_t needles_nomatch_star[] = {
179         0x01, 'C',
180         0xff,
181         0x00,
182         0x00
183     };
184     EXPECT_EQ(match_names(needles_nomatch_star, needles_nomatch_star + sizeof(needles_nomatch_star), udp_payload, sizeof(udp_payload), 0x01), nomatch);
185 }
186 
TEST(ApfDnsTest,MatchNamesInAnswers)187 TEST(ApfDnsTest, MatchNamesInAnswers) {
188     // needles = { A.B.LOCAL }
189     const uint8_t needles_match1[] = {
190         0x01, 'A',
191         0x01, 'B',
192         0x05, 'L', 'O', 'C', 'A', 'L',
193         0x00,
194         0x00
195     };
196     const uint8_t udp_payload[] = {
197         0x00, 0x00, 0x84, 0x00, // tid = 0x00, flags = 0x8400,
198         0x00, 0x00, // qdcount = 0
199         0x00, 0x02, // ancount = 2
200         0x00, 0x00, // nscount = 0
201         0x00, 0x00, // arcount = 0
202         0x01, 'a',
203         0x01, 'b',
204         0x05, 'l', 'o', 'c', 'a', 'l',
205         0x00, // name1 = a.b.local
206         0x00, 0x01, 0x80, 0x01, // type = A, class = 0x8001
207         0x00, 0x00, 0x00, 0x78, // ttl = 120
208         0x00, 0x04, 0xc0, 0xa8, 0x01, 0x09, // rdlengh = 4, rdata = 192.168.1.9
209         0xc0, 0x0e, // name2 = b.local (name compression)
210         0x00, 0x01, 0x80, 0x01, // type = A, class = 0x8001
211         0x00, 0x00, 0x00, 0x78, // ttl = 120
212         0x00, 0x04, 0xc0, 0xa8, 0x01, 0x09 // rdlengh = 4, rdata = 192.168.1.9
213     };
214     EXPECT_EQ(match_names(needles_match1, needles_match1 + sizeof(needles_match1), udp_payload, sizeof(udp_payload), -1), match);
215     // needles = { A, B.LOCAL }
216     const uint8_t needles_match2[] = {
217         0x01, 'A', 0x00,
218         0x01, 'B',
219         0x05, 'L', 'O', 'C', 'A', 'L',
220         0x00,
221         0x00
222     };
223     EXPECT_EQ(match_names(needles_match2, needles_match2 + sizeof(needles_match2), udp_payload, sizeof(udp_payload), -1), match);
224     // needles = { *, B.* }
225     const uint8_t needles_match2_star[] = {
226         0xff,
227         0x01, 'B',
228         0xff,
229         0x00,
230         0x00
231     };
232     EXPECT_EQ(match_names(needles_match2_star, needles_match2_star + sizeof(needles_match2_star), udp_payload, sizeof(udp_payload), -1), match);
233     // needles = { C.LOCAL }
234     const uint8_t needles_nomatch[] = {
235         0x01, 'C',
236         0x05, 'L', 'O', 'C', 'A', 'L',
237         0x00,
238         0x00
239     };
240     EXPECT_EQ(match_names(needles_nomatch, needles_nomatch + sizeof(needles_nomatch), udp_payload, sizeof(udp_payload), -1), nomatch);
241     // needles = { C.* }
242     const uint8_t needles_nomatch_star[] = {
243         0x01, 'C',
244         0xff,
245         0x00,
246         0x00
247     };
248     EXPECT_EQ(match_names(needles_nomatch_star, needles_nomatch_star + sizeof(needles_nomatch_star), udp_payload, sizeof(udp_payload), -1), nomatch);
249 }
250 
251 } // namespace apf
252