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