1 /*
2 * Copyright (c) 2015 Verisure Innovation AB
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
21 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
25 * OF SUCH DAMAGE.
26 *
27 * This file is part of the lwIP TCP/IP stack.
28 *
29 * Author: Erik Ekman <erik@kryo.se>
30 *
31 */
32
33 #include "test_mdns.h"
34
35 #include "lwip/pbuf.h"
36 #include "lwip/apps/mdns.h"
37 #include "lwip/apps/mdns_domain.h"
38 #include "lwip/apps/mdns_priv.h"
39
START_TEST(readname_basic)40 START_TEST(readname_basic)
41 {
42 static const u8_t data[] = { 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0x00 };
43 struct pbuf *p;
44 struct mdns_domain domain;
45 u16_t offset;
46 LWIP_UNUSED_ARG(_i);
47
48 p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
49 fail_if(p == NULL);
50 p->payload = (void *)(size_t)data;
51 offset = mdns_readname(p, 0, &domain);
52 pbuf_free(p);
53 fail_unless(offset == sizeof(data));
54 fail_unless(domain.length == sizeof(data));
55 fail_if(memcmp(&domain.name, data, sizeof(data)));
56 }
57 END_TEST
58
START_TEST(readname_anydata)59 START_TEST(readname_anydata)
60 {
61 static const u8_t data[] = { 0x05, 0x00, 0xFF, 0x08, 0xc0, 0x0f, 0x04, 0x7f, 0x80, 0x82, 0x88, 0x00 };
62 struct pbuf *p;
63 struct mdns_domain domain;
64 u16_t offset;
65 LWIP_UNUSED_ARG(_i);
66
67 p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
68 fail_if(p == NULL);
69 p->payload = (void *)(size_t)data;
70 offset = mdns_readname(p, 0, &domain);
71 pbuf_free(p);
72 fail_unless(offset == sizeof(data));
73 fail_unless(domain.length == sizeof(data));
74 fail_if(memcmp(&domain.name, data, sizeof(data)));
75 }
76 END_TEST
77
START_TEST(readname_short_buf)78 START_TEST(readname_short_buf)
79 {
80 static const u8_t data[] = { 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a' };
81 struct pbuf *p;
82 struct mdns_domain domain;
83 u16_t offset;
84 LWIP_UNUSED_ARG(_i);
85
86 p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
87 fail_if(p == NULL);
88 p->payload = (void *)(size_t)data;
89 offset = mdns_readname(p, 0, &domain);
90 pbuf_free(p);
91 fail_unless(offset == MDNS_READNAME_ERROR);
92 }
93 END_TEST
94
START_TEST(readname_long_label)95 START_TEST(readname_long_label)
96 {
97 static const u8_t data[] = {
98 0x05, 'm', 'u', 'l', 't', 'i',
99 0x52, 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
100 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
101 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
102 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
103 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
104 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 0x00
105 };
106 struct pbuf *p;
107 struct mdns_domain domain;
108 u16_t offset;
109 LWIP_UNUSED_ARG(_i);
110
111 p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
112 fail_if(p == NULL);
113 p->payload = (void *)(size_t)data;
114 offset = mdns_readname(p, 0, &domain);
115 pbuf_free(p);
116 fail_unless(offset == MDNS_READNAME_ERROR);
117 }
118 END_TEST
119
START_TEST(readname_overflow)120 START_TEST(readname_overflow)
121 {
122 static const u8_t data[] = {
123 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
124 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
125 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
126 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
127 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
128 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
129 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
130 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
131 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
132 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
133 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
134 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
135 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
136 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
137 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
138 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
139 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
140 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
141 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
142 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
143 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
144 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
145 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
146 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
147 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
148 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
149 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
150 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
151 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
152 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
153 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
154 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
155 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
156 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
157 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
158 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
159 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
160 0x00
161 };
162 struct pbuf *p;
163 struct mdns_domain domain;
164 u16_t offset;
165 LWIP_UNUSED_ARG(_i);
166
167 p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
168 fail_if(p == NULL);
169 p->payload = (void *)(size_t)data;
170 offset = mdns_readname(p, 0, &domain);
171 pbuf_free(p);
172 fail_unless(offset == MDNS_READNAME_ERROR);
173 }
174 END_TEST
175
START_TEST(readname_jump_earlier)176 START_TEST(readname_jump_earlier)
177 {
178 static const u8_t data[] = {
179 /* Some padding needed, not supported to jump to bytes containing dns header */
180 /* 0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
181 /* 10 */ 0x0f, 0x0e, 0x05, 'l', 'o', 'c', 'a', 'l', 0x00, 0xab,
182 /* 20 */ 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0xc0, 0x0c
183 };
184 static const u8_t fullname[] = {
185 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0x05, 'l', 'o', 'c', 'a', 'l', 0x00
186 };
187 struct pbuf *p;
188 struct mdns_domain domain;
189 u16_t offset;
190 LWIP_UNUSED_ARG(_i);
191
192 p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
193 fail_if(p == NULL);
194 p->payload = (void *)(size_t)data;
195 offset = mdns_readname(p, 20, &domain);
196 pbuf_free(p);
197 fail_unless(offset == sizeof(data));
198 fail_unless(domain.length == sizeof(fullname));
199
200 fail_if(memcmp(&domain.name, fullname, sizeof(fullname)));
201 }
202 END_TEST
203
START_TEST(readname_jump_earlier_jump)204 START_TEST(readname_jump_earlier_jump)
205 {
206 static const u8_t data[] = {
207 /* Some padding needed, not supported to jump to bytes containing dns header */
208 /* 0x00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
209 /* 0x08 */ 0x00, 0x00, 0x00, 0x00, 0x03, 0x0b, 0x0a, 0xf2,
210 /* 0x10 */ 0x04, 'c', 'a', 's', 't', 0x00, 0xc0, 0x10,
211 /* 0x18 */ 0x05, 'm', 'u', 'l', 't', 'i', 0xc0, 0x16
212 };
213 static const u8_t fullname[] = {
214 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0x00
215 };
216 struct pbuf *p;
217 struct mdns_domain domain;
218 u16_t offset;
219 LWIP_UNUSED_ARG(_i);
220
221 p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
222 fail_if(p == NULL);
223 p->payload = (void *)(size_t)data;
224 offset = mdns_readname(p, 0x18, &domain);
225 pbuf_free(p);
226 fail_unless(offset == sizeof(data));
227 fail_unless(domain.length == sizeof(fullname));
228
229 fail_if(memcmp(&domain.name, fullname, sizeof(fullname)));
230 }
231 END_TEST
232
START_TEST(readname_jump_maxdepth)233 START_TEST(readname_jump_maxdepth)
234 {
235 static const u8_t data[] = {
236 /* Some padding needed, not supported to jump to bytes containing dns header */
237 /* 0x00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
238 /* 0x08 */ 0x00, 0x00, 0x00, 0x00, 0x03, 0x0b, 0x0a, 0xf2,
239 /* 0x10 */ 0x04, 'n', 'a', 'm', 'e', 0xc0, 0x27, 0x03,
240 /* 0x18 */ 0x03, 'd', 'n', 's', 0xc0, 0x10, 0xc0, 0x10,
241 /* 0x20 */ 0x04, 'd', 'e', 'e', 'p', 0xc0, 0x18, 0x00,
242 /* 0x28 */ 0x04, 'c', 'a', 's', 't', 0xc0, 0x20, 0xb0,
243 /* 0x30 */ 0x05, 'm', 'u', 'l', 't', 'i', 0xc0, 0x28
244 };
245 static const u8_t fullname[] = {
246 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
247 0x04, 'd', 'e', 'e', 'p', 0x03, 'd', 'n', 's',
248 0x04, 'n', 'a', 'm', 'e', 0x00
249 };
250 struct pbuf *p;
251 struct mdns_domain domain;
252 u16_t offset;
253 LWIP_UNUSED_ARG(_i);
254
255 p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
256 fail_if(p == NULL);
257 p->payload = (void *)(size_t)data;
258 offset = mdns_readname(p, 0x30, &domain);
259 pbuf_free(p);
260 fail_unless(offset == sizeof(data));
261 fail_unless(domain.length == sizeof(fullname));
262
263 fail_if(memcmp(&domain.name, fullname, sizeof(fullname)));
264 }
265 END_TEST
266
START_TEST(readname_jump_later)267 START_TEST(readname_jump_later)
268 {
269 static const u8_t data[] = {
270 /* 0x00 */ 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0xc0, 0x10, 0x00, 0x01, 0x40,
271 /* 0x10 */ 0x05, 'l', 'o', 'c', 'a', 'l', 0x00, 0xab
272 };
273 static const u8_t fullname[] = {
274 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0x05, 'l', 'o', 'c', 'a', 'l', 0x00
275 };
276 struct pbuf *p;
277 struct mdns_domain domain;
278 u16_t offset;
279 LWIP_UNUSED_ARG(_i);
280
281 p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
282 fail_if(p == NULL);
283 p->payload = (void *)(size_t)data;
284 offset = mdns_readname(p, 0, &domain);
285 pbuf_free(p);
286 fail_unless(offset == 13);
287 fail_unless(domain.length == sizeof(fullname));
288
289 fail_if(memcmp(&domain.name, fullname, sizeof(fullname)));
290 }
291 END_TEST
292
START_TEST(readname_half_jump)293 START_TEST(readname_half_jump)
294 {
295 static const u8_t data[] = {
296 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0xc0
297 };
298 struct pbuf *p;
299 struct mdns_domain domain;
300 u16_t offset;
301 LWIP_UNUSED_ARG(_i);
302
303 p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
304 fail_if(p == NULL);
305 p->payload = (void *)(size_t)data;
306 offset = mdns_readname(p, 0, &domain);
307 pbuf_free(p);
308 fail_unless(offset == MDNS_READNAME_ERROR);
309 }
310 END_TEST
311
START_TEST(readname_jump_toolong)312 START_TEST(readname_jump_toolong)
313 {
314 static const u8_t data[] = {
315 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0xc2, 0x10, 0x00, 0x01, 0x40
316 };
317 struct pbuf *p;
318 struct mdns_domain domain;
319 u16_t offset;
320 LWIP_UNUSED_ARG(_i);
321
322 p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
323 fail_if(p == NULL);
324 p->payload = (void *)(size_t)data;
325 offset = mdns_readname(p, 0, &domain);
326 pbuf_free(p);
327 fail_unless(offset == MDNS_READNAME_ERROR);
328 }
329 END_TEST
330
START_TEST(readname_jump_loop_label)331 START_TEST(readname_jump_loop_label)
332 {
333 static const u8_t data[] = {
334 /* 0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
335 /* 10 */ 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0xc0, 0x10
336 };
337 struct pbuf *p;
338 struct mdns_domain domain;
339 u16_t offset;
340 LWIP_UNUSED_ARG(_i);
341
342 p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
343 fail_if(p == NULL);
344 p->payload = (void *)(size_t)data;
345 offset = mdns_readname(p, 10, &domain);
346 pbuf_free(p);
347 fail_unless(offset == MDNS_READNAME_ERROR);
348 }
349 END_TEST
350
START_TEST(readname_jump_loop_jump)351 START_TEST(readname_jump_loop_jump)
352 {
353 static const u8_t data[] = {
354 /* 0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
355 /* 10 */ 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0xc0, 0x15
356 };
357 struct pbuf *p;
358 struct mdns_domain domain;
359 u16_t offset;
360 LWIP_UNUSED_ARG(_i);
361
362 p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
363 fail_if(p == NULL);
364 p->payload = (void *)(size_t)data;
365 offset = mdns_readname(p, 10, &domain);
366 pbuf_free(p);
367 fail_unless(offset == MDNS_READNAME_ERROR);
368 }
369 END_TEST
370
START_TEST(add_label_basic)371 START_TEST(add_label_basic)
372 {
373 static const u8_t data[] = { 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0x00 };
374 struct mdns_domain domain;
375 err_t res;
376 LWIP_UNUSED_ARG(_i);
377
378 memset(&domain, 0, sizeof(domain));
379 res = mdns_domain_add_label(&domain, "multi", 5);
380 fail_unless(res == ERR_OK);
381 res = mdns_domain_add_label(&domain, "cast", 4);
382 fail_unless(res == ERR_OK);
383 res = mdns_domain_add_label(&domain, NULL, 0);
384 fail_unless(res == ERR_OK);
385 fail_unless(domain.length == sizeof(data));
386 fail_if(memcmp(&domain.name, data, sizeof(data)));
387 }
388 END_TEST
389
START_TEST(add_label_long_label)390 START_TEST(add_label_long_label)
391 {
392 static const char *toolong = "abcdefghijklmnopqrstuvwxyz0123456789-abcdefghijklmnopqrstuvwxyz0123456789-abcdefghijklmnopqrstuvwxyz0123456789-";
393 struct mdns_domain domain;
394 err_t res;
395 LWIP_UNUSED_ARG(_i);
396
397 memset(&domain, 0, sizeof(domain));
398 res = mdns_domain_add_label(&domain, "multi", 5);
399 fail_unless(res == ERR_OK);
400 res = mdns_domain_add_label(&domain, toolong, (u8_t)strlen(toolong));
401 fail_unless(res == ERR_VAL);
402 }
403 END_TEST
404
START_TEST(add_label_full)405 START_TEST(add_label_full)
406 {
407 static const char *label = "0123456789abcdef0123456789abcdef";
408 struct mdns_domain domain;
409 err_t res;
410 LWIP_UNUSED_ARG(_i);
411
412 memset(&domain, 0, sizeof(domain));
413 res = mdns_domain_add_label(&domain, label, (u8_t)strlen(label));
414 fail_unless(res == ERR_OK);
415 fail_unless(domain.length == 33);
416 res = mdns_domain_add_label(&domain, label, (u8_t)strlen(label));
417 fail_unless(res == ERR_OK);
418 fail_unless(domain.length == 66);
419 res = mdns_domain_add_label(&domain, label, (u8_t)strlen(label));
420 fail_unless(res == ERR_OK);
421 fail_unless(domain.length == 99);
422 res = mdns_domain_add_label(&domain, label, (u8_t)strlen(label));
423 fail_unless(res == ERR_OK);
424 fail_unless(domain.length == 132);
425 res = mdns_domain_add_label(&domain, label, (u8_t)strlen(label));
426 fail_unless(res == ERR_OK);
427 fail_unless(domain.length == 165);
428 res = mdns_domain_add_label(&domain, label, (u8_t)strlen(label));
429 fail_unless(res == ERR_OK);
430 fail_unless(domain.length == 198);
431 res = mdns_domain_add_label(&domain, label, (u8_t)strlen(label));
432 fail_unless(res == ERR_OK);
433 fail_unless(domain.length == 231);
434 res = mdns_domain_add_label(&domain, label, (u8_t)strlen(label));
435 fail_unless(res == ERR_VAL);
436 fail_unless(domain.length == 231);
437 res = mdns_domain_add_label(&domain, label, 25);
438 fail_unless(res == ERR_VAL);
439 fail_unless(domain.length == 231);
440 res = mdns_domain_add_label(&domain, label, 24);
441 fail_unless(res == ERR_VAL);
442 fail_unless(domain.length == 231);
443 res = mdns_domain_add_label(&domain, label, 23);
444 fail_unless(res == ERR_OK);
445 fail_unless(domain.length == 255);
446 res = mdns_domain_add_label(&domain, NULL, 0);
447 fail_unless(res == ERR_OK);
448 fail_unless(domain.length == 256);
449 res = mdns_domain_add_label(&domain, NULL, 0);
450 fail_unless(res == ERR_VAL);
451 fail_unless(domain.length == 256);
452 }
453 END_TEST
454
START_TEST(domain_eq_basic)455 START_TEST(domain_eq_basic)
456 {
457 static const u8_t data[] = {
458 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0x00
459 };
460 struct mdns_domain domain1, domain2;
461 err_t res;
462 LWIP_UNUSED_ARG(_i);
463
464 memset(&domain1, 0, sizeof(domain1));
465 res = mdns_domain_add_label(&domain1, "multi", 5);
466 fail_unless(res == ERR_OK);
467 res = mdns_domain_add_label(&domain1, "cast", 4);
468 fail_unless(res == ERR_OK);
469 res = mdns_domain_add_label(&domain1, NULL, 0);
470 fail_unless(res == ERR_OK);
471 fail_unless(domain1.length == sizeof(data));
472
473 memset(&domain2, 0, sizeof(domain2));
474 res = mdns_domain_add_label(&domain2, "multi", 5);
475 fail_unless(res == ERR_OK);
476 res = mdns_domain_add_label(&domain2, "cast", 4);
477 fail_unless(res == ERR_OK);
478 res = mdns_domain_add_label(&domain2, NULL, 0);
479 fail_unless(res == ERR_OK);
480
481 fail_unless(mdns_domain_eq(&domain1, &domain2));
482 }
483 END_TEST
484
START_TEST(domain_eq_diff)485 START_TEST(domain_eq_diff)
486 {
487 struct mdns_domain domain1, domain2;
488 err_t res;
489 LWIP_UNUSED_ARG(_i);
490
491 memset(&domain1, 0, sizeof(domain1));
492 res = mdns_domain_add_label(&domain1, "multi", 5);
493 fail_unless(res == ERR_OK);
494 res = mdns_domain_add_label(&domain1, "base", 4);
495 fail_unless(res == ERR_OK);
496 res = mdns_domain_add_label(&domain1, NULL, 0);
497 fail_unless(res == ERR_OK);
498
499 memset(&domain2, 0, sizeof(domain2));
500 res = mdns_domain_add_label(&domain2, "multi", 5);
501 fail_unless(res == ERR_OK);
502 res = mdns_domain_add_label(&domain2, "cast", 4);
503 fail_unless(res == ERR_OK);
504 res = mdns_domain_add_label(&domain2, NULL, 0);
505 fail_unless(res == ERR_OK);
506
507 fail_if(mdns_domain_eq(&domain1, &domain2));
508 }
509 END_TEST
510
START_TEST(domain_eq_case)511 START_TEST(domain_eq_case)
512 {
513 struct mdns_domain domain1, domain2;
514 err_t res;
515 LWIP_UNUSED_ARG(_i);
516
517 memset(&domain1, 0, sizeof(domain1));
518 res = mdns_domain_add_label(&domain1, "multi", 5);
519 fail_unless(res == ERR_OK);
520 res = mdns_domain_add_label(&domain1, "cast", 4);
521 fail_unless(res == ERR_OK);
522 res = mdns_domain_add_label(&domain1, NULL, 0);
523 fail_unless(res == ERR_OK);
524
525 memset(&domain2, 0, sizeof(domain2));
526 res = mdns_domain_add_label(&domain2, "MulTI", 5);
527 fail_unless(res == ERR_OK);
528 res = mdns_domain_add_label(&domain2, "casT", 4);
529 fail_unless(res == ERR_OK);
530 res = mdns_domain_add_label(&domain2, NULL, 0);
531 fail_unless(res == ERR_OK);
532
533 fail_unless(mdns_domain_eq(&domain1, &domain2));
534 }
535 END_TEST
536
START_TEST(domain_eq_anydata)537 START_TEST(domain_eq_anydata)
538 {
539 static const u8_t data1[] = { 0x05, 0xcc, 0xdc, 0x00, 0xa0 };
540 static const u8_t data2[] = { 0x7f, 0x8c, 0x01, 0xff, 0xcf };
541 struct mdns_domain domain1, domain2;
542 err_t res;
543 LWIP_UNUSED_ARG(_i);
544
545 memset(&domain1, 0, sizeof(domain1));
546 res = mdns_domain_add_label(&domain1, (const char*)data1, sizeof(data1));
547 fail_unless(res == ERR_OK);
548 res = mdns_domain_add_label(&domain1, "cast", 4);
549 fail_unless(res == ERR_OK);
550 res = mdns_domain_add_label(&domain1, (const char*)data2, sizeof(data2));
551 fail_unless(res == ERR_OK);
552 res = mdns_domain_add_label(&domain1, NULL, 0);
553 fail_unless(res == ERR_OK);
554
555 memset(&domain2, 0, sizeof(domain2));
556 res = mdns_domain_add_label(&domain2, (const char*)data1, sizeof(data1));
557 fail_unless(res == ERR_OK);
558 res = mdns_domain_add_label(&domain2, "casT", 4);
559 fail_unless(res == ERR_OK);
560 res = mdns_domain_add_label(&domain2, (const char*)data2, sizeof(data2));
561 fail_unless(res == ERR_OK);
562 res = mdns_domain_add_label(&domain2, NULL, 0);
563 fail_unless(res == ERR_OK);
564
565 fail_unless(mdns_domain_eq(&domain1, &domain2));
566 }
567 END_TEST
568
START_TEST(domain_eq_length)569 START_TEST(domain_eq_length)
570 {
571 struct mdns_domain domain1, domain2;
572 err_t res;
573 LWIP_UNUSED_ARG(_i);
574
575 memset(&domain1, 0, sizeof(domain1));
576 memset(domain1.name, 0xAA, sizeof(MDNS_DOMAIN_MAXLEN));
577 res = mdns_domain_add_label(&domain1, "multi", 5);
578 fail_unless(res == ERR_OK);
579 res = mdns_domain_add_label(&domain1, "cast", 4);
580 fail_unless(res == ERR_OK);
581
582 memset(&domain2, 0, sizeof(domain2));
583 memset(domain2.name, 0xBB, sizeof(MDNS_DOMAIN_MAXLEN));
584 res = mdns_domain_add_label(&domain2, "multi", 5);
585 fail_unless(res == ERR_OK);
586 res = mdns_domain_add_label(&domain2, "cast", 4);
587 fail_unless(res == ERR_OK);
588
589 fail_unless(mdns_domain_eq(&domain1, &domain2));
590 }
591 END_TEST
592
START_TEST(compress_full_match)593 START_TEST(compress_full_match)
594 {
595 static const u8_t data[] = {
596 0x00, 0x00,
597 0x06, 'f', 'o', 'o', 'b', 'a', 'r', 0x05, 'l', 'o', 'c', 'a', 'l', 0x00
598 };
599 struct pbuf *p;
600 struct mdns_domain domain;
601 u16_t offset;
602 u16_t length;
603 err_t res;
604 LWIP_UNUSED_ARG(_i);
605
606 p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
607 fail_if(p == NULL);
608 p->payload = (void *)(size_t)data;
609
610 memset(&domain, 0, sizeof(domain));
611 res = mdns_domain_add_label(&domain, "foobar", 6);
612 fail_unless(res == ERR_OK);
613 res = mdns_domain_add_label(&domain, "local", 5);
614 fail_unless(res == ERR_OK);
615 res = mdns_domain_add_label(&domain, NULL, 0);
616 fail_unless(res == ERR_OK);
617
618 offset = 2;
619 length = mdns_compress_domain(p, &offset, &domain);
620 /* Write 0 bytes, then a jump to addr 2 */
621 fail_unless(length == 0);
622 fail_unless(offset == 2);
623
624 pbuf_free(p);
625 }
626 END_TEST
627
START_TEST(compress_full_match_subset)628 START_TEST(compress_full_match_subset)
629 {
630 static const u8_t data[] = {
631 0x00, 0x00,
632 0x02, 'g', 'o', 0x06, 'f', 'o', 'o', 'b', 'a', 'r', 0x05, 'l', 'o', 'c', 'a', 'l', 0x00
633 };
634 struct pbuf *p;
635 struct mdns_domain domain;
636 u16_t offset;
637 u16_t length;
638 err_t res;
639 LWIP_UNUSED_ARG(_i);
640
641 p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
642 fail_if(p == NULL);
643 p->payload = (void *)(size_t)data;
644
645 memset(&domain, 0, sizeof(domain));
646 res = mdns_domain_add_label(&domain, "foobar", 6);
647 fail_unless(res == ERR_OK);
648 res = mdns_domain_add_label(&domain, "local", 5);
649 fail_unless(res == ERR_OK);
650 res = mdns_domain_add_label(&domain, NULL, 0);
651 fail_unless(res == ERR_OK);
652
653 offset = 2;
654 length = mdns_compress_domain(p, &offset, &domain);
655 /* Write 0 bytes, then a jump to addr 5 */
656 fail_unless(length == 0);
657 fail_unless(offset == 5);
658
659 pbuf_free(p);
660 }
661 END_TEST
662
START_TEST(compress_full_match_jump)663 START_TEST(compress_full_match_jump)
664 {
665 static const u8_t data[] = {
666 /* 0x00 */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
667 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
668 /* 0x10 */ 0x04, 'l', 'w', 'i', 'p', 0x05, 'l', 'o', 'c', 'a', 'l', 0x00, 0xc0, 0x00, 0x02, 0x00,
669 /* 0x20 */ 0x06, 'f', 'o', 'o', 'b', 'a', 'r', 0xc0, 0x15
670 };
671 struct pbuf *p;
672 struct mdns_domain domain;
673 u16_t offset;
674 u16_t length;
675 err_t res;
676 LWIP_UNUSED_ARG(_i);
677
678 p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
679 fail_if(p == NULL);
680 p->payload = (void *)(size_t)data;
681
682 memset(&domain, 0, sizeof(domain));
683 res = mdns_domain_add_label(&domain, "foobar", 6);
684 fail_unless(res == ERR_OK);
685 res = mdns_domain_add_label(&domain, "local", 5);
686 fail_unless(res == ERR_OK);
687 res = mdns_domain_add_label(&domain, NULL, 0);
688 fail_unless(res == ERR_OK);
689
690 offset = 0x20;
691 length = mdns_compress_domain(p, &offset, &domain);
692 /* Write 0 bytes, then a jump to addr 0x20 */
693 fail_unless(length == 0);
694 fail_unless(offset == 0x20);
695
696 pbuf_free(p);
697 }
698 END_TEST
699
START_TEST(compress_no_match)700 START_TEST(compress_no_match)
701 {
702 static const u8_t data[] = {
703 0x00, 0x00,
704 0x04, 'l', 'w', 'i', 'p', 0x05, 'w', 'i', 'k', 'i', 'a', 0x03, 'c', 'o', 'm', 0x00
705 };
706 struct pbuf *p;
707 struct mdns_domain domain;
708 u16_t offset;
709 u16_t length;
710 err_t res;
711 LWIP_UNUSED_ARG(_i);
712
713 p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
714 fail_if(p == NULL);
715 p->payload = (void *)(size_t)data;
716
717 memset(&domain, 0, sizeof(domain));
718 res = mdns_domain_add_label(&domain, "foobar", 6);
719 fail_unless(res == ERR_OK);
720 res = mdns_domain_add_label(&domain, "local", 5);
721 fail_unless(res == ERR_OK);
722 res = mdns_domain_add_label(&domain, NULL, 0);
723 fail_unless(res == ERR_OK);
724
725 offset = 2;
726 length = mdns_compress_domain(p, &offset, &domain);
727 /* Write all bytes, no jump */
728 fail_unless(length == domain.length);
729
730 pbuf_free(p);
731 }
732 END_TEST
733
START_TEST(compress_2nd_label)734 START_TEST(compress_2nd_label)
735 {
736 static const u8_t data[] = {
737 0x00, 0x00,
738 0x06, 'f', 'o', 'o', 'b', 'a', 'r', 0x05, 'l', 'o', 'c', 'a', 'l', 0x00
739 };
740 struct pbuf *p;
741 struct mdns_domain domain;
742 u16_t offset;
743 u16_t length;
744 err_t res;
745 LWIP_UNUSED_ARG(_i);
746
747 p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
748 fail_if(p == NULL);
749 p->payload = (void *)(size_t)data;
750
751 memset(&domain, 0, sizeof(domain));
752 res = mdns_domain_add_label(&domain, "lwip", 4);
753 fail_unless(res == ERR_OK);
754 res = mdns_domain_add_label(&domain, "local", 5);
755 fail_unless(res == ERR_OK);
756 res = mdns_domain_add_label(&domain, NULL, 0);
757 fail_unless(res == ERR_OK);
758
759 offset = 2;
760 length = mdns_compress_domain(p, &offset, &domain);
761 /* Write 5 bytes, then a jump to addr 9 */
762 fail_unless(length == 5);
763 fail_unless(offset == 9);
764
765 pbuf_free(p);
766 }
767 END_TEST
768
START_TEST(compress_2nd_label_short)769 START_TEST(compress_2nd_label_short)
770 {
771 static const u8_t data[] = {
772 0x00, 0x00,
773 0x04, 'l', 'w', 'i', 'p', 0x05, 'l', 'o', 'c', 'a', 'l', 0x00
774 };
775 struct pbuf *p;
776 struct mdns_domain domain;
777 u16_t offset;
778 u16_t length;
779 err_t res;
780 LWIP_UNUSED_ARG(_i);
781
782 p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
783 fail_if(p == NULL);
784 p->payload = (void *)(size_t)data;
785
786 memset(&domain, 0, sizeof(domain));
787 res = mdns_domain_add_label(&domain, "foobar", 6);
788 fail_unless(res == ERR_OK);
789 res = mdns_domain_add_label(&domain, "local", 5);
790 fail_unless(res == ERR_OK);
791 res = mdns_domain_add_label(&domain, NULL, 0);
792 fail_unless(res == ERR_OK);
793
794 offset = 2;
795 length = mdns_compress_domain(p, &offset, &domain);
796 /* Write 5 bytes, then a jump to addr 7 */
797 fail_unless(length == 7);
798 fail_unless(offset == 7);
799
800 pbuf_free(p);
801 }
802 END_TEST
803
START_TEST(compress_jump_to_jump)804 START_TEST(compress_jump_to_jump)
805 {
806 static const u8_t data[] = {
807 /* 0x00 */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
808 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
809 /* 0x10 */ 0x04, 'l', 'w', 'i', 'p', 0x05, 'l', 'o', 'c', 'a', 'l', 0x00, 0xc0, 0x00, 0x02, 0x00,
810 /* 0x20 */ 0x07, 'b', 'a', 'n', 'a', 'n', 'a', 's', 0xc0, 0x15
811 };
812 struct pbuf *p;
813 struct mdns_domain domain;
814 u16_t offset;
815 u16_t length;
816 err_t res;
817 LWIP_UNUSED_ARG(_i);
818
819 p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
820 fail_if(p == NULL);
821 p->payload = (void *)(size_t)data;
822
823 memset(&domain, 0, sizeof(domain));
824 res = mdns_domain_add_label(&domain, "foobar", 6);
825 fail_unless(res == ERR_OK);
826 res = mdns_domain_add_label(&domain, "local", 5);
827 fail_unless(res == ERR_OK);
828 res = mdns_domain_add_label(&domain, NULL, 0);
829 fail_unless(res == ERR_OK);
830
831 offset = 0x20;
832 length = mdns_compress_domain(p, &offset, &domain);
833 /* Don't compress if jump would be to a jump */
834 fail_unless(length == domain.length);
835
836 offset = 0x10;
837 length = mdns_compress_domain(p, &offset, &domain);
838 /* Write 7 bytes, then a jump to addr 0x15 */
839 fail_unless(length == 7);
840 fail_unless(offset == 0x15);
841
842 pbuf_free(p);
843 }
844 END_TEST
845
START_TEST(compress_long_match)846 START_TEST(compress_long_match)
847 {
848 static const u8_t data[] = {
849 0x00, 0x00,
850 0x06, 'f', 'o', 'o', 'b', 'a', 'r', 0x05, 'l', 'o', 'c', 'a', 'l', 0x03, 'c', 'o', 'm', 0x00
851 };
852 struct pbuf *p;
853 struct mdns_domain domain;
854 u16_t offset;
855 u16_t length;
856 err_t res;
857 LWIP_UNUSED_ARG(_i);
858
859 p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
860 fail_if(p == NULL);
861 p->payload = (void *)(size_t)data;
862
863 memset(&domain, 0, sizeof(domain));
864 res = mdns_domain_add_label(&domain, "foobar", 6);
865 fail_unless(res == ERR_OK);
866 res = mdns_domain_add_label(&domain, "local", 5);
867 fail_unless(res == ERR_OK);
868 res = mdns_domain_add_label(&domain, NULL, 0);
869 fail_unless(res == ERR_OK);
870
871 offset = 2;
872 length = mdns_compress_domain(p, &offset, &domain);
873 fail_unless(length == domain.length);
874
875 pbuf_free(p);
876 }
877 END_TEST
878
mdns_suite(void)879 Suite* mdns_suite(void)
880 {
881 testfunc tests[] = {
882 TESTFUNC(readname_basic),
883 TESTFUNC(readname_anydata),
884 TESTFUNC(readname_short_buf),
885 TESTFUNC(readname_long_label),
886 TESTFUNC(readname_overflow),
887 TESTFUNC(readname_jump_earlier),
888 TESTFUNC(readname_jump_earlier_jump),
889 TESTFUNC(readname_jump_maxdepth),
890 TESTFUNC(readname_jump_later),
891 TESTFUNC(readname_half_jump),
892 TESTFUNC(readname_jump_toolong),
893 TESTFUNC(readname_jump_loop_label),
894 TESTFUNC(readname_jump_loop_jump),
895
896 TESTFUNC(add_label_basic),
897 TESTFUNC(add_label_long_label),
898 TESTFUNC(add_label_full),
899
900 TESTFUNC(domain_eq_basic),
901 TESTFUNC(domain_eq_diff),
902 TESTFUNC(domain_eq_case),
903 TESTFUNC(domain_eq_anydata),
904 TESTFUNC(domain_eq_length),
905
906 TESTFUNC(compress_full_match),
907 TESTFUNC(compress_full_match_subset),
908 TESTFUNC(compress_full_match_jump),
909 TESTFUNC(compress_no_match),
910 TESTFUNC(compress_2nd_label),
911 TESTFUNC(compress_2nd_label_short),
912 TESTFUNC(compress_jump_to_jump),
913 TESTFUNC(compress_long_match),
914 };
915 return create_suite("MDNS", tests, sizeof(tests)/sizeof(testfunc), NULL, NULL);
916 }
917