Add new patch cross.patch to fix cross compilation.
[debian/iodine.git] / tests / read.c
1 /*
2  * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
3  * 2006-2009 Bjorn Andersson <flex@kryo.se>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17
18 #include <sys/types.h>
19 #include <sys/socket.h>
20 #include <netinet/in.h>
21 #include <sys/stat.h>
22 #include <arpa/nameser.h>
23 #ifdef DARWIN
24 #define BIND_8_COMPAT
25 #include <arpa/nameser_compat.h>
26 #endif
27 #include <stdio.h>
28 #include <stdint.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <check.h>
32
33 #include "common.h"
34 #include "encoding.h"
35 #include "dns.h"
36 #include "read.h"
37 #include "test.h"
38
39 START_TEST(test_read_putshort)
40 {
41         unsigned short k;
42         unsigned short l;
43         char* p;
44         int i;
45
46         for (i = 0; i < 65536; i++) {
47                 p = (char*)&k;
48                 putshort(&p, i);
49                 fail_unless(ntohs(k) == i,
50                                 "Bad value on putshort for %d: %d != %d",
51                                         i, ntohs(k), i);
52
53                 p = (char*)&k;
54                 readshort(NULL, &p, &l);
55                 fail_unless(l == i,
56                                 "Bad value on readshort for %d: %d != %d",
57                                         i, l, i);
58         }
59 }
60 END_TEST
61
62 START_TEST(test_read_putlong)
63 {
64         uint32_t k;
65         uint32_t l;
66         char* p;
67         int i;
68         int j;
69
70         for (i = 0; i < 32; i++) {
71                 p = (char*)&k;
72                 j = 0xf << i;
73
74                 putlong(&p, j);
75
76                 fail_unless(ntohl(k) == j,
77                                 "Bad value on putlong for %d: %d != %d", i, ntohl(j), j);
78
79                 p = (char*)&k;
80                 readlong(NULL, &p, &l);
81
82                 fail_unless(l == j,
83                                 "Bad value on readlong for %d: %d != %d", i, l, j);
84         }
85 }
86 END_TEST
87
88 START_TEST(test_read_name_empty_loop)
89 {
90         unsigned char emptyloop[] = {
91                 'A', 'A', 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92                 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01 };
93         char buf[1024];
94         char *data;
95         int rv;
96
97         memset(buf, 0, sizeof(buf));
98         data = (char*) emptyloop + sizeof(HEADER);
99         buf[1023] = 'A';
100         rv = readname((char *) emptyloop, sizeof(emptyloop), &data, buf, 1023);
101         fail_unless(rv == 0);
102         fail_unless(buf[1023] == 'A');
103 }
104 END_TEST
105
106 START_TEST(test_read_name_inf_loop)
107 {
108         unsigned char infloop[] = {
109                 'A', 'A', 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
110                 0x01, 'A', 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01 };
111         char buf[1024];
112         char *data;
113         int rv;
114
115         memset(buf, 0, sizeof(buf));
116         data = (char*) infloop + sizeof(HEADER);
117         buf[4] = '\a';
118         rv = readname((char*) infloop, sizeof(infloop), &data, buf, 4);
119         fail_unless(rv == 3);
120         fail_unless(buf[4] == '\a');
121 }
122 END_TEST
123
124 START_TEST(test_read_name_longname)
125 {
126         unsigned char longname[] =
127                 "AA\x81\x80\x00\x01\x00\x00\x00\x00\x00\x00"
128                 "\x3FzBCDEFGHIJKLMNOPQURSTUVXYZ0123456789abcdefghijklmnopqrstuvxyzAA"
129                 "\x3FzBCDEFGHIJKLMNOPQURSTUVXYZ0123456789abcdefghijklmnopqrstuvxyzAA"
130                 "\x3FzBCDEFGHIJKLMNOPQURSTUVXYZ0123456789abcdefghijklmnopqrstuvxyzAA"
131                 "\x3FzBCDEFGHIJKLMNOPQURSTUVXYZ0123456789abcdefghijklmnopqrstuvxyzAA"
132                 "\x3FzBCDEFGHIJKLMNOPQURSTUVXYZ0123456789abcdefghijklmnopqrstuvxyzAA"
133                 "\x3FzBCDEFGHIJKLMNOPQURSTUVXYZ0123456789abcdefghijklmnopqrstuvxyzAA"
134                 "\x00\x00\x01\x00\x01";
135         char buf[1024];
136         char *data;
137         int rv;
138
139         memset(buf, 0, sizeof(buf));
140         data = (char*) longname + sizeof(HEADER);
141         buf[256] = '\a';
142         rv = readname((char*) longname, sizeof(longname), &data, buf, 256);
143         fail_unless(rv == 256);
144         fail_unless(buf[256] == '\a');
145 }
146 END_TEST
147
148 START_TEST(test_read_name_onejump)
149 {
150         unsigned char onejump[] =
151                 "AA\x81\x80\x00\x01\x00\x00\x00\x00\x00\x00"
152                 "\x02hh\xc0\x15\x00\x01\x00\x01\x05zBCDE\x00";
153         char buf[1024];
154         char *data;
155         int rv;
156
157         memset(buf, 0, sizeof(buf));
158         data = (char*) onejump + sizeof(HEADER);
159         rv = readname((char*) onejump, sizeof(onejump), &data, buf, 256);
160         fail_unless(rv == 9);
161 }
162 END_TEST
163
164 START_TEST(test_read_name_badjump_start)
165 {
166         unsigned char badjump[] = {
167                 'A', 'A', 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
168                 0xfe, 0xcc, 0x00, 0x01, 0x00, 0x01 };
169         unsigned char *jumper;
170         char buf[1024];
171         char *data;
172         int rv;
173
174         /* This test uses malloc to cause segfault if jump is executed */
175         memset(buf, 0, sizeof(buf));
176         jumper = malloc(sizeof(badjump));
177         if (jumper) {
178                 memcpy(jumper, badjump, sizeof(badjump));
179                 data = (char*) jumper + sizeof(HEADER);
180                 rv = readname((char*) jumper, sizeof(badjump), &data, buf, 256);
181
182                 fail_unless(rv == 0);
183                 fail_unless(buf[0] == 0);
184         }
185         free(jumper);
186 }
187 END_TEST
188
189 START_TEST(test_read_name_badjump_second)
190 {
191         unsigned char badjump2[] = {
192                 'A', 'A', 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
193                 0x02, 'B', 'A', 0xfe, 0xcc, 0x00, 0x01, 0x00, 0x01 };
194         unsigned char *jumper;
195         char buf[1024];
196         char *data;
197         int rv;
198
199         /* This test uses malloc to cause segfault if jump is executed */
200         memset(buf, 0, sizeof(buf));
201         jumper = malloc(sizeof(badjump2));
202         if (jumper) {
203                 memcpy(jumper, badjump2, sizeof(badjump2));
204                 data = (char*) jumper + sizeof(HEADER);
205                 rv = readname((char*) jumper, sizeof(badjump2), &data, buf, 256);
206
207                 fail_unless(rv == 4);
208                 fail_unless(strcmp("BA.", buf) == 0,
209                                 "buf is not BA: %s", buf);
210         }
211         free(jumper);
212 }
213 END_TEST
214
215 START_TEST(test_putname)
216 {
217         char out[] = "\x06" "BADGER\x06" "BADGER\x04" "KRYO\x02" "SE\x00";
218         char buf[256];
219         char *domain = "BADGER.BADGER.KRYO.SE";
220         char *b;
221         int ret;
222
223         memset(buf, 0, 256);
224         b = buf;
225         ret = putname(&b, 256, domain);
226
227         fail_unless(ret == strlen(domain) + 1);
228         fail_unless(strncmp(buf, out, ret) == 0, "Happy flow failed");
229 }
230 END_TEST
231
232 START_TEST(test_putname_nodot)
233 {
234         char buf[256];
235         char *nodot =
236                 "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"
237                 "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ";
238         char *b;
239         int ret;
240
241         memset(buf, 0, 256);
242         b = buf;
243         ret = putname(&b, 256, nodot);
244
245         fail_unless(ret == -1);
246         fail_unless(b == buf);
247 }
248 END_TEST
249
250 START_TEST(test_putname_toolong)
251 {
252         char buf[256];
253         char *toolong =
254                 "ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ."
255                 "ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ."
256                 "ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ."
257                 "ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ."
258                 "ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ."
259                 "ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ.";
260         char *b;
261         int ret;
262
263         memset(buf, 0, 256);
264         b = buf;
265         ret = putname(&b, 256, toolong);
266
267         fail_unless(ret == -1);
268         fail_unless(b == buf);
269 }
270 END_TEST
271
272
273 TCase *
274 test_read_create_tests()
275 {
276         TCase *tc;
277
278         tc = tcase_create("Read");
279         tcase_set_timeout(tc, 60);
280         tcase_add_test(tc, test_read_putshort);
281         tcase_add_test(tc, test_read_putlong);
282         tcase_add_test(tc, test_read_name_empty_loop);
283         tcase_add_test(tc, test_read_name_inf_loop);
284         tcase_add_test(tc, test_read_name_longname);
285         tcase_add_test(tc, test_read_name_onejump);
286         tcase_add_test(tc, test_read_name_badjump_start);
287         tcase_add_test(tc, test_read_name_badjump_second);
288         tcase_add_test(tc, test_putname);
289         tcase_add_test(tc, test_putname_nodot);
290         tcase_add_test(tc, test_putname_toolong);
291
292         return tc;
293 }