42 #define DS_SPRINTF_SIZE 128 67 if (ds->
data == NULL) {
74 *((
char *)ds->
data) =
'\0';
81 cur_strlen = strlen((
char *)ds->
data);
82 max = ds->
len - cur_strlen;
89 vsnprintf_ret = vsnprintf((
char *)ds->
data+cur_strlen, max, fmt, args);
96 if (vsnprintf_ret >= max) {
100 new_len = ds->
len * 2;
101 while (new_len <= cur_strlen + vsnprintf_ret) {
114 *((
char *)ds->
data+cur_strlen) =
'\0';
118 memcpy(tmp_buffer->
data, ds->
data, cur_strlen);
122 vsprintf((
char *)tmp_buffer->
data + cur_strlen, fmt, args);
164 bp = (
struct buffer *)0;
166 log_error (
"%s(%d): can't allocate buffer.",
173 log_error (
"%s(%d): can't allocate option cache.", file, line);
178 (*oc) -> data.len = len;
179 (*oc) -> data.buffer = bp;
180 (*oc) -> data.
data = &bp -> data [0];
181 (*oc) -> data.terminated = 0;
183 memcpy (&bp -> data [0], data, len);
193 log_error (
"No memory for host lookup tree node.");
213 log_error (
"Can't allocate space for new host.");
220 unsigned len,
int terminated,
int allocate,
226 log_error (
"No memory for make_const_data tree node.");
234 len + terminated, file, line)) {
235 log_error (
"Can't allocate const_data buffer");
239 nt -> data.const_data.
data =
240 &nt -> data.const_data.buffer -> data [0];
241 memcpy (nt -> data.const_data.buffer -> data,
242 data, len + terminated);
245 nt -> data.const_data.terminated = terminated;
247 nt -> data.const_data.
data = 0;
250 nt -> data.const_data.len = len;
259 log_error (
"No memory for make_const_int tree node.");
288 log_error (
"No memory for concatenation expression node.");
304 log_error (
"No memory for encapsulation expression node.");
321 log_error (
"no memory for substring expression.");
338 log_error (
"no memory for limit expression");
344 log_error (
"no memory for limit offset expression");
353 log_error (
"no memory for limit length expression");
384 (*result) ->
op = let_statement;
390 strcpy ((*result) ->
data.let.
name, name);
394 static int do_host_lookup (result, dns)
403 log_debug (
"time: now = %d dns = %d diff = %d",
408 if (cur_time <= dns ->
timeout) {
413 ? inet_ntoa (*(
struct in_addr *)(dns -> data.
data))
420 log_debug (
"Looking up %s", dns -> hostname);
424 h = gethostbyname (dns -> hostname);
430 log_error (
"%s: host unknown.", dns -> hostname);
434 log_error (
"%s: temporary name server failure",
438 log_error (
"%s: name server failed", dns -> hostname);
441 log_error (
"%s: no A record associated with address",
453 log_debug (
"Lookup succeeded; first address is %s",
454 inet_ntoa (h -> h_addr_list [0]));
458 for (count = 0; h -> h_addr_list [count]; count++)
465 new_len = count * h -> h_length;
468 log_error (
"No memory for %s.", dns -> hostname);
472 dns -> data.
data = &dns -> data.buffer -> data [0];
473 dns -> data.len = new_len;
474 dns -> data.terminated = 0;
478 for (i = 0; i < count; i++) {
479 memcpy (&dns -> data.buffer -> data [h -> h_length * i],
480 h -> h_addr_list [i], (
unsigned)(h -> h_length));
483 log_debug (
"dns -> data: %x h -> h_addr_list [0]: %x",
484 *(
int *)(dns ->
buffer), h -> h_addr_list [0]);
492 log_debug (
"hard copy: %d %s", dns -> data.len,
494 ? inet_ntoa (*(
struct in_addr *)(dns -> data.
data)) : 0));
501 in_options, cfg_options, scope, expr,
file,
line)
520 if (!scope || !*scope)
525 if (binding && binding ->
value) {
539 if (!scope || !*scope) {
541 expr -> data.funcall.name);
545 binding =
find_binding (*scope, expr -> data.funcall.name);
547 if (!binding || !binding ->
value) {
549 expr -> data.funcall.name);
552 if (binding ->
value -> type != binding_function) {
554 expr -> data.funcall.name);
562 log_error (
"%s: can't allocate argument scope.",
563 expr -> data.funcall.name);
567 arg = expr -> data.funcall.arglist;
568 s = binding -> value -> value.fundef -> args;
576 memset (nb, 0,
sizeof *nb);
577 nb -> name =
dmalloc (strlen (s ->
string) + 1,
580 strcpy (nb -> name, s ->
string);
588 in_options, cfg_options, scope,
589 arg -> data.arg.val, file, line);
592 arg = arg -> data.arg.next;
597 expr -> data.funcall.name);
603 expr -> data.funcall.name);
613 lease, client_state, in_options, cfg_options, &ns,
622 bv -> type = binding_boolean;
624 (&bv -> value.boolean, packet, lease, client_state,
625 in_options, cfg_options, scope, expr));
629 bv -> type = binding_numeric;
631 (&bv -> value.intval, packet, lease, client_state,
632 in_options, cfg_options, scope, expr));
636 bv -> type = binding_data;
638 (&bv -> value.data, packet, lease, client_state,
639 in_options, cfg_options, scope, expr,
MDL));
641 log_error (
"%s: invalid expression type: %d",
642 "evaluate_expression", expr -> op);
645 if (result && status)
666 log_error (
"%s(%d): negative refcnt!", file, line);
667 #if defined (DEBUG_RC_HISTORY) 668 dump_rc_history (bv);
670 #if defined (POINTER_DEBUG) 677 switch (bv ->
type) {
686 log_error (
"%s(%d): invalid binding type: %d",
687 file, line, bv ->
type);
695 in_options, cfg_options, scope, expr)
711 int regflags = REG_EXTENDED | REG_NOSUB;
715 switch (expr -> op) {
719 #if defined (DEBUG_EXPRESSIONS) 720 log_debug (
"bool: check (%s) returns %s",
721 expr -> data.check -> name,
722 *result ?
"true" :
"false");
730 in_options, cfg_options, scope,
731 expr -> data.equal [0],
MDL);
733 client_state, in_options,
735 expr -> data.equal [1],
MDL);
736 if (sleft && sright) {
740 switch (obv ->
type) {
777 }
else if (!sleft && !sright)
782 #if defined (DEBUG_EXPRESSIONS) 785 (*result ?
"true" :
"false"));
795 regflags |= REG_ICASE;
800 memset(&left, 0,
sizeof left);
803 in_options, cfg_options,
818 memset(&right, 0,
sizeof right);
821 in_options, cfg_options,
826 memset(&re, 0,
sizeof(re));
827 if (bleft && bright &&
828 (left.
data != NULL) && (right.
data != NULL) &&
829 (regcomp(&re, (
char *)right.
data, regflags) == 0) &&
830 (regexec(&re, (
char *)left.
data, (
size_t)0, NULL, 0) == 0))
833 #if defined (DEBUG_EXPRESSIONS) 839 *result ?
"true" :
"false");
856 return bleft && bright;
868 in_options, cfg_options,
870 expr -> data.and [0]);
873 (&bright, packet, lease, client_state,
874 in_options, cfg_options,
875 scope, expr -> data.and [1]);
879 #if defined (DEBUG_EXPRESSIONS) 881 sleft ? (bleft ?
"true" :
"false") :
"NULL",
882 sright ? (bright ?
"true" :
"false") :
"NULL",
884 ? (bleft && bright ?
"true" :
"false") :
"NULL"));
886 if (sleft && sright) {
887 *result = bleft && bright;
896 in_options, cfg_options,
898 expr -> data.or [0]);
899 if (!sleft || !bleft)
901 (&bright, packet, lease, client_state,
902 in_options, cfg_options,
903 scope, expr -> data.or [1]);
906 #if defined (DEBUG_EXPRESSIONS) 908 sleft ? (bleft ?
"true" :
"false") :
"NULL",
909 sright ? (bright ?
"true" :
"false") :
"NULL",
911 ? (bleft || bright ?
"true" :
"false") :
"NULL"));
913 if (sleft || sright) {
914 *result = bleft || bright;
922 in_options, cfg_options,
925 #if defined (DEBUG_EXPRESSIONS) 927 sleft ? (bleft ?
"true" :
"false") :
"NULL",
928 sleft ? (!bleft ?
"true" :
"false") :
"NULL");
937 memset (&left, 0,
sizeof left);
940 packet, lease, client_state,
941 in_options, cfg_options, in_options,
942 scope, expr -> data.exists -> code,
MDL))
948 #if defined (DEBUG_EXPRESSIONS) 950 expr -> data.option ->
universe -> name,
951 expr -> data.option -> name,
952 *result ?
"true" :
"false");
958 #if defined (DEBUG_EXPRESSIONS) 963 #if defined (DEBUG_EXPRESSIONS) 965 packet -> known ?
"true" :
"false");
967 *result = packet -> known;
972 #if defined (DEBUG_EXPRESSIONS) 973 log_debug (
"bool: static = false (%s %s %s %d)",
975 (lease && (lease -> flags & STATIC_LEASE)
978 lease ? lease -> flags : 0);
983 #if defined (DEBUG_EXPRESSIONS) 990 if (scope && *scope) {
994 if (binding ->
value)
1002 #if defined (DEBUG_EXPRESSIONS) 1003 log_debug (
"boolean: %s? = %s", expr -> data.variable,
1004 *result ?
"true" :
"false");
1009 if (scope && *scope) {
1010 binding =
find_binding (*scope, expr -> data.variable);
1012 if (binding && binding ->
value) {
1020 "evaluate_boolean_expression");
1027 #if defined (DEBUG_EXPRESSIONS) 1028 log_debug (
"boolean: %s = %s", expr -> data.variable,
1029 sleft ? (*result ?
"true" :
"false") :
"NULL");
1036 in_options, cfg_options,
1040 log_error (
"%s() returned type %d in %s.",
1041 expr -> data.funcall.name,
1043 "evaluate_boolean_expression");
1048 #if defined (DEBUG_EXPRESSIONS) 1049 log_debug (
"boolean: %s() = %s", expr -> data.funcall.name,
1050 sleft ? (*result ?
"true" :
"false") :
"NULL");
1082 log_error (
"Data opcode in evaluate_boolean_expression: %d",
1101 log_error (
"Numeric opcode in evaluate_boolean_expression: %d",
1109 log_error (
"dns opcode in evaluate_boolean_expression: %d",
1114 log_error (
"function definition in evaluate_boolean_expr");
1121 log_error (
"Bogus opcode in evaluate_boolean_expression: %d",
1127 in_options, cfg_options, scope, expr,
file,
line)
1140 unsigned long offset,
len, i;
1146 struct packet *relay_packet;
1149 switch (expr -> op) {
1152 memset (&data, 0,
sizeof data);
1155 in_options, cfg_options, scope,
1156 expr -> data.substring.expr,
1161 (&offset, packet, lease, client_state, in_options,
1162 cfg_options, scope, expr -> data.substring.offset);
1165 in_options, cfg_options,
1167 expr -> data.substring.
len);
1169 if (s0 && s1 && s2) {
1173 if (data.
len > offset) {
1175 result -> len -= offset;
1176 if (result -> len > len) {
1177 result -> len = len;
1178 result -> terminated = 0;
1180 result -> data += offset;
1186 #if defined (DEBUG_EXPRESSIONS) 1187 log_debug (
"data: substring (%s, %s, %s) = %s",
1191 (s3 ?
print_hex_2 (result -> len, result -> data, 30)
1202 memset (&data, 0,
sizeof data);
1205 in_options, cfg_options, scope,
1206 expr -> data.suffix.expr,
MDL);
1210 in_options, cfg_options,
1212 expr -> data.suffix.
len);
1221 if (data.
len > len) {
1222 result -> data += data.
len - len;
1223 result -> len = len;
1229 #if defined (DEBUG_EXPRESSIONS) 1230 log_debug (
"data: suffix (%s, %s) = %s",
1242 memset(&data, 0,
sizeof data);
1245 in_options, cfg_options, scope,
1249 result->len = data.
len;
1253 result->data = &result->buffer->data[0];
1254 memcpy(result->buffer->data, data.
data,
1257 s = (
unsigned char *)result->data;
1258 for (i = 0; i < result->len; i++, s++)
1262 log_error(
"data: lcase: no buffer memory.");
1266 #if defined (DEBUG_EXPRESSIONS) 1278 memset(&data, 0,
sizeof data);
1281 in_options, cfg_options, scope,
1285 result->len = data.
len;
1289 result->data = &result->buffer->data[0];
1290 memcpy(result->buffer->data, data.
data,
1293 s = (
unsigned char *)result->data;
1294 for (i = 0; i < result->len; i++, s++)
1298 log_error(
"data: lcase: no buffer memory.");
1302 #if defined (DEBUG_EXPRESSIONS) 1318 packet, lease, client_state,
1319 in_options, cfg_options, in_options,
1320 scope, expr -> data.option -> code,
1325 #if defined (DEBUG_EXPRESSIONS) 1327 expr -> data.option ->
universe -> name,
1328 expr -> data.option -> name,
1329 s0 ?
print_hex_1 (result -> len, result -> data, 60)
1338 packet, lease, client_state,
1339 in_options, cfg_options, cfg_options,
1340 scope, expr -> data.option -> code,
1345 #if defined (DEBUG_EXPRESSIONS) 1346 log_debug (
"data: config-option %s.%s = %s",
1347 expr -> data.option ->
universe -> name,
1348 expr -> data.option -> name,
1349 s0 ?
print_hex_1 (result -> len, result -> data, 60)
1358 memset(result, 0,
sizeof(*result));
1361 #if defined (DEBUG_EXPRESSIONS) 1372 if (packet != NULL && packet->
raw != NULL) {
1374 log_error(
"data: hardware: invalid hlen (%d)\n",
1378 result->len = packet->
raw->
hlen + 1;
1380 result->data = &result->buffer->data[0];
1381 result->buffer->data[0] = packet->
raw->
htype;
1382 memcpy(&result->buffer->data[1],
1384 result->terminated = 0;
1387 "no memory for buffer.");
1390 }
else if (lease != NULL) {
1393 result->data = &result->buffer->data[0];
1394 memcpy(result->buffer->data,
1396 result->terminated = 0;
1399 "no memory for buffer.");
1403 log_error(
"data: hardware: no raw packet or lease " 1408 #if defined (DEBUG_EXPRESSIONS) 1416 if (!packet || !packet -> raw) {
1417 log_error (
"data: packet: raw packet not available");
1423 in_options, cfg_options,
1425 expr -> data.packet.offset);
1427 packet, lease, client_state,
1428 in_options, cfg_options,
1430 expr -> data.packet.
len);
1431 if (s0 && s1 && offset < packet -> packet_length) {
1432 if (offset + len > packet -> packet_length)
1434 packet -> packet_length - offset;
1436 result -> len = len;
1438 result -> len, file, line)) {
1439 result -> data = &result ->
buffer -> data [0];
1440 memcpy (result ->
buffer -> data,
1441 (((
unsigned char *)(packet -> raw))
1442 + offset), result -> len);
1443 result -> terminated = 0;
1445 log_error (
"data: packet: no buffer memory.");
1451 #if defined (DEBUG_EXPRESSIONS) 1452 log_debug (
"data: packet (%ld, %ld) = %s",
1455 result -> data, 60) : NULL);
1464 (result, packet, lease, client_state,
1465 in_options, cfg_options, scope,
1466 &expr -> data.encapsulate);
1470 #if defined (DEBUG_EXPRESSIONS) 1471 log_debug (
"data: encapsulate (%s) = %s",
1472 expr -> data.encapsulate.
data,
1474 result -> data, 60) :
"NULL");
1480 #if defined (DEBUG_EXPRESSIONS) 1483 expr -> data.const_data.
data, 60));
1486 &expr -> data.const_data, file, line);
1491 s0 = do_host_lookup (result, expr -> data.host_lookup);
1492 #if defined (DEBUG_EXPRESSIONS) 1493 log_debug (
"data: DNS lookup (%s) = %s",
1494 expr -> data.host_lookup -> hostname,
1503 memset (&data, 0,
sizeof data);
1506 in_options, cfg_options, scope,
1507 expr -> data.concat [0],
MDL);
1508 memset (&other, 0,
sizeof other);
1511 in_options, cfg_options, scope,
1512 expr -> data.concat [1],
MDL);
1515 result -> len = data.
len + other.
len;
1525 result -> data = &result ->
buffer -> data [0];
1527 memcpy (&result ->
buffer -> data [data.
len],
1535 #if defined (DEBUG_EXPRESSIONS) 1536 log_debug (
"data: concat (%s, %s) = %s",
1548 in_options, cfg_options,
1550 expr -> data.encode_int);
1555 log_error (
"data: encode_int8: no memory");
1559 result -> data = &result ->
buffer -> data [0];
1560 result ->
buffer -> data [0] = len;
1565 #if defined (DEBUG_EXPRESSIONS) 1567 log_debug (
"data: encode_int8 (NULL) = NULL");
1569 log_debug (
"data: encode_int8 (%ld) = %s", len,
1571 result -> data, 20));
1579 in_options, cfg_options,
1581 expr -> data.encode_int);
1586 log_error (
"data: encode_int16: no memory");
1590 result -> data = &result ->
buffer -> data [0];
1596 #if defined (DEBUG_EXPRESSIONS) 1598 log_debug (
"data: encode_int16 (NULL) = NULL");
1600 log_debug (
"data: encode_int16 (%ld) = %s", len,
1602 result -> data, 20));
1609 in_options, cfg_options,
1611 expr -> data.encode_int);
1616 log_error (
"data: encode_int32: no memory");
1620 result -> data = &result ->
buffer -> data [0];
1626 #if defined (DEBUG_EXPRESSIONS) 1628 log_debug (
"data: encode_int32 (NULL) = NULL");
1630 log_debug (
"data: encode_int32 (%ld) = %s", len,
1632 result -> data, 20));
1639 (&offset, packet, lease, client_state, in_options,
1640 cfg_options, scope, expr -> data.b2a.base);
1643 in_options, cfg_options,
1645 expr -> data.b2a.width);
1648 memset (&data, 0,
sizeof data);
1651 in_options, cfg_options, scope,
1652 expr -> data.b2a.separator,
1656 memset (&other, 0,
sizeof other);
1659 in_options, cfg_options, scope,
1662 if (s0 && s1 && s2 && s3) {
1665 if (len != 8 && len != 16 && len != 32) {
1666 log_info (
"binary_to_ascii: %s %ld!",
1667 "invalid width", len);
1675 if (other.
len % len) {
1676 log_info (
"binary-to-ascii: %s %d %s %ld!",
1677 "length of buffer", other.
len,
1678 "not a multiple of width", len);
1685 for (i = 0; i < other.
len; i += len) {
1688 if (other.
data [i] < 8)
1690 else if (other.
data [i] < 64)
1694 }
else if (offset == 10) {
1695 if (other.
data [i] < 10)
1697 else if (other.
data [i] < 100)
1701 }
else if (offset == 16) {
1702 if (other.
data [i] < 16)
1714 if (i + len != other.
len)
1719 buflen + 1, file, line)) {
1720 log_error (
"data: binary-to-ascii: no memory");
1724 result -> data = &result ->
buffer -> data [0];
1725 result -> len = buflen;
1726 result -> terminated = 1;
1729 for (i = 0; i < other.
len; i += len) {
1731 (&result ->
buffer -> data [buflen],
1732 &other.
data [i], offset, len));
1733 if (i + len != other.
len) {
1741 result ->
buffer -> data [buflen] = 0;
1747 #if defined (DEBUG_EXPRESSIONS) 1748 log_debug (
"data: binary-to-ascii (%s, %s, %s, %s) = %s",
1753 (status ?
print_hex_3 (result -> len, result -> data, 30)
1767 (&len, packet, lease, client_state, in_options,
1768 cfg_options, scope, expr -> data.reverse.width);
1771 memset (&data, 0,
sizeof data);
1774 in_options, cfg_options, scope,
1775 expr -> data.reverse.
buffer,
1783 if (data.
len % len) {
1784 log_info (
"reverse: %s %d %s %ld!",
1785 "length of buffer", data.
len,
1786 "not a multiple of width", len);
1793 data.
len, file, line)) {
1798 result -> data = &result ->
buffer -> data [0];
1799 result -> len = data.
len;
1800 result -> terminated = 0;
1802 for (i = 0; i < data.
len; i += len) {
1803 memcpy (&result ->
buffer -> data [i],
1804 &data.
data [data.
len - i - len], len);
1811 #if defined (DEBUG_EXPRESSIONS) 1812 log_debug (
"data: reverse (%s, %s) = %s",
1815 (status ?
print_hex_3 (result -> len, result -> data, 30)
1826 log_debug(
"data: \"leased-address\" configuration " 1827 "directive: there is no lease associated " 1828 "with this client.");
1834 result -> data = &result ->
buffer -> data [0];
1835 memcpy (&result ->
buffer -> data [0],
1837 result -> terminated = 0;
1839 log_error (
"data: leased-address: no memory.");
1842 #if defined (DEBUG_EXPRESSIONS) 1849 memset (&data, 0,
sizeof data);
1852 lease, client_state, in_options, cfg_options,
1853 scope, expr -> data.pick_first_value.car,
MDL))) {
1854 #if defined (DEBUG_EXPRESSIONS) 1855 log_debug (
"data: pick_first_value (%s, xxx)",
1857 result -> data, 40));
1862 if (expr -> data.pick_first_value.cdr &&
1865 lease, client_state, in_options, cfg_options,
1866 scope, expr -> data.pick_first_value.cdr,
MDL))) {
1867 #if defined (DEBUG_EXPRESSIONS) 1868 log_debug (
"data: pick_first_value (NULL, %s)",
1870 result -> data, 40));
1875 #if defined (DEBUG_EXPRESSIONS) 1876 log_debug (
"data: pick_first_value (NULL, NULL) = NULL");
1881 if (!lease || !lease -> host) {
1882 log_error (
"data: host_decl_name: not available");
1885 result -> len = strlen (lease -> host -> name);
1887 result -> len + 1, file, line)) {
1888 result -> data = &result ->
buffer -> data [0];
1889 strcpy ((
char *)&result ->
buffer -> data [0],
1890 lease -> host -> name);
1891 result -> terminated = 1;
1893 log_error (
"data: host-decl-name: no memory.");
1896 #if defined (DEBUG_EXPRESSIONS) 1897 log_debug (
"data: host-decl-name = %s", lease -> host -> name);
1902 #if defined (DEBUG_EXPRESSIONS) 1908 if (scope && *scope) {
1909 binding =
find_binding (*scope, expr -> data.variable);
1911 if (binding && binding -> value) {
1912 if (binding -> value -> type == binding_data) {
1914 &binding -> value -> value.data,
1917 }
else if (binding -> value -> type != binding_data) {
1919 binding -> value -> type,
1920 "evaluate_data_expression");
1928 #if defined (DEBUG_EXPRESSIONS) 1929 log_debug (
"data: %s = %s", expr -> data.variable,
1931 result -> data, 50) :
"NULL");
1938 in_options, cfg_options,
1942 log_error (
"%s() returned type %d in %s.",
1943 expr -> data.funcall.name,
1945 "evaluate_data_expression");
1951 #if defined (DEBUG_EXPRESSIONS) 1952 log_debug (
"data: %s = %s", expr -> data.funcall.name,
1954 result -> data, 50) :
"NULL");
1960 if (packet && packet -> raw -> file [0]) {
1962 memchr (packet -> raw -> file, 0,
1963 sizeof packet -> raw -> file);
1965 fn = ((
char *)packet -> raw -> file +
1966 sizeof packet -> raw -> file);
1967 result -> len = fn - &(packet -> raw -> file [0]);
1969 result -> len + 1, file, line)) {
1970 result -> data = &result ->
buffer -> data [0];
1971 memcpy (&result ->
buffer -> data [0],
1972 packet -> raw -> file,
1974 result ->
buffer -> data [result -> len] = 0;
1975 result -> terminated = 1;
1978 log_error (
"data: filename: no memory.");
1984 #if defined (DEBUG_EXPRESSIONS) 1985 log_info (
"data: filename = \"%s\"",
1986 s0 ? (
const char *)(result -> data) :
"NULL");
1992 if (packet && packet -> raw -> sname [0]) {
1994 memchr (packet -> raw -> sname, 0,
1995 sizeof packet -> raw -> sname);
1997 fn = ((
char *)packet -> raw -> sname +
1998 sizeof packet -> raw -> sname);
1999 result -> len = fn - &packet -> raw -> sname [0];
2001 result -> len + 1, file, line)) {
2002 result -> data = &result ->
buffer -> data [0];
2003 memcpy (&result ->
buffer -> data [0],
2004 packet -> raw -> sname,
2006 result ->
buffer -> data [result -> len] = 0;
2007 result -> terminated = 1;
2016 #if defined (DEBUG_EXPRESSIONS) 2018 s0 ? (
const char *)(result -> data) :
"NULL");
2031 memset(result, 0,
sizeof(*result));
2033 log_error(
"data: gethostname(): no memory for buffer");
2036 result->data = result->buffer->data;
2043 if (!gethostname((
char *)result->buffer->data, 255)) {
2044 if (result->buffer->data[255] ==
'\0')
2046 strlen((
char *)result->buffer->data);
2072 memset (&data, 0,
sizeof data);
2077 in_options, cfg_options,
2084 ((packet == NULL) ||
2086 #if defined (DEBUG_EXPRESSIONS) 2087 log_debug(
"data: v6relay(%lu) = NULL", len);
2094 relay_packet = packet;
2095 relay_options = in_options;
2099 relay_options = relay_packet->
options;
2104 #if defined (DEBUG_EXPRESSIONS) 2105 log_debug(
"data: v6relay(%lu) = NULL", len);
2111 client_state, relay_options,
2121 #if defined (DEBUG_EXPRESSIONS) 2122 log_debug(
"data: v6relay(%lu) = %s", len,
2132 memset(&data, 0,
sizeof data);
2136 in_options, cfg_options, scope,
2139 memset (&other, 0,
sizeof other);
2142 in_options, cfg_options, scope,
2148 log_error (
"data: concat_dclist failed");
2152 #if defined (DEBUG_EXPRESSIONS) 2153 log_debug (
"data: concat_dclists (%s, %s) = %s",
2158 (((s0 && s1) && result->len > 0)
2159 ?
print_hex_3 (result->len, result->data, result->len)
2185 log_error (
"Boolean opcode in evaluate_data_expression: %d",
2204 log_error (
"Numeric opcode in evaluate_data_expression: %d",
2212 log_error (
"dns opcode in evaluate_boolean_expression: %d",
2217 log_error (
"function definition in evaluate_data_expression");
2225 log_error (
"Bogus opcode in evaluate_data_expression: %d", expr -> op);
2230 in_options, cfg_options, scope, expr)
2231 unsigned
long *result;
2241 int status, sleft, sright;
2245 unsigned long ileft, iright;
2248 switch (expr -> op) {
2263 log_error (
"Boolean opcode in evaluate_numeric_expression: %d",
2292 log_error (
"Data opcode in evaluate_numeric_expression: %d",
2297 memset (&data, 0,
sizeof data);
2299 (&data, packet, lease, client_state, in_options,
2300 cfg_options, scope, expr -> data.extract_int,
MDL);
2302 *result = data.
data [0];
2303 #if defined (DEBUG_EXPRESSIONS) 2304 log_debug (
"num: extract_int8 (%s) = %s",
2312 memset(&data, 0,
sizeof(data));
2314 (&data, packet, lease, client_state, in_options,
2316 if (status && data.
len >= 2) {
2320 #if defined (DEBUG_EXPRESSIONS) 2322 log_debug(
"num: extract_int16 (%s) = %ld",
2326 log_debug(
"num: extract_int16 (NULL) = NULL");
2335 memset (&data, 0,
sizeof data);
2337 (&data, packet, lease, client_state, in_options,
2338 cfg_options, scope, expr -> data.extract_int,
MDL));
2339 if (status && data.
len >= 4) {
2343 #if defined (DEBUG_EXPRESSIONS) 2345 log_debug (
"num: extract_int32 (%s) = %ld",
2349 log_debug (
"num: extract_int32 (NULL) = NULL");
2356 *result = expr -> data.const_int;
2357 #if defined (DEBUG_EXPRESSIONS) 2358 log_debug (
"number: CONSTANT = %ld", *result);
2364 log_error(
"data: leased_lease: not available");
2369 "data: lease_time: lease ends at",
2374 #if defined (DEBUG_EXPRESSIONS) 2375 log_debug(
"number: lease-time = (%lu - %lu) = %ld",
2376 (
long unsigned)lease->
ends,
2382 if (scope && *scope) {
2383 binding =
find_binding (*scope, expr -> data.variable);
2385 if (binding && binding ->
value) {
2392 "evaluate_numeric_expression");
2399 #if defined (DEBUG_EXPRESSIONS) 2402 expr -> data.variable, *result);
2405 expr -> data.variable);
2413 in_options, cfg_options,
2417 log_error (
"%s() returned type %d in %s.",
2418 expr -> data.funcall.name,
2420 "evaluate_numeric_expression");
2425 #if defined (DEBUG_EXPRESSIONS) 2426 log_debug (
"data: %s = %ld", expr -> data.funcall.name,
2427 status ? *result : 0);
2434 in_options, cfg_options,
2436 expr -> data.and [0]);
2439 in_options, cfg_options,
2441 expr -> data.and [1]);
2443 #if defined (DEBUG_EXPRESSIONS) 2444 if (sleft && sright)
2446 ileft, iright, ileft + iright);
2448 log_debug (
"num: %ld + NULL = NULL", ileft);
2450 log_debug (
"num: NULL + %ld = NULL", iright);
2452 if (sleft && sright) {
2453 *result = ileft + iright;
2461 in_options, cfg_options,
2463 expr -> data.and [0]);
2466 in_options, cfg_options,
2468 expr -> data.and [1]);
2470 #if defined (DEBUG_EXPRESSIONS) 2471 if (sleft && sright)
2473 ileft, iright, ileft - iright);
2475 log_debug (
"num: %ld - NULL = NULL", ileft);
2477 log_debug (
"num: NULL - %ld = NULL", iright);
2479 if (sleft && sright) {
2480 *result = ileft - iright;
2488 in_options, cfg_options,
2490 expr -> data.and [0]);
2493 in_options, cfg_options,
2495 expr -> data.and [1]);
2497 #if defined (DEBUG_EXPRESSIONS) 2498 if (sleft && sright)
2500 ileft, iright, ileft * iright);
2502 log_debug (
"num: %ld * NULL = NULL", ileft);
2504 log_debug (
"num: NULL * %ld = NULL", iright);
2506 if (sleft && sright) {
2507 *result = ileft * iright;
2515 in_options, cfg_options,
2517 expr -> data.and [0]);
2520 in_options, cfg_options,
2522 expr -> data.and [1]);
2524 #if defined (DEBUG_EXPRESSIONS) 2525 if (sleft && sright) {
2528 ileft, iright, ileft / iright);
2533 log_debug (
"num: %ld / NULL = NULL", ileft);
2535 log_debug (
"num: NULL / %ld = NULL", iright);
2537 if (sleft && sright && iright) {
2538 *result = ileft / iright;
2546 in_options, cfg_options,
2548 expr -> data.and [0]);
2551 in_options, cfg_options,
2553 expr -> data.and [1]);
2555 #if defined (DEBUG_EXPRESSIONS) 2556 if (sleft && sright) {
2559 ileft, iright, ileft % iright);
2564 log_debug (
"num: %ld %% NULL = NULL", ileft);
2566 log_debug (
"num: NULL %% %ld = NULL", iright);
2568 if (sleft && sright && iright) {
2569 *result = ileft % iright;
2577 in_options, cfg_options,
2579 expr -> data.and [0]);
2582 in_options, cfg_options,
2584 expr -> data.and [1]);
2586 #if defined (DEBUG_EXPRESSIONS) 2587 if (sleft && sright)
2589 ileft, iright, ileft & iright);
2591 log_debug (
"num: %ld & NULL = NULL", ileft);
2593 log_debug (
"num: NULL & %ld = NULL", iright);
2595 if (sleft && sright) {
2596 *result = ileft & iright;
2604 in_options, cfg_options,
2606 expr -> data.and [0]);
2609 in_options, cfg_options,
2611 expr -> data.and [1]);
2613 #if defined (DEBUG_EXPRESSIONS) 2614 if (sleft && sright)
2616 ileft, iright, ileft | iright);
2618 log_debug (
"num: %ld | NULL = NULL", ileft);
2620 log_debug (
"num: NULL | %ld = NULL", iright);
2622 if (sleft && sright) {
2623 *result = ileft | iright;
2631 in_options, cfg_options,
2633 expr -> data.and [0]);
2636 in_options, cfg_options,
2638 expr -> data.and [1]);
2640 #if defined (DEBUG_EXPRESSIONS) 2641 if (sleft && sright)
2643 ileft, iright, ileft ^ iright);
2645 log_debug (
"num: %ld ^ NULL = NULL", ileft);
2647 log_debug (
"num: NULL ^ %ld = NULL", iright);
2649 if (sleft && sright) {
2650 *result = ileft ^ iright;
2657 #if defined (DEBUG_EXPRESSIONS) 2659 client_state -> state);
2661 *result = client_state -> state;
2664 #if defined (DEBUG_EXPRESSIONS) 2671 log_error (
"function definition in evaluate_numeric_expr");
2678 log_fatal(
"Impossible case at %s:%d. Undefined operator " 2679 "%d.",
MDL, expr->
op);
2683 log_error (
"evaluate_numeric_expression: bogus opcode %d", expr -> op);
2700 in_options, cfg_options, scope, oc,
file,
line)
2719 in_options, cfg_options, scope,
2735 cfg_options, scope, oc,
file,
line)
2753 if (oc && in_options) {
2756 memset(&ds, 0,
sizeof ds);
2758 lease, client_state, in_options,
2759 cfg_options, scope, oc, file,
2764 if (ds.
data[0] == 1)
2766 else if ((ds.
data[0] == 2) && (ignorep != NULL))
2781 in_options, cfg_options, scope, expr)
2798 in_options, cfg_options,
2829 if (expr ->
refcnt < 0) {
2830 log_error (
"%s(%d): negative refcnt!", file, line);
2831 #if defined (DEBUG_RC_HISTORY) 2832 dump_rc_history (expr);
2834 #if defined (POINTER_DEBUG) 2842 switch (expr ->
op) {
3117 static int op_val (
enum expr_op);
3119 static int op_val (
op)
3203 return op_val (op1) - op_val (op2);
3317 switch (expr ->
op) {
3349 col, indent + 2, 0);
3425 (file, col, indent,
"",
"",
3474 expr ->
data.
not, col, indent + 2, 1);
3531 sprintf (obuf,
"%d", width);
3554 sprintf (obuf,
"%d", width);
3575 goto print_option_name;
3637 s =
"config-option";
3638 goto print_option_name;
3749 log_fatal (
"invalid expression type in print_expression: %d",
3760 for (s = scope; s; s = s ->
outer) {
3761 for (bp = s ->
bindings; bp; bp = bp -> next) {
3762 if (!strcasecmp (name, bp -> name)) {
3774 for (bp = scope -> bindings; bp; bp =
next) {
3780 dfree (bp, file, line);
3782 scope -> bindings = (
struct binding *)0;
3793 if (!ptr || !*ptr) {
3794 log_error (
"%s(%d): null pointer", file, line);
3795 #if defined (POINTER_DEBUG) 3802 binding_scope = *ptr;
3803 *ptr = (
struct binding_scope *)0;
3804 --binding_scope ->
refcnt;
3807 if (binding_scope ->
refcnt > 0)
3810 if (binding_scope ->
refcnt < 0) {
3811 log_error (
"%s(%d): negative refcnt!", file, line);
3812 #if defined (DEBUG_RC_HISTORY) 3813 dump_rc_history (binding_scope);
3815 #if defined (POINTER_DEBUG) 3823 if (binding_scope ->
outer)
3825 dfree (binding_scope, file, line);
3837 if ((ptr == NULL) || (*ptr == NULL)) {
3838 log_error (
"%s(%d): null pointer", file, line);
3839 #if defined (POINTER_DEBUG) 3849 if (bp -> refcnt < 0) {
3850 log_error (
"%s(%d): negative refcnt!", file, line);
3851 #if defined (DEBUG_RC_HISTORY) 3852 dump_rc_history (bp);
3854 #if defined (POINTER_DEBUG) 3860 if (!bp -> refcnt) {
3861 for (sp = bp -> args; sp; sp =
next) {
3863 dfree (sp, file, line);
3865 if (bp -> statements)
3868 dfree (bp, file, line);
3870 *ptr = (
struct fundef *)0;
3874 #if defined (NOTYET) 3878 int crhs, clhs, llhs, lrhs;
3879 switch (expr -> op) {
3881 if (expr -> data.substring.len &&
3884 (
int)expr -> data.substring.len -> data.const_int);
3891 if (expr -> data.suffix.len &&
3894 (
int)expr -> data.suffix.len -> data.const_int);
3907 expr -> data.concat [0]);
3909 expr -> data.concat [1]);
3910 if (crhs == 0 || clhs == 0)
3920 *rv = expr -> data.const_data.len;
3925 expr -> data.reverse.buffer);
3934 expr -> data.concat [0]);
3936 expr -> data.concat [1]);
3937 if (crhs == 0 || clhs == 0)
3947 expr -> data.v6relay.relay);
3949 expr -> data.v6relay.roption);
3950 if (crhs == 0 || clhs == 0)
4055 return (
struct binding *)0;
4062 return (
struct binding *)0;
4064 memset (binding, 0,
sizeof *binding);
4065 binding -> name =
dmalloc (strlen (name) + 1,
MDL);
4066 if (!binding -> name) {
4068 return (
struct binding *)0;
4070 strcpy (binding -> name, name);
4072 binding ->
next = (*scope) -> bindings;
4073 (*scope) -> bindings = binding;
4090 if (binding -> value)
4097 binding -> value -> type = binding_data;
4111 !binding -> value ||
4112 binding -> value -> type != binding_data)
4115 if (binding -> value -> value.
data.terminated) {
4124 memcpy (value ->
buffer -> data,
4125 binding -> value -> value.
data.data,
4126 binding -> value -> value.
data.len);
4127 value -> data = value ->
buffer -> data;
4128 value -> len = binding -> value -> value.
data.len;
4140 if (binding ->
value)
4182 char *uncomp = uncompbuf;
4184 int compbuf_max = 0;
4189 if (list1 && (list1->
data) && (list1->
len)) {
4195 " error decompressing domain list 1");
4199 uncomp_len = list_len;
4204 if (list2 && (list2->
data) && (list2->
len)) {
4206 if (uncomp_len > 0) {
4212 uncomp, (
sizeof(uncompbuf)
4216 " error decompressing domain list 2");
4220 uncomp_len += list_len;
4225 if (uncomp_len == 0) {
4227 log_error (
"concat_dclists: empty list allocate fail");
4243 compbuf_max = uncomp_len + 3;
4245 for (i = 0; i < uncomp_len; i++)
4246 if (*uncomp++ ==
',')
4251 log_error (
"concat_dclists: No memory for result");
4260 if (list_len <= 0) {
4261 log_error (
"concat_dlists: error compressing result");
4268 result->
len = list_len;
#define rc_register(file, line, reference, addr, refcnt, d, f)
int executable_statement_allocate(struct executable_statement **ptr, const char *file, int line)
char * print_dotted_quads(unsigned len, const u_int8_t *data)
struct binding_scope * global_scope
int token_indent_data_string(FILE *file, int col, int indent, const char *prefix, const char *suffix, struct data_string *data)
int binding_value_dereference(struct binding_value **v, const char *file, int line)
int executable_statement_dereference(struct executable_statement **ptr, const char *file, int line)
int free_bindings(struct binding_scope *scope, const char *file, int line)
const char * piaddr(const struct iaddr addr)
int make_const_option_cache(struct option_cache **oc, struct buffer **buffer, u_int8_t *data, unsigned len, struct option *option, const char *file, int line)
struct expression::expr_union::@25 arg
struct expression * equal[2]
struct binding_scope * outer
struct data_string encapsulate
void * dmalloc(unsigned, const char *, int)
struct expression::expr_union::@21 pick_first_value
int expression_allocate(struct expression **cptr, const char *file, int line)
int data_string_sprintfa(struct data_string *ds, const char *fmt,...)
int execute_statements(struct binding_value **result, 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, struct executable_statement *statements, struct on_star *on_star)
struct iaddr ip_addr(struct iaddr subnet, struct iaddr mask, u_int32_t host_address)
int binding_value_reference(struct binding_value **ptr, struct binding_value *src, const char *file, int line)
#define print_hex_1(len, data, limit)
struct executable_statement * statements
enum expression_context expression_context(struct expression *expr)
struct expression * lcase
int int int log_debug(const char *,...) __attribute__((__format__(__printf__
struct expression * arglist
struct expression::expr_union::@16 substring
char * print_dec_2(unsigned long val)
int is_numeric_expression(struct expression *expr)
int option_reference(struct option **dest, struct option *src, const char *file, int line)
int find_bound_string(struct data_string *value, struct binding_scope *scope, const char *name)
struct universe dhcp_universe
char * print_dec_1(unsigned long val)
void data_string_forget(struct data_string *data, const char *file, int line)
struct expression * concat[2]
int evaluate_numeric_expression(unsigned long *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 expression *expr)
enum binding_value::@15 type
int log_error(const char *,...) __attribute__((__format__(__printf__
int is_compound_expression(struct expression *expr)
struct expression * offset
int binding_scope_dereference(struct binding_scope **ptr, const char *file, int line)
enum expression_context op_context(enum expr_op op)
int evaluate_expression(struct binding_value **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 expression *expr, const char *file, int line)
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)
void indent_spaces(FILE *file, int indent)
int make_substring(struct expression **new, struct expression *expr, struct expression *offset, struct expression *length)
struct option_state * options
struct expression::expr_union::@17 suffix
int is_boolean_expression(struct expression *expr)
void expression_dereference(struct expression **eptr, const char *file, int line)
void log_fatal(const char *,...) __attribute__((__format__(__printf__
int evaluate_boolean_expression_result(int *ignorep, 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 expression *expr)
int binding_value_allocate(struct binding_value **cptr, const char *file, int line)
int buffer_reference(struct buffer **ptr, struct buffer *bp, const char *file, int line)
int option_cache_allocate(struct option_cache **cptr, const char *file, int line)
union expression::expr_union data
struct hardware hardware_addr
int unset(struct binding_scope *scope, const char *name)
struct expression * encode_int
int make_host_lookup(struct expression **expr, const char *name)
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 expression::expr_union::@20 reverse
struct expression * width
struct expression * roption
int buffer_allocate(struct buffer **ptr, unsigned len, const char *file, int line)
int binding_scope_allocate(struct binding_scope **ptr, const char *file, int line)
void putULong(unsigned char *, u_int32_t)
int binary_to_ascii(unsigned char *, const unsigned char *, unsigned int, unsigned int)
int make_concat(struct expression **expr, struct expression *left, struct expression *right)
int MRns_name_compress_list(const char *buf, int buflen, unsigned char *compbuf, size_t compbuf_size)
Creates a compressed list from a string of comma-separated domain-names.
u_int32_t getUShort(const unsigned char *)
void dfree(void *, const char *, int)
struct expression * buffer
int concat_dclists(struct data_string *result, struct data_string *list1, struct data_string *list2)
Adds two Dc-formatted lists into a single Dc-formatted list.
int make_let(struct executable_statement **result, const char *name)
struct hardware hw_address
#define print_hex_3(len, data, limit)
int int log_info(const char *,...) __attribute__((__format__(__printf__
struct expression * relay
int fundef_dereference(struct fundef **ptr, const char *file, int line)
struct expression::expr_union::@19 b2a
int evaluate_data_expression(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 expression *expr, const char *file, int line)
int option_cache(struct option_cache **oc, struct data_string *dp, struct expression *expr, struct option *option, const char *file, int line)
struct expression * extract_int
u_int32_t getULong(const unsigned char *)
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)
int check_collection(struct packet *packet, struct lease *lease, struct collection *collection)
union binding_value::value value
int MRns_name_uncompress_list(const unsigned char *buf, int buflen, char *dst_buf, size_t dst_size)
Creates a string of comma-separated domain-names from a compressed list.
struct data_string const_data
struct binding * bindings
int binding_scope_reference(struct binding_scope **ptr, struct binding_scope *bp, const char *file, int line)
int token_print_indent_concat(FILE *file, int col, int indent, const char *prefix, const char *suffix,...)
int evaluate_boolean_option_cache(int *ignorep, 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)
#define print_hex_2(len, data, limit)
int make_const_data(struct expression **expr, const unsigned char *data, unsigned len, int terminated, int allocate, const char *file, int line)
int enter_dns_host(struct dns_host_entry **dh, const char *name)
struct string_list * next
int is_data_expression(struct expression *expr)
struct binding_value * value
int make_limit(struct expression **new, struct expression *expr, int limit)
struct binding * create_binding(struct binding_scope **scope, const char *name)
struct expression * ucase
void free_expression(struct expression *expr, const char *file, int line)
struct collection * check
int make_encapsulation(struct expression **expr, struct data_string *name)
int expression_reference(struct expression **ptr, struct expression *src, const char *file, int line)
int dns_host_entry_allocate(struct dns_host_entry **ptr, const char *hostname, const char *file, int line)
int converted_length(const unsigned char *, unsigned int, unsigned int)
u_int8_t hbuf[HARDWARE_ADDR_LEN+1]
int evaluate_boolean_expression(int *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 expression *expr)
int op_precedence(enum expr_op op1, enum expr_op op2)
int token_print_indent(FILE *file, int col, int indent, const char *prefix, const char *suffix, const char *buf)
int dns_host_entry_dereference(struct dns_host_entry **ptr, const char *file, int line)
int make_const_int(struct expression **expr, unsigned long val)
struct expression::expr_union::@27 v6relay
struct dns_host_entry * host_lookup
pair cons(caddr_t car, pair cdr)
int write_expression(FILE *file, struct expression *expr, int col, int indent, int firstp)
struct binding * find_binding(struct binding_scope *scope, const char *name)
void putUShort(unsigned char *, u_int32_t)
const unsigned char * data
struct interface_info * interface
int bind_ds_value(struct binding_scope **scope, const char *name, struct data_string *value)
void data_string_copy(struct data_string *dest, const struct data_string *src, const char *file, int line)
void free_binding_value(struct binding_value *bv, const char *file, int line)
struct expression::expr_union::@26 funcall
int data_subexpression_length(int *, struct expression *)
int expr_valid_for_context(struct expression *, enum expression_context)
struct expression::expr_union::@18 packet
struct expression * separator
int buffer_dereference(struct buffer **ptr, const char *file, int line)
struct packet * dhcpv6_container_packet
int data_string_terminate(struct data_string *str, const char *file, int line)