1
2 #include <setjmp.h>
3 #include <stdlib.h>
4
5 #include "dhcpd.h"
6
7 jmp_buf env;
8
9 void expand_domain_search(struct packet *packet);
10
11 void
no_option_present()12 no_option_present()
13 {
14 int ret;
15 struct option_data option;
16 struct packet p;
17
18 option.data = NULL;
19 option.len = 0;
20 p.options[DHO_DOMAIN_SEARCH] = option;
21
22 ret = setjmp(env);
23 if (ret == 0)
24 expand_domain_search(&p);
25
26 if (p.options[DHO_DOMAIN_SEARCH].len != 0 ||
27 p.options[DHO_DOMAIN_SEARCH].data != NULL)
28 abort();
29 }
30
31 void
one_domain_valid()32 one_domain_valid()
33 {
34 int ret;
35 struct packet p;
36 struct option_data *option;
37
38 char *data = "\007example\003org\0";
39 char *expected = "example.org.";
40
41 option = &p.options[DHO_DOMAIN_SEARCH];
42 option->len = 13;
43 option->data = malloc(option->len);
44 memcpy(option->data, data, option->len);
45
46 ret = setjmp(env);
47 if (ret == 0)
48 expand_domain_search(&p);
49
50 if (option->len != strlen(expected) ||
51 strcmp(option->data, expected) != 0)
52 abort();
53
54 free(option->data);
55 }
56
57 void
one_domain_truncated1()58 one_domain_truncated1()
59 {
60 int ret;
61 struct option_data *option;
62 struct packet p;
63
64 char *data = "\007example\003org";
65
66 option = &p.options[DHO_DOMAIN_SEARCH];
67 option->len = 12;
68 option->data = malloc(option->len);
69 memcpy(option->data, data, option->len);
70
71 ret = setjmp(env);
72 if (ret == 0)
73 expand_domain_search(&p);
74
75 if (ret != 1)
76 abort();
77
78 free(option->data);
79 }
80
81 void
one_domain_truncated2()82 one_domain_truncated2()
83 {
84 int ret;
85 struct option_data *option;
86 struct packet p;
87
88 char *data = "\007ex";
89
90 option = &p.options[DHO_DOMAIN_SEARCH];
91 option->len = 3;
92 option->data = malloc(option->len);
93 memcpy(option->data, data, option->len);
94
95 ret = setjmp(env);
96 if (ret == 0)
97 expand_domain_search(&p);
98
99 if (ret != 1)
100 abort();
101
102 free(option->data);
103 }
104
105 void
two_domains_valid()106 two_domains_valid()
107 {
108 int ret;
109 struct packet p;
110 struct option_data *option;
111
112 char *data = "\007example\003org\0\007example\003com\0";
113 char *expected = "example.org. example.com.";
114
115 option = &p.options[DHO_DOMAIN_SEARCH];
116 option->len = 26;
117 option->data = malloc(option->len);
118 memcpy(option->data, data, option->len);
119
120 ret = setjmp(env);
121 if (ret == 0)
122 expand_domain_search(&p);
123
124 if (option->len != strlen(expected) ||
125 strcmp(option->data, expected) != 0)
126 abort();
127
128 free(option->data);
129 }
130
131 void
two_domains_truncated1()132 two_domains_truncated1()
133 {
134 int ret;
135 struct option_data *option;
136 struct packet p;
137
138 char *data = "\007example\003org\0\007example\003com";
139
140 option = &p.options[DHO_DOMAIN_SEARCH];
141 option->len = 25;
142 option->data = malloc(option->len);
143 memcpy(option->data, data, option->len);
144
145 ret = setjmp(env);
146 if (ret == 0)
147 expand_domain_search(&p);
148
149 if (ret != 1)
150 abort();
151
152 free(option->data);
153 }
154
155 void
two_domains_truncated2()156 two_domains_truncated2()
157 {
158 int ret;
159 struct option_data *option;
160 struct packet p;
161
162 char *data = "\007example\003org\0\007ex";
163
164 option = &p.options[DHO_DOMAIN_SEARCH];
165 option->len = 16;
166 option->data = malloc(option->len);
167 memcpy(option->data, data, option->len);
168
169 ret = setjmp(env);
170 if (ret == 0)
171 expand_domain_search(&p);
172
173 if (ret != 1)
174 abort();
175
176 free(option->data);
177 }
178
179 void
two_domains_compressed()180 two_domains_compressed()
181 {
182 int ret;
183 struct packet p;
184 struct option_data *option;
185
186 char *data = "\007example\003org\0\006foobar\xc0\x08";
187 char *expected = "example.org. foobar.org.";
188
189 option = &p.options[DHO_DOMAIN_SEARCH];
190 option->len = 22;
191 option->data = malloc(option->len);
192 memcpy(option->data, data, option->len);
193
194 ret = setjmp(env);
195 if (ret == 0)
196 expand_domain_search(&p);
197
198 if (option->len != strlen(expected) ||
199 strcmp(option->data, expected) != 0)
200 abort();
201
202 free(option->data);
203 }
204
205 void
two_domains_infloop()206 two_domains_infloop()
207 {
208 int ret;
209 struct packet p;
210 struct option_data *option;
211
212 char *data = "\007example\003org\0\006foobar\xc0\x0d";
213
214 option = &p.options[DHO_DOMAIN_SEARCH];
215 option->len = 22;
216 option->data = malloc(option->len);
217 memcpy(option->data, data, option->len);
218
219 ret = setjmp(env);
220 if (ret == 0)
221 expand_domain_search(&p);
222
223 if (ret != 1)
224 abort();
225
226 free(option->data);
227 }
228
229 void
two_domains_forwardptr()230 two_domains_forwardptr()
231 {
232 int ret;
233 struct packet p;
234 struct option_data *option;
235
236 char *data = "\007example\003org\xc0\x0d\006foobar\0";
237
238 option = &p.options[DHO_DOMAIN_SEARCH];
239 option->len = 22;
240 option->data = malloc(option->len);
241 memcpy(option->data, data, option->len);
242
243 ret = setjmp(env);
244 if (ret == 0)
245 expand_domain_search(&p);
246
247 if (ret != 1)
248 abort();
249
250 free(option->data);
251 }
252
253 void
two_domains_truncatedptr()254 two_domains_truncatedptr()
255 {
256 int ret;
257 struct packet p;
258 struct option_data *option;
259
260 char *data = "\007example\003org\0\006foobar\xc0";
261
262 option = &p.options[DHO_DOMAIN_SEARCH];
263 option->len = 21;
264 option->data = malloc(option->len);
265 memcpy(option->data, data, option->len);
266
267 ret = setjmp(env);
268 if (ret == 0)
269 expand_domain_search(&p);
270
271 if (ret != 1)
272 abort();
273
274 free(option->data);
275 }
276
277 void
multiple_domains_valid()278 multiple_domains_valid()
279 {
280 int ret;
281 struct packet p;
282 struct option_data *option;
283
284 char *data =
285 "\007example\003org\0\002cl\006foobar\003com\0\002fr\xc0\x10";
286
287 char *expected = "example.org. cl.foobar.com. fr.foobar.com.";
288
289 option = &p.options[DHO_DOMAIN_SEARCH];
290 option->len = 33;
291 option->data = malloc(option->len);
292 memcpy(option->data, data, option->len);
293
294 ret = setjmp(env);
295 if (ret == 0)
296 expand_domain_search(&p);
297
298 if (option->len != strlen(expected) ||
299 strcmp(option->data, expected) != 0)
300 abort();
301
302 free(option->data);
303 }
304
305 static
306 void
parse_date_helper(const char * string,time_t timestamp)307 parse_date_helper(const char *string, time_t timestamp)
308 {
309 int ret = 0;
310 FILE *file = NULL;
311 time_t ts;
312
313 file = fopen("/tmp/dhclient.test", "w");
314 if (!file)
315 abort();
316
317 ret = fwrite(string, strlen(string), 1, file);
318 if (ret <= 0)
319 abort();
320
321 fclose(file);
322
323 file = fopen("/tmp/dhclient.test", "r");
324 if (!file)
325 abort();
326
327 new_parse("test");
328 ts = parse_date(file);
329 if (ts != timestamp)
330 abort();
331
332 fclose(file);
333 }
334
335 void
parse_date_valid(void)336 parse_date_valid(void)
337 {
338 int ret;
339
340 ret = setjmp(env);
341 if (ret != 0)
342 abort();
343
344 parse_date_helper(" 2 2024/7/2 20:25:50;\n", 1719951950);
345 #ifndef __i386__
346 parse_date_helper(" 1 2091/7/2 20:25:50;\n", 3834246350);
347 #endif
348 }
349
350 int
main(int argc,char * argv[])351 main(int argc, char *argv[])
352 {
353
354 no_option_present();
355
356 one_domain_valid();
357 one_domain_truncated1();
358 one_domain_truncated2();
359
360 two_domains_valid();
361 two_domains_truncated1();
362 two_domains_truncated2();
363
364 two_domains_compressed();
365 two_domains_infloop();
366 two_domains_forwardptr();
367 two_domains_truncatedptr();
368
369 multiple_domains_valid();
370
371 parse_date_valid();
372
373 return (0);
374 }
375