[svn-inject] Applying Debian modifications to trunk
[debian/iodine.git] / test.c
1 /*
2  * Copyright (c) 2006 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 <assert.h>
30
31 #include "structs.h"
32 #include "encoding.h"
33 #include "dns.h"
34 #include "read.h"
35         
36 static void
37 test_readputshort()
38 {
39         short tshort;
40         short putted;
41         short temps;
42         char buf[4];
43         short *s;
44         char* p;
45         int i;
46
47         printf(" * Testing read/putshort... ");
48         fflush(stdout);
49
50         for (i = 0; i < 65536; i++) {
51                 tshort = (unsigned short) i;
52                 temps = htons(tshort);
53                 p = buf;
54                 putshort(&p, tshort);
55                 s = &putted;
56                 memcpy(s, buf, sizeof(short));
57                 if (putted != temps) {
58                         printf("Bad value on putshort for %d\n", i);
59                         exit(1);
60                 }
61                 s = &temps;
62                 memcpy(buf, s, sizeof(short));
63                 p = buf;
64                 readshort(NULL, &p, &temps);
65                 if (temps != tshort) {
66                         printf("Bad value on readshort for %d\n", i);
67                         exit(1);
68                 }
69         }
70
71         printf("OK\n");
72 }
73
74 static void
75 test_readputlong()
76 {
77         char buf[4];
78         uint32_t putint;
79         uint32_t tempi;
80         uint32_t tint;
81         uint32_t *l;
82         char* p;
83         int i;
84
85         printf(" * Testing read/putlong... ");
86         fflush(stdout);
87
88         for (i = 0; i < 32; i++) {
89                 tint = 0xF << i;
90                 tempi = htonl(tint);
91                 p = buf;
92                 putlong(&p, tint);
93                 l = &putint;
94                 memcpy(l, buf, sizeof(uint32_t));
95                 if (putint != tempi) {
96                         printf("Bad value on putlong for %d\n", i);
97                         exit(2);
98                 }
99                 l = &tempi;
100                 memcpy(buf, l, sizeof(uint32_t));
101                 p = buf;
102                 readlong(NULL, &p, &tempi);
103                 if (tempi != tint) {
104                         printf("Bad value on readlong for %d\n", i);
105                         exit(2);
106                 }
107         }
108
109         printf("OK\n");
110 }
111
112
113 static void
114 test_readname()
115 {
116         char emptyloop[] = {
117                 'A', 'A', 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
118                 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01 }; 
119         char infloop[] = {
120                 'A', 'A', 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
121                 0x01, 'A', 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01 }; 
122         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 onejump[] = 
132                 "AA\x81\x80\x00\x01\x00\x00\x00\x00\x00\x00"
133                 "\x02hh\xc0\x15\x00\x01\x00\x01\x05zBCDE\x00";
134         char badjump[] = {
135                 'A', 'A', 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
136                 0xfe, 0xcc, 0x00, 0x01, 0x00, 0x01 }; 
137         char badjump2[] = {
138                 'A', 'A', 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
139                 0x02, 'B', 'A', 0xfe, 0xcc, 0x00, 0x01, 0x00, 0x01 }; 
140         char *jumper;
141         char buf[1024];
142         char *data;
143         int rv;
144
145         printf(" * Testing readname... ");
146         fflush(stdout);
147
148         memset(buf, 0, sizeof(buf));
149         data = emptyloop + sizeof(HEADER);
150         buf[1023] = 'A';
151         rv = readname(emptyloop, sizeof(emptyloop), &data, buf, 1023);
152         assert(buf[1023] == 'A');
153         
154         memset(buf, 0, sizeof(buf));
155         data = infloop + sizeof(HEADER);
156         buf[4] = '\a';
157         rv = readname(infloop, sizeof(infloop), &data, buf, 4);
158         assert(buf[4] == '\a');
159         
160         memset(buf, 0, sizeof(buf));
161         data = longname + sizeof(HEADER);
162         buf[256] = '\a';
163         rv = readname(longname, sizeof(longname), &data, buf, 256);
164         assert(buf[256] == '\a');
165
166         memset(buf, 0, sizeof(buf));
167         data = onejump + sizeof(HEADER);
168         rv = readname(onejump, sizeof(onejump), &data, buf, 256);
169         assert(rv == 9);
170         
171         // These two tests use malloc to cause segfault if jump is executed
172         memset(buf, 0, sizeof(buf));
173         jumper = malloc(sizeof(badjump));
174         if (jumper) {
175                 memcpy(jumper, badjump, sizeof(badjump));
176                 data = jumper + sizeof(HEADER);
177                 rv = readname(jumper, sizeof(badjump), &data, buf, 256);
178                 assert(rv == 0);
179         }
180         free(jumper);
181         
182         memset(buf, 0, sizeof(buf));
183         jumper = malloc(sizeof(badjump2));
184         if (jumper) {
185                 memcpy(jumper, badjump2, sizeof(badjump2));
186                 data = jumper + sizeof(HEADER);
187                 rv = readname(jumper, sizeof(badjump2), &data, buf, 256);
188                 assert(rv == 4);
189                 assert(strcmp("BA.", buf) == 0);
190         }
191         free(jumper);
192
193         printf("OK\n");
194 }
195
196 static void
197 test_encode_hostname() {
198         char buf[256];
199         int len;
200         int ret;
201
202         len = 256;
203         printf(" * Testing hostname encoding... ");
204         fflush(stdout);
205
206         memset(buf, 0, 256);
207         ret = dns_encode_hostname(      // More than 63 chars between dots
208                 "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"
209                 , buf, len);
210         assert(ret == -1);
211         
212         memset(buf, 0, 256);
213         ret = dns_encode_hostname(      // More chars than fits into array
214                 "ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ."
215                 "ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ."
216                 "ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ."
217                 , buf, len);
218         assert(ret == -1);
219         assert(strlen(buf) < len);
220         
221         printf("OK\n");
222 }
223
224 static void
225 test_base32() {
226         char temp[256];
227         char *start = "HELLOTEST";
228         char *out = "1HELLOTEST";
229         char *end;
230         char *tempend;
231         int codedlength;
232
233         printf(" * Testing base32 encoding... ");
234         fflush(stdout);
235
236         memset(temp, 0, sizeof(temp));
237         end = malloc(16);
238         memset(end, 0, 16);
239
240         codedlength = encode_data(start, 9, 256, temp, 0);
241         tempend = temp + strlen(temp);
242         decode_data(end, 16, temp, tempend);
243         assert(strcmp(out, end) == 0);
244         free(end);
245         
246         printf("OK\n");
247 }
248
249 int
250 main()
251 {
252         printf("** iodine test suite\n");
253
254         test_readputshort();
255         test_readputlong();
256         test_readname();
257         test_encode_hostname();
258         test_base32();
259
260         printf("** All went well :)\n");
261         return 0;
262 }