1 /**
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <netdb.h>
17 #include <arpa/nameser.h>
18 #include <stdlib.h>
19 #include <sys/wait.h>
20 #include <string.h>
21 #include "functionalext.h"
22
23 #define TEST_MSG_SIZE 8
24 #define TEST_DNS_HEAD 12
25 #define TEST_SHIFT 8
26 #define TEST_INDEX_2 2
27 #define TEST_INDEX_3 3
28 #define TEST_INDEX_5 5
29 #define TEST_SKIP_SIZE 4
30 #define TEST_DATA_LEN 10
31
32 struct test_skiprr_data {
33 int sect;
34 int result;
35 };
36
37 static unsigned char msg[] = "\x71\x79\x81\x80\x00\x01"
38 "\x00\x02\x00\x04\x00\x04\x03\x77\x77\x77\x03\x61\x62\x63\x03\x63"
39 "\x6f\x6d\x00\x00\x01\x00\x01\xc0\x0c\x00\x05\x00\x01\x00\x00\x02"
40 "\xe8\x00\x02\xc0\x10\xc0\x10\x00\x01\x00\x01\x00\x00\x02\xe9\x00"
41 "\x04\x0a\xb5\x84\xfa\xc0\x10\x00\x02\x00\x01\x00\x00\xda\xeb\x00"
42 "\x0d\x06\x73\x65\x6e\x73\x30\x31\x03\x64\x69\x67\xc0\x14\xc0\x10"
43 "\x00\x02\x00\x01\x00\x00\xda\xeb\x00\x09\x06\x73\x65\x6e\x73\x30"
44 "\x32\xc0\x4e\xc0\x10\x00\x02\x00\x01\x00\x00\xda\xeb\x00\x09\x06"
45 "\x6f\x72\x6e\x73\x30\x31\xc0\x4e\xc0\x10\x00\x02\x00\x01\x00\x00"
46 "\xda\xeb\x00\x09\x06\x6f\x72\x6e\x73\x30\x32\xc0\x4e\xc0\x75\x00"
47 "\x01\x00\x01\x00\x00\x7a\x36\x00\x04\x0a\xbb\xbd\x2c\xc0\x8a\x00"
48 "\x01\x00\x01\x00\x00\x1b\x96\x00\x04\x0a\xbb\xbe\x2c\xc0\x47\x00"
49 "\x01\x00\x01\x00\x00\x92\xb1\x00\x04\x0a\xb5\x86\x10\xc0\x60\x00"
50 "\x01\x00\x01\x00\x00\x92\xb1\x00\x04\x0a\xb5\x87\xc7";
51
52 static struct test_skiprr_data test_data[TEST_SKIP_SIZE] = {{1, 17}, {2, 30}, {4, 88}, {4, 64}};
53
54 /**
55 * @tc.name : ns_get16_0100
56 * @tc.desc : Parse data from array and return
57 * @tc.level : Level 0
58 */
ns_get16_0100(void)59 void ns_get16_0100(void)
60 {
61 const unsigned char cp[] = "11";
62 unsigned int ret = ns_get16(cp);
63 unsigned int getresult = 12593;
64 EXPECT_EQ("ns_get16_0100", ret, getresult);
65 }
66
67 /**
68 * @tc.name : ns_get32_0100
69 * @tc.desc : Parse data from array and return
70 * @tc.level : Level 0
71 */
ns_get32_0100(void)72 void ns_get32_0100(void)
73 {
74 const unsigned char cp[] = "11";
75 unsigned long ret = ns_get32(cp);
76 unsigned long getresult = 825294897;
77 EXPECT_LONGEQ("ns_get32_0100", ret, getresult);
78 }
79
80 /**
81 * @tc.name : ns_put16_0100
82 * @tc.desc : Get actual data value from data of ns_get16
83 * @tc.level : Level 0
84 */
ns_put16_0100(void)85 void ns_put16_0100(void)
86 {
87 const unsigned char from[] = "11";
88 unsigned char to[TEST_MSG_SIZE];
89 memset(to, 0x0, TEST_MSG_SIZE);
90 unsigned int ret = ns_get16(from);
91 ns_put16(ret, to);
92 for (int i = 0; i < sizeof(from) / sizeof(unsigned char); i++) {
93 EXPECT_EQ("ns_put16_0100", from[i], to[i]);
94 }
95 }
96
97 /**
98 * @tc.name : ns_put32_0100
99 * @tc.desc : Get actual data value from data of ns_get32
100 * @tc.level : Level 0
101 */
ns_put32_0100(void)102 void ns_put32_0100(void)
103 {
104 const unsigned char from[] = "1234";
105 unsigned char to[TEST_MSG_SIZE];
106 memset(to, 0x0, TEST_MSG_SIZE);
107 unsigned long ret = ns_get32(from);
108 ns_put32(ret, to);
109 for (int i = 0; i < sizeof(from) / sizeof(unsigned char); i++) {
110 EXPECT_LONGEQ("ns_put32_0100", from[i], to[i]);
111 }
112 }
113
114 /**
115 * @tc.name : ns_name_uncompress_0100
116 * @tc.desc : Get the domain name from the array and store the data in the array (success)
117 * @tc.level : Level 0
118 */
ns_name_uncompress_0100(void)119 void ns_name_uncompress_0100(void)
120 {
121 unsigned char domain[] = {2, 'p', 'q', 0xc0, 5, 0};
122 char name[] = "XXXX";
123
124 int ret = ns_name_uncompress(domain, domain + 6, domain, name, TEST_MSG_SIZE);
125 EXPECT_EQ("ns_name_uncompress_0100", ret, 5);
126 EXPECT_STREQ("ns_name_uncompress_0100", name, "pq");
127
128 memcpy(domain, "\xc0\x02", 3);
129 memcpy(name, "XXXX", 5);
130 size_t limitsize = 1;
131 ret = ns_name_uncompress(domain, domain + 3, domain, name, limitsize);
132
133 EXPECT_EQ("ns_name_uncompress_0100", ret, 2);
134 EXPECT_STREQ("ns_name_uncompress_0100", name, "");
135 }
136
137 /**
138 * @tc.name : ns_name_uncompress_0200
139 * @tc.desc : Get the domain name from the array and store the data in the array (failed)
140 * @tc.level : Level 2
141 */
ns_name_uncompress_0200(void)142 void ns_name_uncompress_0200(void)
143 {
144 unsigned char domain[] = {2, 'p', 'q', 0xc0, 5, 0};
145 char name[] = "XXXX";
146
147 int ret = ns_name_uncompress(domain, domain + 6, domain, name, ERREXPECT);
148 EXPECT_EQ("ns_name_uncompress_0200", ret, ERREXPECT);
149 EXPECT_EQ("ns_name_uncompress_0200", errno, EMSGSIZE);
150 }
151
152 /**
153 * @tc.name : ns_name_uncompress_0300
154 * @tc.desc : Get the domain name from the array and store the data in the array (failed)
155 * @tc.level : Level 2
156 */
ns_name_uncompress_0300(void)157 void ns_name_uncompress_0300(void)
158 {
159 unsigned char domain[] = "error value";
160 char name[] = "XXXX";
161
162 int ret = ns_name_uncompress(domain, domain + 6, domain, name, ERREXPECT);
163 EXPECT_EQ("ns_name_uncompress_0200", ret, ERREXPECT);
164 EXPECT_EQ("ns_name_uncompress_0200", errno, EMSGSIZE);
165 }
166
167 /**
168 * @tc.name : ns_initparse_0100
169 * @tc.desc : Parse DNS protocol reply packets into ns_msg structure
170 * @tc.level : Level 0
171 */
ns_initparse_0100(void)172 void ns_initparse_0100(void)
173 {
174 ns_msg handle;
175 errno = 0;
176 int ret = ns_initparse(msg, sizeof(msg) - 1, &handle);
177 EXPECT_EQ("ns_initparse_0100", ret, CMPFLAG);
178 EXPECT_EQ("ns_initparse_0100", errno, CMPFLAG);
179
180 uint16_t id = (msg[0] << TEST_SHIFT) | msg[1];
181 uint16_t flags = (msg[TEST_INDEX_2] << TEST_SHIFT) | msg[TEST_INDEX_3];
182 EXPECT_EQ("ns_initparse_0100", handle._id, id);
183 EXPECT_EQ("ns_initparse_0100", handle._flags, flags);
184 }
185
186 /**
187 * @tc.name : ns_initparse_0200
188 * @tc.desc : Provide error parameter data, parse DNS protocol response packet into ns_msg structure
189 * @tc.level : Level 2
190 */
ns_initparse_0200(void)191 void ns_initparse_0200(void)
192 {
193 ns_msg handle;
194 errno = 0;
195 int ret = ns_initparse(msg, TEST_DATA_LEN, &handle);
196 EXPECT_EQ("ns_initparse_0200", ret, ERREXPECT);
197 EXPECT_EQ("ns_initparse_0200", errno, EMSGSIZE);
198
199 errno = 0;
200 ret = ns_initparse(msg, sizeof(msg), &handle);
201 EXPECT_EQ("ns_initparse_0200", ret, ERREXPECT);
202 EXPECT_EQ("ns_initparse_0200", errno, EMSGSIZE);
203 }
204
205 /**
206 * @tc.name : ns_skiprr_0100
207 * @tc.desc : Find the record location from a given DNS packet
208 * @tc.level : Level 0
209 */
ns_skiprr_0100(void)210 void ns_skiprr_0100(void)
211 {
212 unsigned char *ptr = msg + TEST_DNS_HEAD;
213 unsigned char *eom = msg + sizeof(msg) - 1;
214 int i, ret;
215 for (i = 0; i < TEST_SKIP_SIZE; i++) {
216 errno = 0;
217 ret = ns_skiprr(ptr, eom, i, test_data[i].sect);
218 if (ret == -1) {
219 break;
220 }
221 ptr += ret;
222 EXPECT_EQ("ns_skiprr_0100", ret, test_data[i].result);
223 EXPECT_EQ("ns_skiprr_0100", errno, CMPFLAG);
224 }
225 EXPECT_PTREQ("ns_skiprr_0100", ptr, eom);
226 }
227
228 /**
229 * @tc.name : ns_skiprr_0200
230 * @tc.desc : Provide error message, find record location
231 * @tc.level : Level 2
232 */
ns_skiprr_0200(void)233 void ns_skiprr_0200(void)
234 {
235 unsigned char *ptr = msg;
236 unsigned char *eom = msg + sizeof(msg);
237 int i, ret;
238 for (i = 0; i < TEST_SKIP_SIZE; i++) {
239 errno = 0;
240 ret = ns_skiprr(ptr, eom, i, test_data[i].sect);
241 if (ret == -1) {
242 break;
243 }
244 ptr += ret;
245 }
246 EXPECT_PTRNE("ns_skiprr_0200", ptr, eom);
247 }
248
249 /**
250 * @tc.name : ns_parserr_0100
251 * @tc.desc : Extract data from a given DNS packet
252 * @tc.level : Level 0
253 */
ns_parserr_0100(void)254 void ns_parserr_0100(void)
255 {
256 ns_msg handle;
257 errno = 0;
258 int ret = ns_initparse(msg, sizeof(msg) - 1, &handle);
259 EXPECT_EQ("ns_parserr_0100", ret, 0);
260 if (ret != 0) {
261 return;
262 }
263
264 ns_rr rr;
265 memset(&rr, 0x0, sizeof(ns_rr));
266 ret = ns_parserr(&handle, ns_s_qd, 0, &rr);
267 EXPECT_EQ("ns_parserr_0100", ret, 0);
268 EXPECT_STREQ("ns_parserr_0100", rr.name, "www.abc.com");
269 EXPECT_EQ("ns_parserr_0100", rr.rr_class, 1);
270 EXPECT_EQ("ns_parserr_0100", rr.type, 1);
271 EXPECT_EQ("ns_parserr_0100", rr.ttl, 0);
272 EXPECT_EQ("ns_parserr_0100", rr.rdlength, 0);
273 EXPECT_PTREQ("ns_parserr_0100", rr.rdata, NULL);
274
275 memset(&rr, 0x0, sizeof(ns_rr));
276 ret = ns_parserr(&handle, ns_s_an, 0, &rr);
277 EXPECT_EQ("ns_parserr_0100", ret, 0);
278 EXPECT_STREQ("ns_parserr_0100", rr.name, "www.abc.com");
279 EXPECT_EQ("ns_parserr_0100", rr.rr_class, 1);
280 EXPECT_EQ("ns_parserr_0100", rr.type, TEST_INDEX_5);
281 EXPECT_TRUE("ns_parserr_0100", rr.ttl > 0);
282 EXPECT_TRUE("ns_parserr_0100", rr.rdlength > 0);
283 EXPECT_PTRNE("ns_parserr_0100", rr.rdata, NULL);
284 }
285
286 /**
287 * @tc.name : ns_parserr_0200
288 * @tc.desc : Extracting data from given DNS message by providing wrong message length
289 * @tc.level : Level 2
290 */
ns_parserr_0200(void)291 void ns_parserr_0200(void)
292 {
293 ns_msg handle;
294 errno = 0;
295 int ret = ns_initparse(msg, sizeof(msg) - 1, &handle);
296 EXPECT_EQ("ns_parserr_0200", ret, 0);
297 if (ret != 0) {
298 return;
299 }
300
301 ns_rr rr;
302 errno = 0;
303 memset(&rr, 0x0, sizeof(ns_rr));
304 ret = ns_parserr(&handle, -1, 0, &rr);
305 EXPECT_EQ("ns_parserr_0200", ret, -1);
306 EXPECT_EQ("ns_parserr_0200", errno, ENODEV);
307
308 errno = 0;
309 memset(&rr, 0x0, sizeof(ns_rr));
310 ret = ns_parserr(&handle, ns_s_max + 1, 0, &rr);
311 EXPECT_EQ("ns_parserr_0200", ret, -1);
312 EXPECT_EQ("ns_parserr_0200", errno, ENODEV);
313 }
314
315 /**
316 * @tc.name : ns_parserr_0300
317 * @tc.desc : Provides an uninitialized ns_msg to extract data from the given DNS message
318 * @tc.level : Level 2
319 */
ns_parserr_0300(void)320 void ns_parserr_0300(void)
321 {
322 ns_msg handle;
323 errno = 0;
324 ns_rr rr;
325 memset(&handle, 0x0, sizeof(ns_msg));
326 memset(&rr, 0x0, sizeof(ns_rr));
327
328 int ret = ns_parserr(&handle, ns_s_qd, 0, &rr);
329 EXPECT_EQ("ns_parserr_0300", ret, -1);
330 EXPECT_EQ("ns_parserr_0300", errno, ENODEV);
331 }
332
main(void)333 int main(void)
334 {
335 ns_get16_0100();
336 ns_get32_0100();
337 ns_put16_0100();
338 ns_put32_0100();
339 ns_name_uncompress_0100();
340 ns_name_uncompress_0200();
341 ns_name_uncompress_0300();
342 ns_initparse_0100();
343 ns_initparse_0200();
344 ns_skiprr_0100();
345 ns_skiprr_0200();
346 ns_parserr_0100();
347 ns_parserr_0200();
348 ns_parserr_0300();
349 return t_status;
350 }