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