29 #define DHCP_OPTION_DATA
36 static int pretty_text(
char **,
char *,
const unsigned char **,
37 const unsigned char *,
int);
38 static int pretty_domain(
char **,
char *,
const unsigned char **,
39 const unsigned char *);
41 unsigned char *
buffer,
unsigned length,
42 unsigned code,
int terminatep,
54 packet -> options_valid = 0;
61 &packet -> raw -> options [4],
62 (packet -> packet_length -
96 (
unsigned char *)packet -> raw ->
file,
97 sizeof packet -> raw ->
file,
104 (
unsigned char *)packet -> raw -> sname,
105 sizeof packet -> raw -> sname,
110 packet -> options_valid = 1;
119 const
unsigned char *
buffer;
123 unsigned len, offset;
126 struct buffer *bp = (
struct buffer *)0;
128 char *reason =
"general failure";
131 log_error (
"no memory for option buffer.");
134 memcpy (bp -> data, buffer, length);
137 (offset + universe->
tag_size) <= length &&
138 (code = universe->
get_tag(buffer + offset)) != universe->
end; ) {
147 reason =
"code tag at end of buffer - missing "
164 log_fatal(
"Improperly configured option space(%s): "
165 "may not have a nonzero length size "
166 "AND a NULL get_length function.",
175 option_code_hash_lookup(&option, universe->
code_hash, &code,
179 if (offset + len > length) {
182 reason =
"option length exceeds option buffer length";
184 log_error(
"parse_option_buffer: malformed option "
185 "%s.%s (code %u): %s.", universe->
name,
186 option ? option->
name :
"<unknown>",
200 (option->
format[0] ==
'e' || option->
format[0] ==
'E')) {
211 log_debug (
"Ignoring empty DHO_HOST_NAME option");
221 bp->
data + offset, len,
224 "save_option_buffer failed");
232 memset(&
new, 0,
sizeof new);
235 log_error(
"parse_option_buffer: No memory.");
240 memcpy(
new.buffer->data, op->
data.
data,
243 memcpy(
new.buffer->data + op->
data.
len,
244 bp->
data + offset, len);
246 new.data =
new.buffer->data;
255 while (op->
next != NULL)
259 log_error(
"parse_option_buffer: No memory.");
266 nop->data.buffer = NULL;
268 nop->data.data = bp->
data + offset;
294 s = strchr (eopt ->
format,
'E');
296 log_error (
"internal encapsulation format error 1.");
300 t = strchr (++s,
'.');
304 log_error (
"internal encapsulation format error 2.");
307 if (t == s && uname) {
318 s, (
unsigned)(t - s))) {
334 const unsigned char *
buffer,
352 i = (*universe ->
decode) (options, buffer, len, universe);
355 if (eopt ->
format [0] !=
'E')
362 const unsigned char *
buffer,
363 unsigned length,
struct universe *u)
365 struct buffer *bp = (
struct buffer *)0;
373 log_error (
"no memory for option buffer.");
376 memcpy (&bp ->
data [3], buffer + 1, length - 1);
405 if (!bp ->
data [0]) {
409 if (buffer [length - 1] == 0) {
417 for (i = 3; i < length && buffer [i] !=
'.'; i++);
428 if (length > 4 + i &&
430 &bp ->
data[6 + i], length - 4 - i,
436 &bp ->
data [5], length - 3,
442 unsigned total_len = 0;
443 unsigned first_len = 0;
449 while (s < &bp ->
data[0] + length + 2) {
452 log_info (
"fancy bits in fqdn option");
459 if (s + len > &bp ->
data [0] + length + 3) {
460 log_info (
"fqdn tag longer than buffer");
464 if (first_len == 0) {
470 total_len += len + 1;
481 first_len = total_len;
486 &bp ->
data[6], first_len,
489 if (total_len > 0 && first_len != total_len) {
491 &bp->
data[6 + first_len],
492 total_len - first_len,
498 &bp ->
data [6], total_len,
538 int overload_avail,
int terminate,
int bootpp,
541 #define PRIORITY_COUNT 300
544 unsigned char buffer[4096], agentopts[1024];
546 unsigned mb_size = 0, mb_max = 0;
547 unsigned option_size = 0, agent_size = 0;
553 int overload_used = 0;
554 int of1 = 0, of2 = 0;
556 memset(&ds, 0,
sizeof ds);
569 client_state, in_options,
570 cfg_options, scope, op,
MDL) != 0)) {
571 if (ds.
len >= sizeof (u_int16_t)) {
573 if(!mms || (i < mms))
605 if (inpacket != NULL &&
617 if (client_state == NULL) {
622 inpacket, lease, client_state,
623 in_options, cfg_options, scope,
624 priority_list, priority_len,
627 mb_size += agent_size;
636 if (mb_size > agent_size)
637 mb_max = mb_size - agent_size;
641 if (overload_avail & 1) {
646 if (overload_avail & 2) {
667 if (prl != NULL && prl->
len > 0) {
671 priority_list[priority_len++] =
680 priority_list[priority_len++] =
690 for (i = 0; i < prl->
len; i++) {
696 priority_list[priority_len++] = prl->
data[i];
708 priority_list[priority_len++] =
DHO_FQDN;
739 priority_list[priority_len++] =
DHO_FQDN;
754 for (pp = hash[i]; pp; pp = pp->cdr) {
760 priority_list[priority_len++] =
775 for (pp = hash[i]; pp; pp = pp->cdr) {
781 priority_list[priority_len++] =
796 priority_list[priority_len++] =
806 priority_list[priority_len++] =
815 option_size =
store_options(&overload_used, buffer, index, mb_max,
816 inpacket, lease, client_state,
817 in_options, cfg_options, scope,
818 priority_list, priority_len,
819 of1, of2, terminate, vuname);
822 if (option_size == 0)
826 index += option_size;
833 if (mb_size - agent_size - index < 3)
838 buffer[index++] = overload_used;
840 if (overload_used & 1)
843 if (overload_used & 2)
849 if (mb_size - index >= agent_size) {
850 memcpy(&buffer[index], agentopts, agent_size);
853 log_error(
"Unable to store relay agent information "
862 memcpy(outpacket->
options, buffer, index);
887 struct lease *dummy_lease,
893 void *void_vsio_state) {
898 memset(&ds, 0,
sizeof(ds));
900 NULL, opt_state, NULL,
906 }
else if (universe->
tag_size == 2) {
910 }
else if (universe->
tag_size == 4) {
929 log_debug(
"No space for option %d in VSIO space %s.",
934 log_error(
"Error evaluating option %d in VSIO space %s.",
957 add_option6_data(
char *buf,
int buflen,
int* bufpos, uint16_t
code,
959 if ((ds->
len + 4) > (buflen - *bufpos)) {
960 log_debug(
"No space for option %d", code);
962 unsigned char* tmp = (
unsigned char *)buf + *bufpos;
968 memcpy(tmp+4, ds->
data, ds->
len);
970 *bufpos += 4 + ds->
len;
1001 store_encap6 (
char *buf,
int buflen,
int* bufpos,
1003 struct option* encap_opt, uint16_t code) {
1009 char* s = (
char*)encap_opt->
format;
1011 if ((s == NULL) || (*s !=
'E') || (strlen(s) <= 2)) {
1015 t = strchr(++s,
'.');
1016 if ((t == NULL) || (t == s)) {
1020 memset(&ds, 0,
sizeof(ds));
1021 memset(&name, 0,
sizeof(name));
1022 name.data = (
unsigned char *)s;
1030 add_option6_data(buf, buflen, bufpos, code, &ds);
1045 struct packet *packet,
1046 const int *required_opts,
1055 int in_required_opts;
1056 int vsio_option_code;
1067 vsio_option_code = 0;
1071 vsio_option_code = o->
code;
1076 if (vsio_option_code == 0) {
1077 log_fatal(
"No VSIO option code found.");
1080 if (required_opts != NULL) {
1081 for (i=0; required_opts[i] != 0; i++) {
1082 if (required_opts[i] == vsio_option_code) {
1087 opt_state, required_opts[i]);
1091 memset(&ds, 0,
sizeof(ds));
1092 for (; oc != NULL ; oc = oc->
next) {
1097 add_option6_data(buf, buflen, &bufpos,
1098 (uint16_t)required_opts[i], &ds);
1111 oro_size = oro->
len / 2;
1113 for (i=0; i<oro_size; i++) {
1114 memcpy(&code, oro->
data+(i*2), 2);
1121 in_required_opts = 0;
1122 if (required_opts != NULL) {
1123 for (j=0; required_opts[j] != 0; j++) {
1124 if (required_opts[j] == code) {
1125 in_required_opts = 1;
1130 if (in_required_opts) {
1140 if (code == vsio_option_code) {
1148 memset(&ds, 0,
sizeof(ds));
1151 for (; oc != NULL ; oc = oc->
next) {
1153 NULL, opt_state, NULL,
1156 add_option6_data(buf, buflen, &bufpos,
1169 struct option *encap_opt = NULL;
1170 unsigned int code_int =
code;
1172 option_code_hash_lookup(&encap_opt,
1175 if (encap_opt != NULL) {
1176 store_encap6(buf, buflen, &bufpos, opt_state,
1177 packet, encap_opt, code);
1207 if (vs.
bufpos > bufpos+8) {
1208 tmp = (
unsigned char *)buf +
1232 unsigned char *
buffer,
unsigned index,
unsigned buflen,
1238 unsigned *priority_list,
int priority_len,
1239 unsigned first_cutoff,
int second_cutoff,
int terminate,
1242 int bufix = 0, six = 0, tix = 0;
1246 int bufend, sbufend;
1257 buffer = &buffer[index];
1260 first_cutoff -= index;
1262 second_cutoff -= index;
1265 bufend = sbufend = buflen;
1267 if (first_cutoff >= buflen)
1268 log_fatal(
"%s:%d:store_options: Invalid first cutoff.",
MDL);
1269 bufend = first_cutoff;
1271 if (second_cutoff) {
1272 if (second_cutoff >= buflen)
1273 log_fatal(
"%s:%d:store_options: Invalid second cutoff.",
1275 sbufend = second_cutoff;
1277 }
else if (second_cutoff) {
1278 if (second_cutoff >= buflen)
1279 log_fatal(
"%s:%d:store_options: Invalid second cutoff.",
MDL);
1280 bufend = second_cutoff;
1283 memset (&od, 0,
sizeof od);
1288 for (i = 0; i < priority_len; i++) {
1291 for (ix = i + 1; ix < priority_len + tto; ix++) {
1293 priority_list [ix - tto] =
1295 if (priority_list [i] == priority_list [ix]) {
1313 for (ix = i - 1 ; ix >= 0 ; ix--) {
1326 for (i = 0; i < priority_len; i++) {
1330 int optstart, soptstart, toptstart;
1332 int have_encapsulation = 0;
1336 memset (&encapsulation, 0,
sizeof encapsulation);
1337 have_encapsulation = 0;
1343 code = priority_list [i];
1347 if (code >= cfg_options -> site_code_min)
1348 u =
universes [cfg_options -> site_universe];
1357 option_code_hash_lookup(&option, u->
code_hash, &code, 0,
MDL);
1367 if ((option != NULL) &&
1368 (((oc == NULL) && (option->
format[0] ==
'E')) ||
1369 ((oc != NULL) && (option->
format[0] ==
'e')))) {
1374 s = strchr (option->
format,
'E');
1376 t = strchr (++s,
'.');
1378 memset (&name, 0,
sizeof name);
1383 if (vendor_cfg_option) {
1386 vendor_cfg_option -> code);
1394 }
else if (vuname) {
1395 name.
data = (
unsigned char *)s;
1396 name.
len = strlen (s);
1399 name.
data = (
unsigned char *)s;
1406 have_encapsulation =
1408 (&encapsulation, packet, lease, client_state,
1409 in_options, cfg_options, scope, &name));
1424 if (!oc && !have_encapsulation) {
1433 lease, client_state, in_options,
1434 cfg_options, scope, oc,
MDL);
1453 if (have_encapsulation) {
1454 length += encapsulation.
len;
1464 struct buffer *bp = (
struct buffer *)0;
1509 unsigned incr = length;
1511 unsigned char *base;
1515 ((!six && !tix && (i == priority_len - 1) &&
1516 (bufix + 2 + length < bufend)) ||
1517 (bufix + 5 + length < bufend))) {
1521 }
else if (!splitup && first_cutoff &&
1522 (first_cutoff + six + 3 + length < sbufend)) {
1523 base = &buffer[first_cutoff];
1526 }
else if (!splitup && second_cutoff &&
1527 (second_cutoff + tix + 3 + length < buflen)) {
1528 base = &buffer[second_cutoff];
1535 if (bufix + 6 < bufend) {
1536 incr = bufend - bufix - 5;
1540 }
else if (first_cutoff &&
1541 (first_cutoff + six + 4 < sbufend)) {
1542 incr = sbufend - (first_cutoff + six) - 3;
1543 base = &buffer[first_cutoff];
1546 }
else if (second_cutoff &&
1547 (second_cutoff + tix + 4 < buflen)) {
1548 incr = buflen - (second_cutoff + tix) - 3;
1549 base = &buffer[second_cutoff];
1567 base [*pix + 1] = (
unsigned char)incr;
1568 if (tto && incr == length) {
1570 memcpy (base + *pix + 2,
1571 od.
data + ix, (
unsigned)(incr - 1));
1572 base [*pix + 2 + incr - 1] = 0;
1574 memcpy (base + *pix + 2,
1575 od.
data + ix, (
unsigned)incr);
1588 if (first_cutoff && six) {
1589 if ((first_cutoff + six + 1) < sbufend)
1590 memset (&buffer[first_cutoff + six + 1],
DHO_PAD,
1591 sbufend - (first_cutoff + six + 1));
1592 else if (first_cutoff + six >= sbufend)
1593 log_fatal(
"Second buffer overflow in overloaded options.");
1595 buffer[first_cutoff + six] =
DHO_END;
1600 if (second_cutoff && tix) {
1601 if (second_cutoff + tix + 1 < buflen) {
1602 memset (&buffer[second_cutoff + tix + 1],
DHO_PAD,
1603 buflen - (second_cutoff + tix + 1));
1604 }
else if (second_cutoff + tix >= buflen)
1605 log_fatal(
"Third buffer overflow in overloaded options.");
1607 buffer[second_cutoff + tix] =
DHO_END;
1612 if ((six || tix) && (bufix + 3 > bufend))
1613 log_fatal(
"Not enough space for option overload option.");
1629 while (*p !=
'\0') {
1653 log_error(
"format_has_text(%s): 'c' atoms are illegal "
1654 "except after 'D' atoms.", format);
1666 while ((*p !=
'\0') && (*p++ !=
'.'))
1689 const char *
p, *name;
1695 while (*p !=
'\0') {
1721 log_fatal(
"Corrupt format: %s", format);
1724 if (espace == NULL) {
1725 log_error(
"Unknown enumeration: %s", format);
1730 min_len += espace->
width;
1731 last_size = espace->
width;
1766 log_error(
"format_min_length(%s): 'c' atom is illegal "
1767 "except after 'D' atom.", format);
1772 log_error(
"format_min_length(%s): No safe value "
1773 "for unknown format symbols.", format);
1784 #define MAX_OUTPUT_SIZE 32*1024
1787 const
unsigned char *data;
1802 char fmtbuf[32] =
"";
1806 const unsigned char *dp = data;
1809 isc_boolean_t a_array = ISC_FALSE;
1811 unsigned int octets = 0;
1818 memset (enumbuf, 0,
sizeof enumbuf);
1820 if (option->format[0] !=
'R') {
1822 for (l = i = 0; option -> format [i]; i++, l++) {
1823 if (l >=
sizeof(fmtbuf) - 1)
1824 log_fatal(
"Bounds failure on internal buffer at "
1828 log_error (
"%s: Extra codes in format string: %s",
1830 &(option -> format [i]));
1834 fmtbuf [l] = option -> format [i];
1835 switch (option -> format [i]) {
1846 while (option -> format [i] &&
1847 option -> format [i] !=
'.')
1851 for (k = 0; k < len; k++) {
1852 if (!isascii (data [k]) ||
1853 !isprint (data [k]))
1859 if (k == len || (k + 1 == len && data [k] == 0)) {
1874 log_error(
"'c' atom not following D atom in format "
1875 "string: %s", option->format);
1883 if (option->format[i+1] ==
'c')
1897 while (option -> format [i] &&
1898 option -> format [i] !=
'.')
1903 if (enumbuf[l] == NULL) {
1907 hunksize += enumbuf[l]->
width;
1908 hunkinc = enumbuf[l]->
width;
1941 log_error (
"%s: garbage in format string: %s",
1943 &(option -> format [i]));
1949 if (hunksize - opthunk > len) {
1950 log_error (
"%s: expecting at least %d bytes; got %d",
1956 if (numhunk == -1 && hunksize < len)
1963 if (a_array == ISC_TRUE) {
1975 log_error (
"%s: invalid 'a' format: %s",
1976 option->name, option->format);
1980 numhunk = ((len - hunksize) / hunkinc) + 1;
1981 len_used = hunksize + ((numhunk - 1) * hunkinc);
1990 if (hunksize == 0) {
1991 log_error (
"%s: invalid 'A' format: %s",
1992 option->name, option->format);
1996 numhunk = len / hunksize;
1997 len_used = numhunk * hunksize;
2001 if (len_used < len) {
2002 log_error (
"%s: %d extra bytes at end of array\n",
2025 fmtbuf[0]=
'R'; fmtbuf[1]=
'I'; fmtbuf[2]=0;
2026 for (i =0; i < len; i = i + octets + 5) {
2028 log_error (
"wrong subnet mask width in destination descriptor");
2032 octets = ((data[i]+7) / 8);
2035 log_error (
"classless static routes option has wrong size or "
2036 "there's some garbage in format");
2041 for (i = 0; i < numhunk; i++) {
2042 if ((a_array == ISC_TRUE) && (i != 0) && (numelem > 0)) {
2059 for (; j < numelem; j++) {
2060 switch (fmtbuf [j]) {
2063 k = pretty_text(&op, endbuf - 1, &dp,
2064 data + len, emit_quotes);
2072 for( ; dp < (data + len) ; dp += k) {
2074 const unsigned char *nbp, *nend;
2076 nend = &nbuff[
sizeof(nbuff)];
2086 if (op + 2 > endbuf)
2115 pretty_domain(&op, endbuf-1,
2155 switch (enumbuf[j]->
width) {
2171 return "<double impossible condition>";
2175 if (!enumbuf [j] ->
values [i].name)
2177 if (enumbuf [j] ->
values [i].value ==
2182 dp += enumbuf[j]->
width;
2186 sprintf(op,
"%lu", tval);
2191 memcpy(iaddr.
iabuf, dp, 4);
2198 iaddr.
len = (((dp[0]+7)/8)+1);
2200 log_error (
"wrong subnet mask width in destination descriptor");
2204 memcpy(iaddr.
iabuf, dp, iaddr.
len);
2211 memcpy(iaddr.
iabuf, dp, 16);
2216 sprintf (op,
"%ld", (
long)
getLong (dp));
2222 sprintf (op,
"%s",
"infinite");
2224 sprintf(op,
"%lu", tval);
2232 sprintf (op,
"%d", (
int)
getShort (dp));
2236 sprintf(op,
"%u", (
unsigned)
getUShort(dp));
2240 sprintf (op,
"%d", *(
const char *)dp++);
2243 sprintf (op,
"%d", *dp++);
2247 sprintf (op,
"%x", *dp++);
2250 strcpy (op, *dp++ ?
"true" :
"false");
2267 " maximum size %d", MAX_OUTPUT_SIZE);
2271 if (dp == data + len)
2273 if (j + 1 < numelem && comma !=
':')
2276 if (i + 1 < numhunk) {
2279 if (dp == data + len)
2286 in_options, cfg_options, options, scope, code,
file,
line)
2289 struct packet *packet;
2302 if (!universe -> lookup_func)
2304 oc = ((*universe -> lookup_func) (universe, options, code));
2308 in_options, cfg_options, scope, oc,
2321 in_options, cfg_options, options, scope, code,
file,
line)
2324 struct packet *packet;
2340 if ((options == NULL) || (universe->
lookup_func == NULL))
2344 oc = ((*universe->
lookup_func)(universe, options, code));
2349 memset(&d1, 0,
sizeof(d1));
2351 in_options, cfg_options, scope, oc,
2357 *result = d1.
data[0];
2369 enum statement_op op;
2376 case eval_statement:
2377 case break_statement:
2379 log_error (
"bogus statement type in set_option.");
2382 case default_option_statement:
2384 option -> option -> code);
2390 case supersede_option_statement:
2391 case send_option_statement:
2396 case append_option_statement:
2397 case prepend_option_statement:
2399 option -> option -> code);
2407 log_error (
"Can't allocate const expression.");
2419 if (op == append_option_statement) {
2440 switch (((memcmp(option->
option->
format,
"Dc", 2) == 0) +
2446 log_error (
"Both options must be Dc format");
2472 if (universe -> lookup_func)
2473 return (*universe -> lookup_func) (
universe, options,
code);
2475 log_error (
"can't look up options in %s space.",
2491 !(options ->
universes [universe -> index]))
2494 hash = options ->
universes [universe -> index];
2497 for (bptr = hash [hashix]; bptr; bptr = bptr -> cdr) {
2508 struct buffer *bp,
unsigned char *
buffer,
unsigned length,
2509 unsigned code,
int terminatep)
2514 status = prepare_option_buffer(universe, bp, buffer, length, code,
2532 struct buffer *bp,
unsigned char *
buffer,
unsigned length,
2533 unsigned code,
int terminatep)
2538 status = prepare_option_buffer(universe, bp, buffer, length, code,
2556 unsigned char *
buffer,
unsigned length,
unsigned code,
2559 struct buffer *lbp = NULL;
2575 if (code > 0xffffffff)
2580 log_fatal(
"Inconsistent universe tag size at %s:%d.",
MDL);
2583 option_code_hash_lookup(&option, universe->
code_hash, &code, 0,
MDL);
2593 char nbuf[
sizeof(
"unknown-4294967295")];
2595 sprintf(nbuf,
"unknown-%u", code);
2611 log_error(
"No memory for option code %s.%s.",
2626 log_error (
"no memory for option buffer.");
2631 memcpy (lbp ->
data, buffer, length + terminatep);
2633 buffer = &bp ->
data [0];
2641 op ->
data.data = buffer;
2642 op ->
data.len = length;
2650 buffer [length] = 0;
2651 op ->
data.terminated = 1;
2653 op ->
data.terminated = 0;
2663 while ((op->
data.
len > min_len) &&
2681 struct packet *dummy_packet,
2682 struct lease *dummy_lease,
2687 struct universe *dummy_universe,
2688 void *void_accumulator) {
2689 int *accumulator = (
int *)void_accumulator;
2696 struct packet *dummy_packet,
2697 struct lease *dummy_lease,
2702 struct universe *dummy_universe,
2746 memset(server_oro, 0,
sizeof(*server_oro));
2748 log_fatal(
"no memory to build server ORO");
2756 server_oro->
len = 0;
2769 server_oro->
len += 2;
2784 (*universe->
save_func)(universe, options, oc, ISC_FALSE);
2786 log_error(
"can't store options in %s space.", universe->
name);
2795 (*universe->
save_func)(universe, options, oc, ISC_TRUE);
2797 log_error(
"can't store options in %s space.", universe->
name);
2820 universe -> name, oc -> option -> name);
2824 options ->
universes [universe -> index] = (
void *)hash;
2827 for (bptr = hash [hashix]; bptr; bptr = bptr -> cdr) {
2829 (bptr -> car)) -> option -> code ==
2830 oc -> option ->
code)
2845 ocloc = &(*ocloc)->
next;
2846 }
while (*ocloc != NULL);
2859 log_error (
"No memory for option_cache reference.");
2862 bptr -> cdr = hash [hashix];
2865 hash [hashix] = bptr;
2869 struct universe *universe;
2873 if (universe -> delete_func)
2874 (*universe -> delete_func) (universe, options, code);
2876 log_error (
"can't delete options from %s space.",
2881 struct universe *universe;
2895 for (bptr = hash [hashix]; bptr; bptr = bptr -> cdr) {
2896 if (((
struct option_cache *)(bptr -> car)) -> option -> code
2904 prev -> cdr = bptr -> cdr;
2906 hash [hashix] = bptr -> cdr;
2920 if (!ptr || !*ptr) {
2921 log_error (
"Null pointer in option_cache_dereference: %s(%d)",
2923 #if defined (POINTER_DEBUG)
2945 free_option_caches = *ptr;
2948 if ((*ptr) ->
refcnt < 0) {
2949 log_error (
"%s(%d): negative refcnt!", file, line);
2950 #if defined (DEBUG_RC_HISTORY)
2951 dump_rc_history (*ptr);
2953 #if defined (POINTER_DEBUG)
2966 struct universe *universe;
2983 for (cp = heads [i]; cp; cp =
next) {
2992 dfree (heads, file, line);
2993 state ->
universes [universe -> index] = (
void *)0;
3008 if (src->
len == 0 && option->
format[0] !=
'Z')
3011 memset(&tmp, 0,
sizeof(tmp));
3060 struct universe *subu=NULL;
3064 memset(&tmp, 0,
sizeof(tmp));
3067 in_options, cfg_options, scope, oc,
MDL)) {
3081 end = strchr(++start,
'.');
3086 if (end == NULL || start == end)
3090 start, end - start,
MDL);
3094 "refers to unknown "
3095 "option space '%.*s'.",
3097 (
int)(end - start), start);
3108 client_state, in_options,
3109 cfg_options, scope, subu);
3112 }
while (ISC_FALSE);
3124 in_options, cfg_options, scope, name)
3126 struct packet *packet;
3134 struct universe *u = NULL;
3140 log_error(
"option_space_encapsulate: option space '%.*s' does "
3141 "not exist, but is configured.",
3147 if (u->
encapsulate(result, packet, lease, client_state,
3148 in_options, cfg_options, scope, u))
3151 log_error(
"encapsulation requested for '%s' with no support.",
3173 search_subencapsulation(
struct data_string *result,
struct packet *packet,
3178 struct universe *universe)
3181 struct universe *subu;
3184 memset(&sub, 0,
sizeof(sub));
3197 subu->
encapsulate(&sub, packet, lease, client_state,
3198 in_options, cfg_options,
3212 in_options, cfg_options, scope, universe)
3214 struct packet *packet;
3215 struct lease *lease;
3216 struct client_state *client_state;
3220 struct universe *universe;
3239 for (p = hash [i];
p; p = p -> cdr) {
3241 client_state, in_options, cfg_options,
3247 if (search_subencapsulation(result, packet, lease, client_state,
3248 in_options, cfg_options, scope, universe))
3255 in_options, cfg_options, scope, universe)
3257 struct packet *packet;
3258 struct lease *lease;
3259 struct client_state *client_state;
3263 struct universe *universe;
3279 for (ocp = head ->
first; ocp; ocp = ocp -> cdr) {
3281 lease, client_state, in_options,
3292 static unsigned char nni [] = { 1, 0 };
3294 memset (&ds, 0,
sizeof ds);
3299 if (!option_code_hash_lookup(&no_nwip->
option,
3302 log_fatal(
"Nwip option hash does not contain "
3307 client_state, in_options,
3308 cfg_options, scope, no_nwip))
3312 memset (&ds, 0,
sizeof ds);
3321 ds.
buffer -> data [0] = 2;
3322 ds.
buffer -> data [1] = 0;
3323 memcpy (&ds.
buffer -> data [2], result -> data, result -> len);
3339 fqdn_encode(
unsigned char *dst,
int dstlen,
const unsigned char *src,
3343 int i, j, len, outlen=0;
3346 for (i = 0, j = 0 ; i < srclen ; i = j) {
3347 while ((j < srclen) && (src[j] !=
'.') && (src[j] !=
'\0'))
3351 if ((outlen + 1 + len) > dstlen)
3361 memcpy(out, src + i, len);
3369 if ((outlen + 1) > dstlen)
3380 in_options, cfg_options, scope, universe)
3382 struct packet *packet;
3383 struct lease *lease;
3384 struct client_state *client_state;
3388 struct universe *universe;
3391 struct data_string results [FQDN_SUBOPTION_COUNT + 1];
3395 struct buffer *bp = (
struct buffer *)0;
3407 memset (results, 0,
sizeof results);
3408 for (ocp = head ->
first; ocp; ocp = ocp -> cdr) {
3410 if (oc -> option -> code > FQDN_SUBOPTION_COUNT)
3414 packet, lease, client_state,
3415 in_options, cfg_options, scope,
3427 log_error (
"no memory for option buffer.");
3435 memset (&bp ->
data [0], 0, len);
3449 bp -> data [0] |= 2;
3452 bp -> data [0] |= 1;
3462 i = fqdn_encode(&bp->
data[3], len - 3,
3464 results[FQDN_FQDN].
len);
3472 result->terminated = 0;
3476 memcpy (&bp -> data [3], results [
FQDN_FQDN].data,
3479 result -> terminated = 0;
3484 if (results [i].len)
3533 struct client_state *client_state,
3537 struct universe *u,
void *stuff,
3541 struct client_state *,
3545 struct universe *,
void *))
3555 struct packet *packet,
struct lease *lease,
3556 struct client_state *client_state,
3560 struct universe *universe)
3565 unsigned char *
data;
3566 int i, len, rval = 0, count;
3567 struct data_string results[FQDN_SUBOPTION_COUNT + 1];
3576 memset(results, 0,
sizeof(results));
3577 for (ocp = head->
first ; ocp != NULL ; ocp = ocp->
cdr) {
3583 lease, client_state, in_options,
3584 cfg_options, scope, oc,
MDL);
3594 log_error(
"No memory for virtual option buffer.");
3627 count = fqdn_encode(data + 1, len - 1,
3636 result->
len += count;
3655 const unsigned char *buffer,
unsigned length,
3658 struct buffer *bp = NULL;
3659 unsigned char *first_dot;
3660 int len, hlen, dlen;
3675 unsigned bp_size = 3 + (length * 4);
3678 log_error(
"No memory for dhcp6.fqdn option buffer.");
3710 log_error(
"Unable to convert dhcp6.fqdn domain name to "
3717 unsigned char *fqdn_start = bp->
data + 3;
3723 first_dot = (
unsigned char *)strchr((
char *)fqdn_start,
'.');
3725 if (first_dot != NULL) {
3726 hlen = first_dot - fqdn_start;
3754 struct client_state *client_state,
3758 struct universe *u,
void *stuff,
3761 struct lease *,
struct client_state *,
3765 struct universe *,
void *))
3768 (*u ->
foreach) (packet, lease, client_state, in_options,
3769 cfg_options, scope, u, stuff, func);
3773 struct client_state *client_state,
3777 struct universe *u,
void *stuff,
3780 struct lease *,
struct client_state *,
3784 struct universe *,
void *),
3790 if (universe ->
foreach)
3791 (*universe ->
foreach) (packet, lease, client_state,
3792 in_options, cfg_options,
3793 scope, universe, stuff, func);
3797 struct client_state *client_state,
3801 struct universe *u,
void *stuff,
3805 struct client_state *,
3809 struct universe *,
void *))
3815 if (cfg_options -> universe_count <= u -> index)
3818 hash = cfg_options ->
universes [u -> index];
3824 for (p = hash [i];
p; p = p -> cdr) {
3826 (*func) (
oc, packet, lease, client_state,
3827 in_options, cfg_options, scope, u, stuff);
3843 options ->
universes [universe -> index]);
3847 [universe -> index]),
MDL))
3850 options ->
universes [universe -> index]);
3854 for (tail = &head ->
first; *tail; tail = &((*tail) -> cdr)) {
3860 ocloc = &(*ocloc)->
next;
3861 }
while (*ocloc != NULL);
3870 *tail =
cons (0, 0);
3873 (&(*tail) -> car), oc,
MDL);
3878 in_options, cfg_options, scope, universe)
3880 struct packet *packet;
3881 struct lease *lease;
3882 struct client_state *client_state;
3886 struct universe *universe;
3895 cfg_options ->
universes [universe -> index]);
3899 for (oc = head ->
first;
oc; oc = oc -> cdr) {
3901 lease, client_state, in_options, cfg_options,
3906 if (search_subencapsulation(result, packet, lease, client_state,
3907 in_options, cfg_options, scope, universe))
3914 struct universe *universe;
3924 options ->
universes [universe -> index]);
3928 for (tail = &head ->
first; *tail; tail = &((*tail) -> cdr)) {
3930 ((
struct option_cache *)(*tail) -> car) -> option -> code)
3932 tmp = (*tail) -> cdr;
3934 (&(*tail) -> car),
MDL);
3943 struct universe *universe;
3953 options ->
universes [universe -> index]);
3957 for (oc = head ->
first;
oc; oc = oc -> cdr) {
3968 struct universe *universe;
3979 struct client_state *client_state,
3983 struct universe *u,
void *stuff,
3987 struct client_state *,
3991 struct universe *,
void *))
4002 for (car = head ->
first; car; car = car -> cdr) {
4004 packet, lease, client_state,
4005 in_options, cfg_options, scope, u, stuff);
4009 void do_packet (interface, packet, len, from_port, from, hfrom)
4013 unsigned int from_port;
4018 struct packet *decoded_packet;
4019 #if defined (DEBUG_MEMORY_LEAKAGE)
4020 unsigned long previous_outstanding = dmalloc_outstanding;
4023 #if defined (TRACING)
4027 decoded_packet = NULL;
4029 log_error(
"do_packet: no memory for incoming packet!");
4032 decoded_packet->
raw = packet;
4036 interface_reference(&decoded_packet->
interface, interface,
MDL);
4037 decoded_packet->
haddr = hfrom;
4041 log_info(
"Discarding packet with bogus hlen.");
4064 memset(&dp, 0,
sizeof dp);
4066 decoded_packet->
options, NULL,
4078 dhcp(decoded_packet);
4080 bootp(decoded_packet);
4086 #if defined (DEBUG_MEMORY_LEAKAGE)
4087 log_info(
"generation %ld: %ld new, %ld outstanding, %ld long-term",
4089 dmalloc_outstanding - previous_outstanding,
4090 dmalloc_outstanding, dmalloc_longterm);
4091 dmalloc_dump_outstanding();
4093 #if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY)
4122 int len,
int from_port,
const struct iaddr *from,
4123 isc_boolean_t was_unicast) {
4124 unsigned char msg_type;
4130 struct packet *decoded_packet;
4131 #if defined (DEBUG_MEMORY_LEAKAGE)
4132 unsigned long previous_outstanding = dmalloc_outstanding;
4137 "short packet from %s port %d, len %d, dropped",
4138 piaddr(*from), from_port, len);
4142 decoded_packet = NULL;
4144 log_error(
"do_packet6: no memory for incoming packet.");
4149 log_error(
"do_packet6: no memory for options.");
4165 interface_reference(&decoded_packet->
interface, interface,
MDL);
4167 decoded_packet->
unicast = was_unicast;
4169 msg_type = packet[0];
4184 relay->
options, len - relaylen,
4237 #if defined (DEBUG_MEMORY_LEAKAGE)
4238 log_info(
"generation %ld: %ld new, %ld outstanding, %ld long-term",
4240 dmalloc_outstanding - previous_outstanding,
4241 dmalloc_outstanding, dmalloc_longterm);
4242 dmalloc_dump_outstanding();
4244 #if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY)
4252 const unsigned char *send)
4259 if (dst == NULL || dend == NULL || src == NULL || send == NULL ||
4260 *dst == NULL || *src == NULL || (*dst >= dend) || (*src > send) ||
4261 ((send - *src) > (dend - *dst)))
4264 for ( ; *src < send ; (*src)++) {
4265 if (!isascii (**src) || !isprint (**src)) {
4267 if ((*src + 1) != send || **src !=
'\0') {
4268 if (*dst + 4 > dend)
4271 sprintf(*dst,
"\\%03o",
4276 }
else if (**src ==
'"' || **src ==
'\'' || **src ==
'$' ||
4277 **src ==
'`' || **src ==
'\\' || **src ==
'|' ||
4279 if (*dst + 2 > dend)
4288 if (*dst + 1 > dend)
4301 pretty_text(
char **dst,
char *dend,
const unsigned char **src,
4302 const unsigned char *send,
int emit_quotes)
4306 if (dst == NULL || dend == NULL || src == NULL || send == NULL ||
4307 *dst == NULL || *src == NULL ||
4308 ((*dst + (emit_quotes ? 2 : 0)) > dend) || (*src > send))
4317 count =
pretty_escape(dst, dend - (emit_quotes ? 1 : 0), src, send);
4322 if (emit_quotes && (*dst < dend)) {
4334 pretty_domain(
char **dst,
char *dend,
const unsigned char **src,
4335 const unsigned char *send)
4337 const unsigned char *tend;
4341 if (dst == NULL || dend == NULL || src == NULL || send == NULL ||
4342 *dst == NULL || *src == NULL ||
4343 ((*dst + 2) > dend) || (*src >= send))
4362 tend = (*src) + tsiz;
4374 if ((status == -1) || ((*dst + 2) > dend))
4379 count += status + 1;
4395 unsigned int option_num,
4397 unsigned int data_len)
4407 &option_num, 0,
MDL)) {
4408 log_error(
"Attempting to add unknown option %d.", option_num);
4414 log_error(
"No memory for option cache adding %s (option %d).",
4415 option->
name, option_num);
4425 log_error(
"No memory for constant data adding %s (option %d).",
4426 option->
name, option_num);
4454 log_debug(
"Dropped DHCPv4 packet with zero-length client-id");
4457 }
else if (oc->
data.
len == 1) {
4464 log_debug(
"Accepted DHCPv4 packet with one-character client-id - "
4465 "a future version of ISC DHCP will reject this");
4473 log_debug(
"Received DHCPv4 packet without client-id"
4474 " option and empty hlen field.");
4514 struct packet *packet;
4515 struct lease *lease;
4516 struct client_state *client_state;
4523 struct option *option = NULL;
4527 if ((packet == NULL) || (in_options == NULL) || (out_options == NULL))
4531 if (vendor_cfg_option == NULL)
4536 out_options, vendor_cfg_option->
code);
4540 memset(&name, 0,
sizeof(name));
4542 in_options, out_options, scope, oc,
MDL);
4552 if ((oc == NULL) || (oc->
data.
len == 0)) {
4568 (
const char *)name.
data);
struct option_cache * lookup_hashed_option(struct universe *universe, struct option_state *options, unsigned code)
void do_packet6(struct interface_info *, const char *, int, int, const struct iaddr *, isc_boolean_t)
int(* decode)(struct option_state *, const unsigned char *, unsigned, struct universe *)
#define rc_register(file, line, reference, addr, refcnt, d, f)
#define DHCP_FIXED_NON_UDP
int parse_encapsulated_suboptions(struct option_state *options, struct option *eopt, const unsigned char *buffer, unsigned len, struct universe *eu, const char *uname)
unsigned char peer_address[16]
int(* encapsulate)(struct data_string *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct universe *)
int fqdn_option_space_encapsulate(struct data_string *result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct universe *universe)
void set_option(struct universe *universe, struct option_state *options, struct option_cache *option, enum statement_op op)
#define DHO_DHCP_AGENT_OPTIONS
char sname[DHCP_SNAME_LEN]
struct binding_scope * global_scope
void save_linked_option(struct universe *universe, struct option_state *options, struct option_cache *oc, isc_boolean_t appendp)
struct option_cache * free_option_caches
struct universe * universe
void save_option(struct universe *universe, struct option_state *options, struct option_cache *oc)
const char * piaddr(const struct iaddr addr)
int MRns_name_ntop(const u_char *src, char *dst, size_t dstsiz)
#define FQDN_NO_CLIENT_UPDATE
#define DHCP_MIN_OPTION_LEN
unsigned char dhcpv6_transaction_id[3]
int append_option(struct data_string *dst, struct universe *universe, struct option *option, struct data_string *src)
unsigned char options[FLEXIBLE_ARRAY_MEMBER]
void delete_linked_option(struct universe *universe, struct option_state *options, int code)
int hashed_option_space_encapsulate(struct data_string *result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct universe *universe)
int option_cache_dereference(struct option_cache **ptr, const char *file, int line)
int expression_allocate(struct expression **cptr, const char *file, int line)
int store_option(struct data_string *result, struct universe *universe, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct option_cache *oc)
struct option_cache *(* lookup_func)(struct universe *, struct option_state *, unsigned)
struct enumeration * find_enumeration(const char *name, int length)
int int int log_debug(const char *,...) __attribute__((__format__(__printf__
void parse_vendor_option(struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *out_options, struct binding_scope **scope)
Parse a vendor option (option 43)
pair new_pair(char *file, int line) const
#define DHO_DHCP_LEASE_TIME
int option_reference(struct option **dest, struct option *src, const char *file, int line)
struct universe dhcp_universe
int fqdn_universe_decode(struct option_state *options, const unsigned char *buffer, unsigned length, struct universe *u)
struct universe * find_option_universe(struct option *eopt, const char *uname)
void data_string_forget(struct data_string *data, const char *file, int line)
struct option_cache * next
void bootp(struct packet *packet)
const char * pretty_print_option(struct option *option, const unsigned char *data, unsigned len, int emit_commas, int emit_quotes)
#define FQDN_SUBOPTION_COUNT
int option_cache_reference(struct option_cache **ptr, struct option_cache *src, const char *file, int line)
void also_save_option(struct universe *universe, struct option_state *options, struct option_cache *oc)
void delete_option(struct universe *universe, struct option_state *options, int code)
int log_error(const char *,...) __attribute__((__format__(__printf__
u_int32_t(* get_length)(const unsigned char *)
#define DHO_DHCP_REBINDING_TIME
#define DHCPV6_DHCPV4_QUERY
#define DHO_DOMAIN_NAME_SERVERS
int option_space_encapsulate(struct data_string *result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct data_string *name)
int fqdn6_universe_decode(struct option_state *options, const unsigned char *buffer, unsigned length, struct universe *u)
const char * pdestdesc(const struct iaddr addr)
log_fatal("no memory for uname information.")
struct expression * expression
void build_server_oro(struct data_string *server_oro, struct option_state *options, const char *file, int line)
#define DHO_ASSOCIATED_IP
struct option_state * options
unsigned char dhcpv6_hop_count
void do_packet(struct interface_info *interface, struct dhcp_packet *packet, unsigned len, unsigned int from_port, struct iaddr from, struct hardware *hfrom)
unsigned char link_address[16]
void expression_dereference(struct expression **eptr, const char *file, int line)
unsigned char dhcpv6_msg_type
void data_string_truncate(struct data_string *dp, int len)
#define DHO_DHCP_SERVER_IDENTIFIER
struct enumeration * espace
#define DHCPV6_RELAY_REPL
int parse_option_buffer(struct option_state *options, const unsigned char *buffer, unsigned length, struct universe *universe)
int buffer_reference(struct buffer **ptr, struct buffer *bp, const char *file, int line)
void(* store_length)(unsigned char *, u_int32_t)
int option_cache_allocate(struct option_cache **cptr, const char *file, int line)
struct universe vsio_universe
universe_hash_t * universe_hash
int linked_option_state_dereference(struct universe *universe, struct option_state *state, const char *file, int line)
int option_state_allocate(struct option_state **ptr, const char *file, int line)
int evaluate_option_cache(struct data_string *result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct option_cache *oc, const char *file, int line)
struct option_cache * lookup_fqdn6_option(struct universe *universe, struct option_state *options, unsigned code)
#define DHCPV6_DHCPV4_RESPONSE
int32_t getShort(const unsigned char *)
int option_chain_head_dereference(struct option_chain_head **ptr, const char *file, int line)
int32_t getLong(const unsigned char *)
#define DHCP_MAX_OPTION_LEN
void delete_hashed_option(struct universe *universe, struct option_state *options, int code)
void linked_option_space_foreach(struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct universe *u, void *stuff, void(*func)(struct option_cache *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct universe *, void *))
int fqdn6_option_space_encapsulate(struct data_string *result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct universe *universe)
int buffer_allocate(struct buffer **ptr, unsigned len, const char *file, int line)
char * default_option_format
struct interface_info * interface
struct enumeration_value * values
void putULong(unsigned char *, u_int32_t)
if(parse_ip_addr(cfile,&match->addr))
void delete_fqdn6_option(struct universe *universe, struct option_state *options, int code)
void save_hashed_option(struct universe *universe, struct option_state *options, struct option_cache *oc, isc_boolean_t appendp)
struct universe * universe
int linked_option_space_encapsulate(struct data_string *result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct universe *universe)
int make_concat(struct expression **expr, struct expression *left, struct expression *right)
#define DHCPV6_RELAY_FORW
int pretty_escape(char **dst, char *dend, const unsigned char **src, const unsigned char *send)
int cons_options(struct packet *inpacket, struct dhcp_packet *outpacket, struct lease *lease, struct client_state *client_state, int mms, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, int overload_avail, int terminate, int bootpp, struct data_string *prl, const char *vuname)
int save_option_buffer(struct universe *universe, struct option_state *options, struct buffer *bp, unsigned char *buffer, unsigned length, unsigned code, int terminatep)
u_int32_t getUShort(const unsigned char *)
int hashed_option_state_dereference(struct universe *universe, struct option_state *state, const char *file, int line)
struct option * new_option(char *name, const char *file, int line) const
int add_option(struct option_state *options, unsigned int option_num, void *data, unsigned int data_len)
#define DHO_CLASSLESS_STATIC_ROUTES
int store_options(int *ocount, unsigned char *buffer, unsigned index, unsigned buflen, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, unsigned *priority_list, int priority_len, unsigned first_cutoff, int second_cutoff, int terminate, const char *vuname)
struct option_cache * lookup_option(struct universe *universe, struct option_state *options, unsigned code)
int int log_info(const char *,...) __attribute__((__format__(__printf__
int packet6_len_okay(const char *packet, int len)
void * dmalloc(size_t, const char *, int)
int parse_options(struct packet *packet)
unsigned char dhcp4o6_flags[3]
u_int32_t getULong(const unsigned char *)
#define DHO_SUBNET_SELECTION
int validate_packet(struct packet *packet)
#define DHO_DHCP_MAX_MESSAGE_SIZE
int get_option(struct data_string *result, struct universe *universe, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct option_state *options, struct binding_scope **scope, unsigned code, const char *file, int line)
void fqdn6_option_space_foreach(struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct universe *u, void *stuff, void(*func)(struct option_cache *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct universe *, void *))
struct universe ** universes
int store_options6(char *buf, int buflen, struct option_state *opt_state, struct packet *packet, const int *required_opts, struct data_string *oro)
int append_option_buffer(struct universe *universe, struct option_state *options, struct buffer *bp, unsigned char *buffer, unsigned length, unsigned code, int terminatep)
u_int32_t getUChar(const unsigned char *)
void suboption_foreach(struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct universe *u, void *stuff, void(*func)(struct option_cache *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct universe *, void *), struct option_cache *oc, const char *vsname)
void option_space_foreach(struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct universe *u, void *stuff, void(*func)(struct option_cache *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct universe *, void *))
u_int32_t(* get_tag)(const unsigned char *)
void dhcpv6(struct packet *)
struct universe dhcpv6_universe
int make_const_data(struct expression **expr, const unsigned char *data, unsigned len, int terminated, int allocate, const char *file, int line)
void free_pair(pair foo, const char *file, int line)
int packet_dereference(struct packet **ptr, const char *file, int line)
int packet_allocate(struct packet **ptr, const char *file, int line)
int format_min_length(const char *, struct option_cache *)
int option_chain_head_allocate(struct option_chain_head **ptr, const char *file, int line)
#define FQDN_SERVER_UPDATE
void(* store_tag)(unsigned char *, u_int32_t)
#define dmalloc_reuse(x, y, l, z)
unsigned char transaction_id[3]
void save_fqdn6_option(struct universe *universe, struct option_state *options, struct option_cache *oc, isc_boolean_t appendp)
int MRns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src, u_char *dst, size_t dstsiz)
void hashed_option_space_foreach(struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct universe *u, void *stuff, void(*func)(struct option_cache *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct universe *, void *))
struct universe fqdn_universe
void dhcp(struct packet *packet)
int nwip_option_space_encapsulate(struct data_string *result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct universe *universe)
#define DHO_DHCP_OPTION_OVERLOAD
option_code_hash_t * code_hash
pair cons(caddr_t car, pair cdr)
#define DHO_DHCP_RENEWAL_TIME
struct in6_addr dhcpv6_peer_address
#define DHO_DHCP_CLIENT_IDENTIFIER
void trace_inpacket_stash(struct interface_info *, struct dhcp_packet *, unsigned, unsigned int, struct iaddr, struct hardware *)
void putUShort(unsigned char *, u_int32_t)
struct universe nwip_universe
int format_has_text(const char *)
unsigned char options[FLEXIBLE_ARRAY_MEMBER]
const unsigned char * data
int get_option_int(int *result, struct universe *universe, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct option_state *options, struct binding_scope **scope, unsigned code, const char *file, int line)
#define DHO_DHCP_MESSAGE_TYPE
struct option * vendor_cfg_option
void data_string_copy(struct data_string *dest, const struct data_string *src, const char *file, int line)
struct in6_addr dhcpv6_link_address
void(* save_func)(struct universe *, struct option_state *, struct option_cache *, isc_boolean_t)
unsigned char options[FLEXIBLE_ARRAY_MEMBER]
#define DHCP_OPTIONS_COOKIE
int option_dereference(struct option **dest, const char *file, int line)
#define DHO_VENDOR_ENCAPSULATED_OPTIONS
unsigned char options[DHCP_MAX_OPTION_LEN]
#define DHO_DHCP_REQUESTED_ADDRESS
int buffer_dereference(struct buffer **ptr, const char *file, int line)
struct option_cache * lookup_linked_option(struct universe *universe, struct option_state *options, unsigned code)
#define compute_option_hash(x)