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