29#define DHCP_OPTION_DATA
36static int pretty_text(
char **,
char *,
const unsigned char **,
37 const unsigned char *,
int);
38static int pretty_dname(
char **,
char *,
const unsigned char *,
39 const unsigned char *);
40static int pretty_domain(
char **,
char *,
const unsigned char **,
41 const unsigned char *);
43 unsigned char *
buffer,
unsigned length,
44 unsigned code,
int terminatep,
56 packet -> options_valid = 0;
63 &
packet -> raw -> options [4],
106 (
unsigned char *)
packet -> raw -> sname,
107 sizeof packet -> raw -> sname,
112 packet -> options_valid = 1;
121 const unsigned char *
buffer;
125 unsigned len, offset;
130 char *reason =
"general failure";
133 log_error (
"no memory for option buffer.");
136 memcpy (bp -> data,
buffer, length);
149 reason =
"code tag at end of buffer - missing "
166 log_fatal(
"Improperly configured option space(%s): "
167 "may not have a nonzero length size "
168 "AND a NULL get_length function.",
181 if (offset + len > length) {
184 reason =
"option length exceeds option buffer length";
186 log_error(
"parse_option_buffer: malformed option "
213 log_debug (
"Ignoring empty DHO_HOST_NAME option");
223 bp->
data + offset, len,
226 "save_option_buffer failed");
235 memset(&
new, 0,
sizeof new);
238 log_error(
"parse_option_buffer: No memory.");
250 new.data =
new.buffer->data;
259 while (op->
next != NULL)
263 log_error(
"parse_option_buffer: No memory.");
271 nop->data.buffer = NULL;
273 nop->data.data = bp->
data + offset;
299 s = strchr (eopt -> format,
'E');
301 log_error (
"internal encapsulation format error 1.");
305 t = strchr (++s,
'.');
309 log_error (
"internal encapsulation format error 2.");
312 if (t == s && uname) {
323 s, (
unsigned)(t - s))) {
339 const unsigned char *
buffer,
360 if (eopt -> format [0] !=
'E')
367 const unsigned char *
buffer,
368 unsigned length,
struct universe *u)
378 log_error (
"no memory for option buffer.");
381 memcpy (&bp ->
data [3],
buffer + 1, length - 1);
410 if (!bp ->
data [0]) {
414 if (
buffer [length - 1] == 0) {
422 for (i = 3; i < length &&
buffer [i] !=
'.'; i++);
433 if (length > 4 + i &&
435 &bp ->
data[6 + i], length - 4 - i,
441 &bp ->
data [5], length - 3,
447 unsigned total_len = 0;
448 unsigned first_len = 0;
454 while (s < &bp ->
data[0] + length + 2) {
457 log_info (
"label length exceeds 63 in fqdn option");
464 if (s + len > &bp ->
data [0] + length + 3) {
465 log_info (
"fqdn label longer than buffer");
469 if (first_len == 0) {
475 total_len += len + 1;
486 first_len = total_len;
491 &bp ->
data[6], first_len,
494 if (total_len > 0 && first_len != total_len) {
496 &bp->
data[6 + first_len],
497 total_len - first_len,
503 &bp ->
data [6], total_len,
543 int overload_avail,
int terminate,
int bootpp,
546#define PRIORITY_COUNT 300
549 unsigned char buffer[4096], agentopts[1024];
551 unsigned mb_size = 0, mb_max = 0;
552 unsigned option_size = 0, agent_size = 0;
558 int overload_used = 0;
559 int of1 = 0, of2 = 0;
561 memset(&ds, 0,
sizeof ds);
575 cfg_options, scope, op,
MDL) != 0)) {
576 if (ds.
len >= sizeof (u_int16_t)) {
578 if(!mms || (i < mms))
610 if (inpacket != NULL &&
628 in_options, cfg_options, scope,
629 priority_list, priority_len,
632 mb_size += agent_size;
641 if (mb_size > agent_size)
642 mb_max = mb_size - agent_size;
646 if (overload_avail & 1) {
651 if (overload_avail & 2) {
672 if (prl != NULL && prl->
len > 0) {
676 priority_list[priority_len++] =
685 priority_list[priority_len++] =
695 for (i = 0; i < prl->
len; i++) {
701 priority_list[priority_len++] = prl->
data[i];
713 priority_list[priority_len++] =
DHO_FQDN;
744 priority_list[priority_len++] =
DHO_FQDN;
759 for (pp = hash[i]; pp; pp = pp->cdr) {
765 priority_list[priority_len++] =
780 for (pp = hash[i]; pp; pp = pp->cdr) {
786 priority_list[priority_len++] =
801 priority_list[priority_len++] =
811 priority_list[priority_len++] =
822 in_options, cfg_options, scope,
823 priority_list, priority_len,
824 of1, of2, terminate, vuname);
827 if (option_size == 0)
831 index += option_size;
838 if (mb_size - agent_size - index < 3)
843 buffer[index++] = overload_used;
845 if (overload_used & 1)
848 if (overload_used & 2)
854 if (mb_size - index >= agent_size) {
855 memcpy(&
buffer[index], agentopts, agent_size);
858 log_error(
"Unable to store relay agent information "
892 struct lease *dummy_lease,
898 void *void_vsio_state) {
903 memset(&ds, 0,
sizeof(ds));
905 NULL, opt_state, NULL,
934 log_debug(
"No space for option %d in VSIO space %s.",
939 log_error(
"Error evaluating option %d in VSIO space %s.",
962add_option6_data(
char *buf,
int buflen,
int* bufpos, uint16_t code,
964 if ((ds->
len + 4) > (buflen - *bufpos)) {
965 log_debug(
"No space for option %d", code);
967 unsigned char* tmp = (
unsigned char *)buf + *bufpos;
973 memcpy(tmp+4, ds->
data, ds->
len);
975 *bufpos += 4 + ds->
len;
1006store_encap6 (
char *buf,
int buflen,
int* bufpos,
1008 struct option* encap_opt, uint16_t code) {
1014 char* s = (
char*)encap_opt->
format;
1016 if ((s == NULL) || (*s !=
'E') || (strlen(s) <= 2)) {
1020 t = strchr(++s,
'.');
1021 if ((t == NULL) || (t == s)) {
1025 memset(&ds, 0,
sizeof(ds));
1026 memset(&name, 0,
sizeof(name));
1027 name.data = (
unsigned char *)s;
1035 add_option6_data(buf, buflen, bufpos, code, &ds);
1051 const int *required_opts,
1060 int in_required_opts;
1061 int vsio_option_code;
1072 vsio_option_code = 0;
1076 vsio_option_code = o->
code;
1081 if (vsio_option_code == 0) {
1082 log_fatal(
"No VSIO option code found.");
1085 if (required_opts != NULL) {
1086 for (i=0; required_opts[i] != 0; i++) {
1087 if (required_opts[i] == vsio_option_code) {
1092 opt_state, required_opts[i]);
1096 memset(&ds, 0,
sizeof(ds));
1097 for (; oc != NULL ; oc = oc->
next) {
1103 (uint16_t)required_opts[i], &ds);
1116 oro_size = oro->
len / 2;
1118 for (i=0; i<oro_size; i++) {
1119 memcpy(&code, oro->
data+(i*2), 2);
1126 in_required_opts = 0;
1127 if (required_opts != NULL) {
1128 for (j=0; required_opts[j] != 0; j++) {
1129 if (required_opts[j] == code) {
1130 in_required_opts = 1;
1135 if (in_required_opts) {
1145 if (code == vsio_option_code) {
1153 memset(&ds, 0,
sizeof(ds));
1156 for (; oc != NULL ; oc = oc->
next) {
1158 NULL, opt_state, NULL,
1174 struct option *encap_opt = NULL;
1175 unsigned int code_int =
code;
1177 option_code_hash_lookup(&encap_opt,
1180 if (encap_opt != NULL) {
1181 store_encap6(buf, buflen, &bufpos, opt_state,
1212 if (vs.bufpos > bufpos+8) {
1213 tmp = (
unsigned char *)buf +
1218 vs.bufpos-bufpos-4);
1237 unsigned char *
buffer,
unsigned index,
unsigned buflen,
1243 unsigned *priority_list,
int priority_len,
1244 unsigned first_cutoff,
int second_cutoff,
int terminate,
1247 int bufix = 0, six = 0, tix = 0;
1251 int bufend, sbufend;
1265 first_cutoff -= index;
1267 second_cutoff -= index;
1270 bufend = sbufend = buflen;
1272 if (first_cutoff >= buflen)
1273 log_fatal(
"%s:%d:store_options: Invalid first cutoff.",
MDL);
1274 bufend = first_cutoff;
1276 if (second_cutoff) {
1277 if (second_cutoff >= buflen)
1278 log_fatal(
"%s:%d:store_options: Invalid second cutoff.",
1280 sbufend = second_cutoff;
1282 }
else if (second_cutoff) {
1283 if (second_cutoff >= buflen)
1284 log_fatal(
"%s:%d:store_options: Invalid second cutoff.",
MDL);
1285 bufend = second_cutoff;
1288 memset (&od, 0,
sizeof od);
1293 for (i = 0; i < priority_len; i++) {
1296 for (ix = i + 1; ix < priority_len + tto; ix++) {
1298 priority_list [ix - tto] =
1300 if (priority_list [i] == priority_list [ix]) {
1318 for (ix = i - 1 ; ix >= 0 ; ix--) {
1331 for (i = 0; i < priority_len; i++) {
1335 int optstart, soptstart, toptstart;
1337 int have_encapsulation = 0;
1341 memset (&encapsulation, 0,
sizeof encapsulation);
1342 have_encapsulation = 0;
1348 code = priority_list [i];
1352 if (code >= cfg_options -> site_code_min)
1353 u =
universes [cfg_options -> site_universe];
1381 t = strchr (++s,
'.');
1383 memset (&name, 0,
sizeof name);
1399 }
else if (vuname) {
1400 name.
data = (
unsigned char *)s;
1401 name.
len = strlen (s);
1404 name.
data = (
unsigned char *)s;
1411 have_encapsulation =
1414 in_options, cfg_options, scope, &name));
1430 if (!oc && !have_encapsulation) {
1440 cfg_options, scope, oc,
MDL);
1459 if (have_encapsulation) {
1460 length += encapsulation.
len;
1515 unsigned incr = length;
1517 unsigned char *base;
1521 ((!six && !tix && (i == priority_len - 1) &&
1522 (bufix + 2 + length < bufend)) ||
1523 (bufix + 5 + length < bufend))) {
1527 }
else if (!splitup && first_cutoff &&
1528 (first_cutoff + six + 3 + length < sbufend)) {
1529 base = &
buffer[first_cutoff];
1532 }
else if (!splitup && second_cutoff &&
1533 (second_cutoff + tix + 3 + length < buflen)) {
1534 base = &
buffer[second_cutoff];
1541 if (bufix + 6 < bufend) {
1542 incr = bufend - bufix - 5;
1546 }
else if (first_cutoff &&
1547 (first_cutoff + six + 4 < sbufend)) {
1548 incr = sbufend - (first_cutoff + six) - 3;
1549 base = &
buffer[first_cutoff];
1552 }
else if (second_cutoff &&
1553 (second_cutoff + tix + 4 < buflen)) {
1554 incr = buflen - (second_cutoff + tix) - 3;
1555 base = &
buffer[second_cutoff];
1573 base [*pix + 1] = (
unsigned char)incr;
1574 if (tto && incr == length) {
1576 memcpy (base + *pix + 2,
1577 od.
data + ix, (
unsigned)(incr - 1));
1578 base [*pix + 2 + incr - 1] = 0;
1580 memcpy (base + *pix + 2,
1581 od.
data + ix, (
unsigned)incr);
1594 if (first_cutoff && six) {
1595 if ((first_cutoff + six + 1) < sbufend)
1597 sbufend - (first_cutoff + six + 1));
1598 else if (first_cutoff + six >= sbufend)
1599 log_fatal(
"Second buffer overflow in overloaded options.");
1606 if (second_cutoff && tix) {
1607 if (second_cutoff + tix + 1 < buflen) {
1609 buflen - (second_cutoff + tix + 1));
1610 }
else if (second_cutoff + tix >= buflen)
1611 log_fatal(
"Third buffer overflow in overloaded options.");
1618 if ((six || tix) && (bufix + 3 > bufend))
1619 log_fatal(
"Not enough space for option overload option.");
1635 while (*p !=
'\0') {
1660 log_error(
"format_has_text(%s): 'c' atoms are illegal "
1661 "except after 'D' atoms.", format);
1673 while ((*p !=
'\0') && (*p++ !=
'.'))
1696 const char *p, *name;
1702 while (*p !=
'\0') {
1728 log_fatal(
"Corrupt format: %s", format);
1731 if (espace == NULL) {
1732 log_error(
"Unknown enumeration: %s", format);
1737 min_len += espace->
width;
1738 last_size = espace->
width;
1752 min_len -= last_size;
1774 log_error(
"format_min_length(%s): 'c' atom is illegal "
1775 "except after 'D' atom.", format);
1780 log_error(
"format_min_length(%s): No safe value "
1781 "for unknown format symbols.", format);
1792#define MAX_OUTPUT_SIZE 32*1024
1795 const unsigned char *data;
1810 char fmtbuf[32] =
"";
1814 const unsigned char *dp = data;
1819 unsigned int octets = 0;
1826 memset (enumbuf, 0,
sizeof enumbuf);
1830 for (l = i = 0;
option -> format [i]; i++, l++) {
1831 if (l >=
sizeof(fmtbuf) - 1)
1832 log_fatal(
"Bounds failure on internal buffer at "
1836 log_error (
"%s: Extra codes in format string: %s",
1838 &(
option -> format [i]));
1842 fmtbuf [l] =
option -> format [i];
1843 switch (
option -> format [i]) {
1854 while (
option -> format [i] &&
1855 option -> format [i] !=
'.')
1859 for (k = 0; k < len; k++) {
1860 if (!isascii (data [k]) ||
1861 !isprint (data [k]))
1867 if (k == len || (k + 1 == len && data [k] == 0)) {
1882 log_error(
"'c' atom not following D atom in format "
1902 log_error(
"%s: Illegal use of domain name: %s",
1922 while (
option -> format [i] &&
1923 option -> format [i] !=
'.')
1928 if (enumbuf[l] == NULL) {
1932 hunksize += enumbuf[l]->
width;
1933 hunkinc = enumbuf[l]->
width;
1966 log_error (
"%s: garbage in format string: %s",
1968 &(
option -> format [i]));
1974 if (hunksize - opthunk > len) {
1975 log_error (
"%s: expecting at least %d bytes; got %d",
1981 if (numhunk == -1 && hunksize < len)
2000 log_error (
"%s: invalid 'a' format: %s",
2005 numhunk = ((len - hunksize) / hunkinc) + 1;
2006 len_used = hunksize + ((numhunk - 1) * hunkinc);
2015 if (hunksize == 0) {
2016 log_error (
"%s: invalid 'A' format: %s",
2021 numhunk = len / hunksize;
2022 len_used = numhunk * hunksize;
2026 if (len_used < len) {
2027 log_error (
"%s: %d extra bytes at end of array\n",
2050 fmtbuf[0]=
'R'; fmtbuf[1]=
'I'; fmtbuf[2]=0;
2051 for (i =0; i < len; i = i + octets + 5) {
2053 log_error (
"wrong subnet mask width in destination descriptor");
2057 octets = ((data[i]+7) / 8);
2060 log_error (
"classless static routes option has wrong size or "
2061 "there's some garbage in format");
2066 for (i = 0; i < numhunk; i++) {
2067 if ((a_array ==
ISC_TRUE) && (i != 0) && (numelem > 0)) {
2084 for (; j < numelem; j++) {
2085 switch (fmtbuf [j]) {
2089 k = pretty_text(&op, endbuf - 1, &dp,
2090 data + len, emit_quotes);
2104 pretty_dname(&op, endbuf-1, dp, data + len);
2110 for( ; dp < (data + len) ; dp += k) {
2112 const unsigned char *nbp, *nend;
2114 nend = &nbuff[
sizeof(nbuff)];
2124 if (op + 2 > endbuf)
2153 pretty_domain(&op, endbuf-1,
2193 switch (enumbuf[j]->
width) {
2209 return "<double impossible condition>";
2220 dp += enumbuf[j]->
width;
2224 sprintf(op,
"%lu", tval);
2238 log_error (
"wrong subnet mask width in destination descriptor");
2254 sprintf (op,
"%ld", (
long)
getLong (dp));
2260 sprintf (op,
"%s",
"infinite");
2262 sprintf(op,
"%lu", tval);
2270 sprintf (op,
"%d", (
int)
getShort (dp));
2274 sprintf(op,
"%u", (
unsigned)
getUShort(dp));
2278 sprintf (op,
"%d", *(
const char *)dp++);
2281 sprintf (op,
"%d", *dp++);
2285 sprintf (op,
"%x", *dp++);
2288 strcpy (op, *dp++ ?
"true" :
"false");
2291 strcpy (op,
"true");
2309 if (dp == data + len)
2311 if (j + 1 < numelem && comma !=
':')
2314 if (i + 1 < numhunk) {
2317 if (dp == data + len)
2324 in_options, cfg_options, options, scope, code,
file,
line)
2346 in_options, cfg_options, scope, oc,
2359 in_options, cfg_options, options, scope, code,
file,
line)
2387 memset(&d1, 0,
sizeof(d1));
2389 in_options, cfg_options, scope, oc,
2395 *result = d1.
data[0];
2417 log_error (
"bogus statement type in set_option.");
2445 log_error (
"Can't allocate const expression.");
2478 switch (((memcmp(
option->option->
format,
"Dc", 2) == 0) +
2484 log_error (
"Both options must be Dc format");
2513 log_error (
"can't look up options in %s space.",
2535 for (bptr = hash [hashix]; bptr; bptr = bptr -> cdr) {
2546 struct buffer *bp,
unsigned char *
buffer,
unsigned length,
2547 unsigned code,
int terminatep)
2552 status = prepare_option_buffer(
universe, bp,
buffer, length, code,
2570 struct buffer *bp,
unsigned char *
buffer,
unsigned length,
2571 unsigned code,
int terminatep)
2576 status = prepare_option_buffer(
universe, bp,
buffer, length, code,
2594 unsigned char *
buffer,
unsigned length,
unsigned code,
2597 struct buffer *lbp = NULL;
2613 if (code > 0xffffffff)
2618 log_fatal(
"Inconsistent universe tag size at %s:%d.",
MDL);
2631 char nbuf[
sizeof(
"unknown-4294967295")];
2633 sprintf(nbuf,
"unknown-%u", code);
2649 log_error(
"No memory for option code %s.%s.",
2664 log_error (
"no memory for option buffer.");
2669 memcpy (lbp ->
data,
buffer, length + terminatep);
2680 op ->
data.len = length;
2689 op ->
data.terminated = 1;
2691 op ->
data.terminated = 0;
2701 while ((op->
data.
len > min_len) &&
2719 struct packet *dummy_packet,
2720 struct lease *dummy_lease,
2726 void *void_accumulator) {
2727 int *accumulator = (
int *)void_accumulator;
2734 struct packet *dummy_packet,
2735 struct lease *dummy_lease,
2784 memset(server_oro, 0,
sizeof(*server_oro));
2786 log_fatal(
"no memory to build server ORO");
2794 server_oro->
len = 0;
2807 server_oro->
len += 2;
2865 for (bptr = hash [hashix]; bptr; bptr = bptr -> cdr) {
2867 (bptr -> car)) ->
option -> code ==
2883 ocloc = &(*ocloc)->
next;
2884 }
while (*ocloc != NULL);
2897 log_error (
"No memory for option_cache reference.");
2900 bptr -> cdr = hash [hashix];
2903 hash [hashix] = bptr;
2914 log_error (
"can't delete options from %s space.",
2933 for (bptr = hash [hashix]; bptr; bptr = bptr -> cdr) {
2942 prev -> cdr = bptr -> cdr;
2944 hash [hashix] = bptr -> cdr;
2958 if (!ptr || !*ptr) {
2959 log_error (
"Null pointer in option_cache_dereference: %s(%d)",
2961#if defined (POINTER_DEBUG)
2986 if ((*ptr) ->
refcnt < 0) {
2988#if defined (DEBUG_RC_HISTORY)
2989 dump_rc_history (*ptr);
2991#if defined (POINTER_DEBUG)
3021 for (cp = heads [i]; cp; cp = next) {
3049 memset(&tmp, 0,
sizeof(tmp));
3102 memset(&tmp, 0,
sizeof(tmp));
3105 in_options, cfg_options, scope, oc,
MDL)) {
3119 end = strchr(++start,
'.');
3124 if (
end == NULL || start ==
end)
3128 start,
end - start,
MDL);
3132 "refers to unknown "
3133 "option space '%.*s'.",
3135 (
int)(
end - start), start);
3147 cfg_options, scope, subu);
3162 in_options, cfg_options, scope,
name)
3178 log_error(
"option_space_encapsulate: option space '%.*s' does "
3179 "not exist, but is configured.",
3186 in_options, cfg_options, scope, u))
3189 log_error(
"encapsulation requested for '%s' with no support.",
3222 memset(&sub, 0,
sizeof(sub));
3236 in_options, cfg_options,
3250 in_options, cfg_options, scope,
universe)
3277 for (p = hash [i]; p; p = p -> cdr) {
3286 in_options, cfg_options, scope,
universe))
3293 in_options, cfg_options, scope,
universe)
3317 for (ocp = head ->
first; ocp; ocp = ocp -> cdr) {
3330 static unsigned char nni [] = { 1, 0 };
3332 memset (&ds, 0,
sizeof ds);
3337 if (!option_code_hash_lookup(&no_nwip->
option,
3340 log_fatal(
"Nwip option hash does not contain "
3346 cfg_options, scope, no_nwip))
3350 memset (&ds, 0,
sizeof ds);
3359 ds.
buffer -> data [0] = 2;
3360 ds.
buffer -> data [1] = 0;
3361 memcpy (&ds.
buffer -> data [2], result -> data, result -> len);
3377fqdn_encode(
unsigned char *dst,
int dstlen,
const unsigned char *src,
3381 int i, j, len, outlen=0;
3384 for (i = 0, j = 0 ; i < srclen ; i = j) {
3385 while ((j < srclen) && (src[j] !=
'.') && (src[j] !=
'\0'))
3389 if ((outlen + 1 + len) > dstlen)
3399 memcpy(out, src + i, len);
3407 if ((outlen + 1) > dstlen)
3418 in_options, cfg_options, scope,
universe)
3445 memset (results, 0,
sizeof results);
3446 for (ocp = head ->
first; ocp; ocp = ocp -> cdr) {
3453 in_options, cfg_options, scope,
3465 log_error (
"no memory for option buffer.");
3473 memset (&bp ->
data [0], 0, len);
3487 bp ->
data [0] |= 2;
3490 bp ->
data [0] |= 1;
3500 i = fqdn_encode(&bp->
data[3], len - 3,
3517 result -> terminated = 0;
3602 unsigned char *
data;
3603 int i, len, rval = 0, count;
3613 memset(results, 0,
sizeof(results));
3614 for (ocp = head->
first ; ocp != NULL ; ocp = ocp->
cdr) {
3621 cfg_options, scope, oc,
MDL);
3631 log_error(
"No memory for virtual option buffer.");
3664 count = fqdn_encode(
data + 1, len - 1,
3673 result->
len += count;
3691 const unsigned char *
buffer,
unsigned length,
3694 struct buffer *bp = NULL;
3695 unsigned char *first_dot;
3696 int len, hlen, dlen;
3711 unsigned bp_size = 3 + (length * 4);
3714 log_error(
"No memory for dhcp6.fqdn option buffer.");
3746 log_error(
"Unable to convert dhcp6.fqdn domain name to "
3753 unsigned char *fqdn_start = bp->
data + 3;
3759 first_dot = (
unsigned char *)strchr((
char *)fqdn_start,
'.');
3761 if (first_dot != NULL) {
3762 hlen = first_dot - fqdn_start;
3805 cfg_options, scope, u, stuff, func);
3828 in_options, cfg_options,
3854 hash = cfg_options ->
universes [u -> index];
3860 for (p = hash [i]; p; p = p -> cdr) {
3863 in_options, cfg_options, scope, u, stuff);
3890 for (tail = &head ->
first; *tail; tail = &((*tail) -> cdr)) {
3893 if (oc->
option->
code == (*ocloc)->option->code) {
3896 ocloc = &(*ocloc)->
next;
3897 }
while (*ocloc != NULL);
3906 *tail =
cons (0, 0);
3909 (&(*tail) -> car), oc,
MDL);
3914 in_options, cfg_options, scope,
universe)
3935 for (oc = head ->
first; oc; oc = oc -> cdr) {
3943 in_options, cfg_options, scope,
universe))
3964 for (tail = &head ->
first; *tail; tail = &((*tail) -> cdr)) {
3968 tmp = (*tail) -> cdr;
3970 (&(*tail) -> car),
MDL);
3993 for (oc = head ->
first; oc; oc = oc -> cdr) {
4038 for (car = head ->
first; car; car = car -> cdr) {
4041 in_options, cfg_options, scope, u, stuff);
4049 unsigned int from_port;
4054 struct packet *decoded_packet;
4055#if defined (DEBUG_MEMORY_LEAKAGE)
4056 unsigned long previous_outstanding = dmalloc_outstanding;
4059#if defined (TRACING)
4063 decoded_packet = NULL;
4065 log_error(
"do_packet: no memory for incoming packet!");
4073 decoded_packet->
haddr = hfrom;
4077 log_info(
"Discarding packet with bogus hlen.");
4100 memset(&dp, 0,
sizeof dp);
4102 decoded_packet->
options, NULL,
4114 dhcp(decoded_packet);
4116 bootp(decoded_packet);
4122#if defined (DEBUG_MEMORY_LEAKAGE)
4123 log_info(
"generation %ld: %ld new, %ld outstanding, %ld long-term",
4125 dmalloc_outstanding - previous_outstanding,
4126 dmalloc_outstanding, dmalloc_longterm);
4127 dmalloc_dump_outstanding();
4129#if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY)
4158 int len,
int from_port,
const struct iaddr *from,
4160 unsigned char msg_type;
4166 struct packet *decoded_packet;
4167#if defined (DEBUG_MEMORY_LEAKAGE)
4168 unsigned long previous_outstanding = dmalloc_outstanding;
4173 "short packet from %s port %d, len %d, dropped",
4174 piaddr(*from), from_port, len);
4178 decoded_packet = NULL;
4180 log_error(
"do_packet6: no memory for incoming packet.");
4185 log_error(
"do_packet6: no memory for options.");
4201 interface_reference(&decoded_packet->
interface, interface,
MDL);
4203 decoded_packet->
unicast = was_unicast;
4220 relay->
options, len - relaylen,
4273#if defined (DEBUG_MEMORY_LEAKAGE)
4274 log_info(
"generation %ld: %ld new, %ld outstanding, %ld long-term",
4276 dmalloc_outstanding - previous_outstanding,
4277 dmalloc_outstanding, dmalloc_longterm);
4278 dmalloc_dump_outstanding();
4280#if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY)
4288 const unsigned char *send)
4295 if (dst == NULL || dend == NULL || src == NULL || send == NULL ||
4296 *dst == NULL || *src == NULL || (*dst >= dend) || (*src > send) ||
4297 ((send - *src) > (dend - *dst)))
4300 for ( ; *src < send ; (*src)++) {
4301 if (!isascii (**src) || !isprint (**src)) {
4303 if ((*src + 1) != send || **src !=
'\0') {
4304 if (*dst + 4 > dend)
4307 sprintf(*dst,
"\\%03o",
4312 }
else if (**src ==
'"' || **src ==
'\'' || **src ==
'$' ||
4313 **src ==
'`' || **src ==
'\\' || **src ==
'|' ||
4315 if (*dst + 2 > dend)
4324 if (*dst + 1 > dend)
4337pretty_text(
char **dst,
char *dend,
const unsigned char **src,
4338 const unsigned char *send,
int emit_quotes)
4342 if (dst == NULL || dend == NULL || src == NULL || send == NULL ||
4343 *dst == NULL || *src == NULL ||
4344 ((*dst + (emit_quotes ? 2 : 0)) > dend) || (*src > send))
4353 count =
pretty_escape(dst, dend - (emit_quotes ? 1 : 0), src, send);
4358 if (emit_quotes && (*dst < dend)) {
4370pretty_dname(
char **dst,
char *dend,
const unsigned char *src,
4371 const unsigned char *send)
4373 const unsigned char *tend;
4374 const unsigned char *srcp = src;
4378 if (dst == NULL || dend == NULL || src == NULL || send == NULL ||
4379 *dst == NULL || ((*dst + 1) > dend) || (src >= send))
4407 if ((status == -1) || ((*dst + 1) > dend))
4412 count += status + 1;
4420pretty_domain(
char **dst,
char *dend,
const unsigned char **src,
4421 const unsigned char *send)
4423 const unsigned char *tend;
4427 if (dst == NULL || dend == NULL || src == NULL || send == NULL ||
4428 *dst == NULL || *src == NULL ||
4429 ((*dst + 2) > dend) || (*src >= send))
4448 tend = (*src) + tsiz;
4460 if ((status == -1) || ((*dst + 2) > dend))
4465 count += status + 1;
4481 unsigned int option_num,
4483 unsigned int data_len)
4493 &option_num, 0,
MDL)) {
4494 log_error(
"Attempting to add unknown option %d.", option_num);
4500 log_error(
"No memory for option cache adding %s (option %d).",
4513 log_error(
"No memory for constant data adding %s (option %d).",
4547 log_debug(
"Dropped DHCPv4 packet with zero-length client-id");
4550 }
else if (oc->
data.
len == 1) {
4557 log_debug(
"Accepted DHCPv4 packet with one-character client-id - "
4558 "a future version of ISC DHCP will reject this");
4568 log_debug(
"Dropped DHCPv4 packet with wrong "
4569 "(len == %d) pxe-client-id", oc->
data.
len);
4578 log_debug(
"Received DHCPv4 packet without client-id"
4579 " option and empty hlen field.");
4633 if ((
packet == NULL) || (in_options == NULL) || (out_options == NULL))
4648 in_options, out_options, scope, oc,
MDL);
4651 if (
name.len == 0) {
4660 if ((oc == NULL) || (oc->
data.
len == 0)) {
4676 (
const char *)
name.data);
#define rc_register(file, line, reference, addr, refcnt, d, f)
int buffer_reference(struct buffer **ptr, struct buffer *bp, const char *file, int line)
int expression_allocate(struct expression **cptr, const char *file, int line)
int option_cache_reference(struct option_cache **ptr, struct option_cache *src, const char *file, int line)
int buffer_allocate(struct buffer **ptr, unsigned len, const char *file, int line)
int option_chain_head_allocate(struct option_chain_head **ptr, const char *file, int line)
void free_pair(pair foo, const char *file, int line)
void data_string_forget(struct data_string *data, const char *file, int line)
int option_state_allocate(struct option_state **ptr, const char *file, int line)
void data_string_truncate(struct data_string *dp, int len)
int packet_dereference(struct packet **ptr, const char *file, int line)
struct option_cache * free_option_caches
struct option * new_option(char *name, const char *file, int line) const
void data_string_copy(struct data_string *dest, const struct data_string *src, const char *file, int line)
int packet_allocate(struct packet **ptr, const char *file, int line)
pair new_pair(char *file, int line) const
int option_cache_allocate(struct option_cache **cptr, const char *file, int line)
int option_chain_head_dereference(struct option_chain_head **ptr, const char *file, int line)
int buffer_dereference(struct buffer **ptr, const char *file, int line)
void save_option(struct universe *universe, struct option_state *options, struct option_cache *oc)
void delete_fqdn6_option(struct universe *universe, struct option_state *options, int code)
int option_cache_dereference(struct option_cache **ptr, const char *file, int line)
const char * pretty_print_option(struct option *option, const unsigned char *data, unsigned len, int emit_commas, int emit_quotes)
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)
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 *))
void save_hashed_option(struct universe *universe, struct option_state *options, struct option_cache *oc, isc_boolean_t appendp)
void delete_option(struct universe *universe, struct option_state *options, int code)
struct universe * find_option_universe(struct option *eopt, const char *uname)
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 fqdn_universe_decode(struct option_state *options, const unsigned char *buffer, unsigned length, struct universe *u)
int parse_encapsulated_suboptions(struct option_state *options, struct option *eopt, const unsigned char *buffer, unsigned len, struct universe *eu, const char *uname)
int hashed_option_state_dereference(struct universe *universe, struct option_state *state, const char *file, int line)
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)
int linked_option_state_dereference(struct universe *universe, struct option_state *state, const char *file, int line)
void set_option(struct universe *universe, struct option_state *options, struct option_cache *option, enum statement_op op)
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 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 *))
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)
struct option_cache * lookup_fqdn6_option(struct universe *universe, struct option_state *options, unsigned code)
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 append_option_buffer(struct universe *universe, struct option_state *options, struct buffer *bp, unsigned char *buffer, unsigned length, unsigned code, int terminatep)
int parse_options(struct packet *packet)
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 *))
int format_has_text(char *format) const
int save_option_buffer(struct universe *universe, struct option_state *options, struct buffer *bp, unsigned char *buffer, unsigned length, unsigned code, int terminatep)
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 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 *))
struct option_cache * lookup_option(struct universe *universe, struct option_state *options, unsigned code)
void do_packet(struct interface_info *interface, struct dhcp_packet *packet, unsigned len, unsigned int from_port, struct iaddr from, struct hardware *hfrom)
struct option_cache * lookup_hashed_option(struct universe *universe, struct option_state *options, unsigned code)
int append_option(struct data_string *dst, struct universe *universe, struct option *option, struct data_string *src)
int pretty_escape(char **dst, char *dend, const unsigned char **src, const unsigned char *send)
struct option_cache * lookup_linked_option(struct universe *universe, struct option_state *options, unsigned code)
void delete_hashed_option(struct universe *universe, struct option_state *options, int code)
struct option * vendor_cfg_option
void save_linked_option(struct universe *universe, struct option_state *options, struct option_cache *oc, isc_boolean_t appendp)
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)
int store_options6(char *buf, int buflen, struct option_state *opt_state, struct packet *packet, const int *required_opts, struct data_string *oro)
void also_save_option(struct universe *universe, struct option_state *options, struct option_cache *oc)
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)
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)
int add_option(struct option_state *options, unsigned int option_num, void *data, unsigned int data_len)
int fqdn6_universe_decode(struct option_state *options, const unsigned char *buffer, unsigned length, struct universe *u)
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 packet6_len_okay(const char *packet, int len)
void build_server_oro(struct data_string *server_oro, struct option_state *options, const char *file, int line)
int parse_option_buffer(struct option_state *options, const unsigned char *buffer, unsigned length, struct universe *universe)
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 validate_packet(struct packet *packet)
void save_fqdn6_option(struct universe *universe, struct option_state *options, struct option_cache *oc, isc_boolean_t appendp)
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)
int format_min_length(char *format, struct option_cache *oc) const
void delete_linked_option(struct universe *universe, struct option_state *options, int code)
struct enumeration * find_enumeration(const char *name, int length)
int32_t getLong(const unsigned char *)
u_int32_t getUShort(const unsigned char *)
void putUShort(unsigned char *, u_int32_t)
u_int32_t getULong(const unsigned char *)
int32_t getShort(const unsigned char *)
u_int32_t getUChar(const unsigned char *)
void putULong(unsigned char *, u_int32_t)
void trace_inpacket_stash(struct interface_info *, struct dhcp_packet *, unsigned, unsigned int, struct iaddr, struct hardware *)
void bootp(struct packet *packet)
void dhcp(struct packet *packet)
#define DHCPV6_RELAY_REPL
#define DHCPV6_RELAY_FORW
#define DHCPV6_DHCPV4_QUERY
#define DHCPV6_DHCPV4_RESPONSE
#define DHO_DHCP_MAX_MESSAGE_SIZE
#define DHO_VENDOR_ENCAPSULATED_OPTIONS
#define DHO_SUBNET_SELECTION
#define DHO_DHCP_AGENT_OPTIONS
#define FQDN_SERVER_UPDATE
#define FQDN_SUBOPTION_COUNT
#define DHCP_FIXED_NON_UDP
#define DHO_DHCP_CLIENT_IDENTIFIER
#define FQDN_NO_CLIENT_UPDATE
#define DHO_ASSOCIATED_IP
#define DHO_PXE_CLIENT_ID
#define DHO_DHCP_MESSAGE_TYPE
#define DHCP_OPTIONS_COOKIE
#define DHO_CLASSLESS_STATIC_ROUTES
#define DHO_DHCP_RENEWAL_TIME
#define DHCP_MIN_OPTION_LEN
#define DHO_DOMAIN_NAME_SERVERS
#define DHO_DHCP_REBINDING_TIME
#define DHO_DHCP_OPTION_OVERLOAD
#define DHO_DHCP_SERVER_IDENTIFIER
#define DHO_DHCP_REQUESTED_ADDRESS
#define DHO_DHCP_LEASE_TIME
#define DHCP_MAX_OPTION_LEN
void do_packet6(struct interface_info *, const char *, int, int, const struct iaddr *, isc_boolean_t)
#define compute_option_hash(x)
struct universe dhcp_universe
void dhcpv6(struct packet *)
const char * piaddr(const struct iaddr addr)
const char * pdestdesc(const struct iaddr addr)
@ supersede_option_statement
@ default_option_statement
@ prepend_option_statement
@ append_option_statement
int MRns_name_ntop(const u_char *src, char *dst, size_t dstsiz)
int MRns_name_len(const u_char *eom, const u_char *src)
int MRns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src, u_char *dst, size_t dstsiz)
#define dmalloc_reuse(x, y, l, z)
void * dmalloc(size_t, const char *, int)
void dfree(void *, const char *, int)
int log_error(const char *,...) __attribute__((__format__(__printf__
int int int log_debug(const char *,...) __attribute__((__format__(__printf__
void log_fatal(const char *,...) __attribute__((__format__(__printf__
int int log_info(const char *,...) __attribute__((__format__(__printf__
const unsigned char * data
unsigned char options[DHCP_MAX_OPTION_LEN]
char sname[DHCP_SNAME_LEN]
unsigned char options[FLEXIBLE_ARRAY_MEMBER]
unsigned char transaction_id[3]
unsigned char options[FLEXIBLE_ARRAY_MEMBER]
unsigned char options[FLEXIBLE_ARRAY_MEMBER]
unsigned char link_address[16]
unsigned char peer_address[16]
struct enumeration_value * values
struct option_cache * next
struct expression * expression
struct universe * universe
struct in6_addr dhcpv6_link_address
unsigned char dhcp4o6_flags[3]
unsigned char dhcpv6_msg_type
unsigned char dhcpv6_hop_count
struct interface_info * interface
struct in6_addr dhcpv6_peer_address
struct option_state * options
unsigned char dhcpv6_transaction_id[3]
int(* decode)(struct option_state *, const unsigned char *, unsigned, struct universe *)
void(* store_length)(unsigned char *, u_int32_t)
void(* save_func)(struct universe *, struct option_state *, struct option_cache *, isc_boolean_t)
int(* encapsulate)(struct data_string *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct universe *)
void(* store_tag)(unsigned char *, u_int32_t)
option_code_hash_t * code_hash
u_int32_t(* get_tag)(const unsigned char *)
u_int32_t(* get_length)(const unsigned char *)
struct option_cache *(* lookup_func)(struct universe *, struct option_state *, unsigned)
struct universe fqdn_universe
struct universe nwip_universe
char * default_option_format
struct universe vsio_universe
int option_reference(struct option **dest, struct option *src, const char *file, int line)
int option_dereference(struct option **dest, const char *file, int line)
universe_hash_t * universe_hash
struct universe dhcpv6_universe
struct universe ** universes
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)
int make_const_data(struct expression **expr, const unsigned char *data, unsigned len, int terminated, int allocate, const char *file, int line)
void expression_dereference(struct expression **eptr, const char *file, int line)
struct binding_scope * global_scope
pair cons(caddr_t car, pair cdr)
int make_concat(struct expression **expr, struct expression *left, struct expression *right)