New upstream release:
[debian/iodine.git] / tests / read.c
1 /*
2  * Copyright (c) 2006-2007 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)
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         unsigned char infloop[] = {
92                 'A', 'A', 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93                 0x01, 'A', 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01 };
94         unsigned char longname[] =
95                 "AA\x81\x80\x00\x01\x00\x00\x00\x00\x00\x00"
96                 "\x3FzBCDEFGHIJKLMNOPQURSTUVXYZ0123456789abcdefghijklmnopqrstuvxyzAA"
97                 "\x3FzBCDEFGHIJKLMNOPQURSTUVXYZ0123456789abcdefghijklmnopqrstuvxyzAA"
98                 "\x3FzBCDEFGHIJKLMNOPQURSTUVXYZ0123456789abcdefghijklmnopqrstuvxyzAA"
99                 "\x3FzBCDEFGHIJKLMNOPQURSTUVXYZ0123456789abcdefghijklmnopqrstuvxyzAA"
100                 "\x3FzBCDEFGHIJKLMNOPQURSTUVXYZ0123456789abcdefghijklmnopqrstuvxyzAA"
101                 "\x3FzBCDEFGHIJKLMNOPQURSTUVXYZ0123456789abcdefghijklmnopqrstuvxyzAA"
102                 "\x00\x00\x01\x00\x01";
103         unsigned char onejump[] =
104                 "AA\x81\x80\x00\x01\x00\x00\x00\x00\x00\x00"
105                 "\x02hh\xc0\x15\x00\x01\x00\x01\x05zBCDE\x00";
106         unsigned char badjump[] = {
107                 'A', 'A', 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
108                 0xfe, 0xcc, 0x00, 0x01, 0x00, 0x01 };
109         unsigned char badjump2[] = {
110                 'A', 'A', 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
111                 0x02, 'B', 'A', 0xfe, 0xcc, 0x00, 0x01, 0x00, 0x01 };
112         unsigned char *jumper;
113         char buf[1024];
114         char *data;
115         int rv;
116
117         memset(buf, 0, sizeof(buf));
118         data = (char*) emptyloop + sizeof(HEADER);
119         buf[1023] = 'A';
120         rv = readname((char *) emptyloop, sizeof(emptyloop), &data, buf, 1023);
121         fail_unless(buf[1023] == 'A', NULL);
122
123         memset(buf, 0, sizeof(buf));
124         data = (char*) infloop + sizeof(HEADER);
125         buf[4] = '\a';
126         rv = readname((char*) infloop, sizeof(infloop), &data, buf, 4);
127         fail_unless(buf[4] == '\a', NULL);
128
129         memset(buf, 0, sizeof(buf));
130         data = (char*) longname + sizeof(HEADER);
131         buf[256] = '\a';
132         rv = readname((char*) longname, sizeof(longname), &data, buf, 256);
133         fail_unless(buf[256] == '\a', NULL);
134
135         memset(buf, 0, sizeof(buf));
136         data = (char*) onejump + sizeof(HEADER);
137         rv = readname((char*) onejump, sizeof(onejump), &data, buf, 256);
138         fail_unless(rv == 9, NULL);
139
140         /* These two tests use malloc to cause segfault if jump is executed */
141         memset(buf, 0, sizeof(buf));
142         jumper = malloc(sizeof(badjump));
143         if (jumper) {
144                 memcpy(jumper, badjump, sizeof(badjump));
145                 data = (char*) jumper + sizeof(HEADER);
146                 rv = readname((char*) jumper, sizeof(badjump), &data, buf, 256);
147
148                 fail_unless(rv == 0, NULL);
149                 fail_unless(buf[0] == 0, NULL);
150         }
151         free(jumper);
152
153         memset(buf, 0, sizeof(buf));
154         jumper = malloc(sizeof(badjump2));
155         if (jumper) {
156                 memcpy(jumper, badjump2, sizeof(badjump2));
157                 data = (char*) jumper + sizeof(HEADER);
158                 rv = readname((char*) jumper, sizeof(badjump2), &data, buf, 256);
159
160                 fail_unless(rv == 4, NULL);
161                 fail_unless(strcmp("BA.", buf) == 0,
162                                 "buf is not BA: %s", buf);
163         }
164         free(jumper);
165 }
166 END_TEST
167
168 START_TEST(test_putname)
169 {
170         char out[] = "\x06" "BADGER\x06" "BADGER\x04" "KRYO\x02" "SE\x00";
171         char buf[256];
172         char *domain = "BADGER.BADGER.KRYO.SE";
173         char *b;
174         int len;
175         int ret;
176
177         len = 256;
178
179         memset(buf, 0, 256);
180         b = buf;
181         ret = putname(&b, 256, domain);
182
183         fail_unless(ret == strlen(domain) + 1, NULL);
184         fail_unless(strncmp(buf, out, ret) == 0, "Happy flow failed");
185 }
186 END_TEST
187
188 START_TEST(test_putname_nodot)
189 {
190         char buf[256];
191         char *nodot =
192                 "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"
193                 "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ";
194         char *b;
195         int len;
196         int ret;
197
198         len = 256;
199
200         memset(buf, 0, 256);
201         b = buf;
202         ret = putname(&b, 256, nodot);
203
204         fail_unless(ret == -1, NULL);
205         fail_unless(b == buf, NULL);
206 }
207 END_TEST
208
209 START_TEST(test_putname_toolong)
210 {
211         char buf[256];
212         char *toolong =
213                 "ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ."
214                 "ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ."
215                 "ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ."
216                 "ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ."
217                 "ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ."
218                 "ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ.";
219         char *b;
220         int len;
221         int ret;
222
223         len = 256;
224
225         memset(buf, 0, 256);
226         b = buf;
227         ret = putname(&b, 256, toolong);
228
229         fail_unless(ret == -1, NULL);
230         fail_unless(b == buf, NULL);
231 }
232 END_TEST
233
234
235 TCase *
236 test_read_create_tests()
237 {
238         TCase *tc;
239
240         tc = tcase_create("Read");
241         tcase_set_timeout(tc, 60);
242         tcase_add_test(tc, test_read_putshort);
243         tcase_add_test(tc, test_read_putlong);
244         tcase_add_test(tc, test_read_name);
245         tcase_add_test(tc, test_putname);
246         tcase_add_test(tc, test_putname_nodot);
247         tcase_add_test(tc, test_putname_toolong);
248
249         return tc;
250 }