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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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