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