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