Deleted Added
full compact
options.c (149399) options.c (228259)
1/* $OpenBSD: options.c,v 1.15 2004/12/26 03:17:07 deraadt Exp $ */
2
3/* DHCP options parsing and reassembly. */
4
5/*
6 * Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
7 * All rights reserved.
8 *

--- 27 unchanged lines hidden (view full) ---

36 * This software has been written for the Internet Software Consortium
37 * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
38 * Enterprises. To learn more about the Internet Software Consortium,
39 * see ``http://www.vix.com/isc''. To learn more about Vixie
40 * Enterprises, see ``http://www.vix.com''.
41 */
42
43#include <sys/cdefs.h>
1/* $OpenBSD: options.c,v 1.15 2004/12/26 03:17:07 deraadt Exp $ */
2
3/* DHCP options parsing and reassembly. */
4
5/*
6 * Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
7 * All rights reserved.
8 *

--- 27 unchanged lines hidden (view full) ---

36 * This software has been written for the Internet Software Consortium
37 * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
38 * Enterprises. To learn more about the Internet Software Consortium,
39 * see ``http://www.vix.com/isc''. To learn more about Vixie
40 * Enterprises, see ``http://www.vix.com''.
41 */
42
43#include <sys/cdefs.h>
44__FBSDID("$FreeBSD: head/sbin/dhclient/options.c 149399 2005-08-23 23:59:55Z brooks $");
44__FBSDID("$FreeBSD: head/sbin/dhclient/options.c 228259 2011-12-04 14:44:31Z dumbbell $");
45
46#include <ctype.h>
47
48#define DHCP_OPTION_DATA
49#include "dhcpd.h"
50
51int bad_options = 0;
52int bad_options_max = 5;
53
54void parse_options(struct packet *);
55void parse_option_buffer(struct packet *, unsigned char *, int);
56int store_options(unsigned char *, int, struct tree_cache **,
57 unsigned char *, int, int, int, int);
45
46#include <ctype.h>
47
48#define DHCP_OPTION_DATA
49#include "dhcpd.h"
50
51int bad_options = 0;
52int bad_options_max = 5;
53
54void parse_options(struct packet *);
55void parse_option_buffer(struct packet *, unsigned char *, int);
56int store_options(unsigned char *, int, struct tree_cache **,
57 unsigned char *, int, int, int, int);
58void expand_domain_search(struct packet *packet);
59int find_search_domain_name_len(struct option_data *option, int *offset);
60void expand_search_domain_name(struct option_data *option, int *offset,
61 unsigned char **domain_search);
58
59
60/*
61 * Parse all available options out of the specified packet.
62 */
63void
64parse_options(struct packet *packet)
65{

--- 23 unchanged lines hidden (view full) ---

89 parse_option_buffer(packet,
90 (unsigned char *)packet->raw->file,
91 sizeof(packet->raw->file));
92 if (packet->options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 2)
93 parse_option_buffer(packet,
94 (unsigned char *)packet->raw->sname,
95 sizeof(packet->raw->sname));
96 }
62
63
64/*
65 * Parse all available options out of the specified packet.
66 */
67void
68parse_options(struct packet *packet)
69{

--- 23 unchanged lines hidden (view full) ---

93 parse_option_buffer(packet,
94 (unsigned char *)packet->raw->file,
95 sizeof(packet->raw->file));
96 if (packet->options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 2)
97 parse_option_buffer(packet,
98 (unsigned char *)packet->raw->sname,
99 sizeof(packet->raw->sname));
100 }
101
102 /* Expand DHCP Domain Search option. */
103 if (packet->options_valid) {
104 expand_domain_search(packet);
105 }
97}
98
99/*
100 * Parse options out of the specified buffer, storing addresses of
101 * option values in packet->options and setting packet->options_valid if
102 * no errors are encountered.
103 */
104void

--- 84 unchanged lines hidden (view full) ---

189 packet->options[code].data = t;
190 }
191 s += len + 2;
192 }
193 packet->options_valid = 1;
194}
195
196/*
106}
107
108/*
109 * Parse options out of the specified buffer, storing addresses of
110 * option values in packet->options and setting packet->options_valid if
111 * no errors are encountered.
112 */
113void

--- 84 unchanged lines hidden (view full) ---

198 packet->options[code].data = t;
199 }
200 s += len + 2;
201 }
202 packet->options_valid = 1;
203}
204
205/*
206 * Expand DHCP Domain Search option. The value of this option is
207 * encoded like DNS' list of labels. See:
208 * RFC 3397
209 * RFC 1035
210 */
211void
212expand_domain_search(struct packet *packet)
213{
214 int offset, expanded_len;
215 struct option_data *option;
216 unsigned char *domain_search, *cursor;
217
218 if (packet->options[DHO_DOMAIN_SEARCH].data == NULL)
219 return;
220
221 option = &packet->options[DHO_DOMAIN_SEARCH];
222
223 /* Compute final expanded length. */
224 expanded_len = 0;
225 offset = 0;
226 while (offset < option->len) {
227 /* We add 1 for the space between domain names. */
228 expanded_len +=
229 find_search_domain_name_len(option, &offset) + 1;
230 }
231 if (expanded_len > 0)
232 /* Remove 1 for the superfluous trailing space. */
233 --expanded_len;
234
235 domain_search = malloc(expanded_len + 1);
236 if (domain_search == NULL)
237 error("Can't allocate storage for expanded domain-search\n");
238
239 offset = 0;
240 cursor = domain_search;
241 while (offset < option->len) {
242 expand_search_domain_name(option, &offset, &cursor);
243 cursor[0] = ' ';
244 cursor++;
245 }
246 domain_search[expanded_len] = '\0';
247
248 free(option->data);
249 option->len = expanded_len;
250 option->data = domain_search;
251}
252
253int
254find_search_domain_name_len(struct option_data *option, int *offset)
255{
256 int domain_name_len, i, label_len, pointer, pointed_len;
257
258 domain_name_len = 0;
259
260 i = *offset;
261 while (i < option->len) {
262 label_len = option->data[i];
263 if (label_len == 0) {
264 /*
265 * A zero-length label marks the end of this
266 * domain name.
267 */
268 *offset = i + 1;
269 return (domain_name_len);
270 } else if (label_len & 0xC0) {
271 /* This is a pointer to another list of labels. */
272 if (i + 1 >= option->len) {
273 /* The pointer is truncated. */
274 error("Truncated pointer in DHCP Domain "
275 "Search option.");
276 }
277
278 pointer = ((label_len & ~(0xC0)) << 8) +
279 option->data[i + 1];
280 if (pointer >= *offset) {
281 /*
282 * The pointer must indicates a prior
283 * occurance.
284 */
285 error("Invalid forward pointer in DHCP Domain "
286 "Search option compression.");
287 }
288
289 pointed_len = find_search_domain_name_len(option,
290 &pointer);
291 domain_name_len += pointed_len;
292
293 *offset = i + 2;
294 return (domain_name_len);
295 }
296
297 if (i + label_len >= option->len) {
298 error("Truncated label in DHCP Domain Search option.");
299 }
300
301 /*
302 * Update the domain name length with the length of the
303 * current label, plus a trailing dot ('.').
304 */
305 domain_name_len += label_len + 1;
306
307 /* Move cursor. */
308 i += label_len + 1;
309 }
310
311 error("Truncated DHCP Domain Search option.");
312
313 return (0);
314}
315
316void
317expand_search_domain_name(struct option_data *option, int *offset,
318 unsigned char **domain_search)
319{
320 int i, label_len, pointer;
321 unsigned char *cursor;
322
323 /*
324 * This is the same loop than the function above
325 * (find_search_domain_name_len). Therefore, we remove checks,
326 * they're already done. Here, we just make the copy.
327 */
328 i = *offset;
329 cursor = *domain_search;
330 while (i < option->len) {
331 label_len = option->data[i];
332 if (label_len == 0) {
333 /*
334 * A zero-length label marks the end of this
335 * domain name.
336 */
337 *offset = i + 1;
338 *domain_search = cursor;
339 return;
340 } else if (label_len & 0xC0) {
341 /* This is a pointer to another list of labels. */
342 pointer = ((label_len & ~(0xC0)) << 8) +
343 option->data[i + 1];
344
345 expand_search_domain_name(option, &pointer, &cursor);
346
347 *offset = i + 2;
348 *domain_search = cursor;
349 return;
350 }
351
352 /* Copy the label found. */
353 memcpy(cursor, option->data + i + 1, label_len);
354 cursor[label_len] = '.';
355
356 /* Move cursor. */
357 i += label_len + 1;
358 cursor += label_len + 1;
359 }
360}
361
362/*
197 * cons options into a big buffer, and then split them out into the
198 * three separate buffers if needed. This allows us to cons up a set of
199 * vendor options using the same routine.
200 */
201int
202cons_options(struct packet *inpacket, struct dhcp_packet *outpacket,
203 int mms, struct tree_cache **options,
204 int overload, /* Overload flags that may be set. */

--- 516 unchanged lines hidden ---
363 * cons options into a big buffer, and then split them out into the
364 * three separate buffers if needed. This allows us to cons up a set of
365 * vendor options using the same routine.
366 */
367int
368cons_options(struct packet *inpacket, struct dhcp_packet *outpacket,
369 int mms, struct tree_cache **options,
370 int overload, /* Overload flags that may be set. */

--- 516 unchanged lines hidden ---