8 #include <netinet/ether.h>
11 #include "libvalidate.h"
32 struct dt_fun *function;
40 struct dt_op stack[32];
45 bool (*call)(struct dt_state *s, int nargs);
49 dt_test_number(double number, const char *value)
54 n = strtod(value, &e);
56 return (e > value && *e == 0 && n == number);
60 dt_test_string(const char *s, const char *end, const char *value)
69 if (!esc && *s == '\\')
88 return (*s == *value || (s > end && *value == 0));
92 dt_step(struct dt_state *s);
95 dt_call(struct dt_state *s);
98 dt_type_or(struct dt_state *s, int nargs)
108 dt_type_and(struct dt_state *s, int nargs)
118 dt_type_not(struct dt_state *s, int nargs)
127 dt_type_neg(struct dt_state *s, int nargs)
130 const char *value = s->value;
135 if (*s->value == '!')
136 while (isspace(*++s->value));
145 dt_type_list(struct dt_state *s, int nargs)
149 char *p, *str = strdup(s->value);
150 const char *value = s->value;
155 for (p = strtok(str, " \t"); p; p = strtok(NULL, " \t"))
175 dt_type_min(struct dt_state *s, int nargs)
180 if (nargs >= 1 && s->stack[s->pos].type == OP_NUMBER)
182 n = strtol(s->value, &e, 0);
184 return (e > s->value && *e == 0 &&
185 n >= s->stack[s->pos].value.number);
192 dt_type_max(struct dt_state *s, int nargs)
197 if (nargs >= 1 && s->stack[s->pos].type == OP_NUMBER)
199 n = strtol(s->value, &e, 0);
201 return (e > s->value && *e == 0 &&
202 n <= s->stack[s->pos].value.number);
209 dt_type_range(struct dt_state *s, int nargs)
215 s->stack[s->pos].type == OP_NUMBER &&
216 s->stack[s->pos + 1].type == OP_NUMBER)
218 n = strtol(s->value, &e, 0);
220 return (e > s->value && *e == 0 &&
221 n >= s->stack[s->pos].value.number &&
222 n <= s->stack[s->pos + 1].value.number);
229 dt_type_minlen(struct dt_state *s, int nargs)
231 if (nargs >= 1 && s->stack[s->pos].type == OP_NUMBER)
232 return (strlen(s->value) >= s->stack[s->pos].value.number);
238 dt_type_maxlen(struct dt_state *s, int nargs)
240 if (nargs >= 1 && s->stack[s->pos].type == OP_NUMBER)
241 return (strlen(s->value) <= s->stack[s->pos].value.number);
247 dt_type_rangelen(struct dt_state *s, int nargs)
250 s->stack[s->pos].type == OP_NUMBER &&
251 s->stack[s->pos + 1].type == OP_NUMBER)
252 return (strlen(s->value) >= s->stack[s->pos].value.number &&
253 strlen(s->value) <= s->stack[s->pos + 1].value.number);
259 dt_type_int(struct dt_state *s, int nargs)
263 strtol(s->value, &e, 0);
265 return (e > s->value && *e == 0);
269 dt_type_uint(struct dt_state *s, int nargs)
274 n = strtol(s->value, &e, 0);
276 return (e > s->value && *e == 0 && n >= 0);
280 dt_type_float(struct dt_state *s, int nargs)
284 strtod(s->value, &e);
286 return (e > s->value && *e == 0);
290 dt_type_ufloat(struct dt_state *s, int nargs)
295 n = strtod(s->value, &e);
297 return (e > s->value && *e == 0 && n >= 0.0);
301 dt_type_bool(struct dt_state *s, int nargs)
304 const char *values[] = {
305 "0", "off", "false", "no",
306 "1", "on", "true", "yes"
309 for (i = 0; i < sizeof(values) / sizeof(values[0]); i++)
310 if (!strcasecmp(values[i], s->value))
317 dt_type_string(struct dt_state *s, int nargs)
323 dt_type_ip4addr(struct dt_state *s, int nargs)
326 return inet_pton(AF_INET, s->value, &a);
330 dt_type_ip6addr(struct dt_state *s, int nargs)
333 return inet_pton(AF_INET6, s->value, &a);
337 dt_type_ipaddr(struct dt_state *s, int nargs)
339 return (dt_type_ip4addr(s, 0) || dt_type_ip6addr(s, 0));
343 dt_type_netmask4(struct dt_state *s, int nargs)
348 if (!inet_pton(AF_INET, s->value, &a))
354 a.s_addr = ntohl(a.s_addr);
356 for (i = 0; (i < 32) && !(a.s_addr & (1 << i)); i++);
358 return ((uint32_t)(~((1 << i) - 1)) == a.s_addr);
362 dt_type_netmask6(struct dt_state *s, int nargs)
367 if (!inet_pton(AF_INET6, s->value, &a))
370 for (i = 0; (i < 16) && (a.s6_addr[i] == 0xFF); i++);
375 if ((a.s6_addr[i] != 255) && (a.s6_addr[i] != 254) &&
376 (a.s6_addr[i] != 252) && (a.s6_addr[i] != 248) &&
377 (a.s6_addr[i] != 240) && (a.s6_addr[i] != 224) &&
378 (a.s6_addr[i] != 192) && (a.s6_addr[i] != 128) &&
382 for (; (i < 16) && (a.s6_addr[i] == 0); i++);
388 dt_type_cidr4(struct dt_state *s, int nargs)
392 char *p, buf[sizeof("255.255.255.255/32\0")];
394 if (strlen(s->value) >= sizeof(buf))
397 strcpy(buf, s->value);
398 p = strchr(buf, '/');
404 n = strtoul(p, &p, 10);
406 if ((*p != 0) || (n > 32))
410 return inet_pton(AF_INET, buf, &a);
414 dt_type_cidr6(struct dt_state *s, int nargs)
418 char *p, buf[sizeof("FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:255.255.255.255/128\0")];
420 if (strlen(s->value) >= sizeof(buf))
423 strcpy(buf, s->value);
424 p = strchr(buf, '/');
430 n = strtoul(p, &p, 10);
432 if ((*p != 0) || (n > 128))
436 return inet_pton(AF_INET6, buf, &a);
440 dt_type_cidr(struct dt_state *s, int nargs)
442 return (dt_type_cidr4(s, 0) || dt_type_cidr6(s, 0));
446 dt_type_ipmask4(struct dt_state *s, int nargs)
451 char *p, buf[sizeof("255.255.255.255/255.255.255.255\0")];
453 if (strlen(s->value) >= sizeof(buf))
456 strcpy(buf, s->value);
457 p = strchr(buf, '/');
465 rv = dt_type_netmask4(s, 0);
472 return inet_pton(AF_INET, buf, &a);
476 dt_type_ipmask6(struct dt_state *s, int nargs)
481 char *p, buf[sizeof("FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:255.255.255.255/"
482 "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:255.255.255.255\0")];
484 if (strlen(s->value) >= sizeof(buf))
487 strcpy(buf, s->value);
488 p = strchr(buf, '/');
496 rv = dt_type_netmask6(s, 0);
503 return inet_pton(AF_INET6, buf, &a);
507 dt_type_ipmask(struct dt_state *s, int nargs)
509 return (dt_type_ipmask4(s, 0) || dt_type_ipmask6(s, 0));
513 dt_type_port(struct dt_state *s, int nargs)
518 n = strtoul(s->value, &e, 10);
520 return (e > s->value && *e == 0 && n <= 65535);
524 dt_type_portrange(struct dt_state *s, int nargs)
529 n = strtoul(s->value, &e, 10);
531 if (e == s->value || *e != '-')
534 m = strtoul(e + 1, &e, 10);
536 return (*e == 0 && n <= 65535 && m <= 65535 && n <= m);
540 dt_type_macaddr(struct dt_state *s, int nargs)
542 return !!ether_aton(s->value);
546 dt_type_uciname(struct dt_state *s, int nargs)
551 *p && ((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z') ||
552 (*p >= '0' && *p <= '9') || (*p == '_'));
559 dt_type_wpakey(struct dt_state *s, int nargs)
561 int len = strlen(s->value);
562 const char *p = s->value;
572 return (len >= 8 && len <= 63);
576 dt_type_wepkey(struct dt_state *s, int nargs)
578 int len = strlen(s->value);
579 const char *p = s->value;
581 if (!strncmp(p, "s:", 2))
587 if (len == 10 || len == 26)
595 return (len == 5 || len == 13);
599 dt_type_hostname(struct dt_state *s, int nargs)
601 const char *p, *last;
603 for (p = last = s->value; *p; p++)
607 if ((p - last) == 0 || (p - last) > 63)
613 else if ((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z') ||
614 (*p >= '0' && *p <= '9') || (*p == '_') || (*p == '-'))
622 return ((p - last) > 0 && (p - last) <= 255);
626 dt_type_host(struct dt_state *s, int nargs)
628 return (dt_type_hostname(s, 0) || dt_type_ipaddr(s, 0));
632 dt_type_network(struct dt_state *s, int nargs)
634 return (dt_type_uciname(s, 0) || dt_type_host(s, 0));
638 dt_type_phonedigit(struct dt_state *s, int nargs)
643 *p && ((*p >= '0' && *p <= '9') || (*p == '*') || (*p == '#') ||
644 (*p == '!') || (*p == '.'));
651 dt_type_directory(struct dt_state *s, int nargs)
654 return (!stat(s->value, &st) && S_ISDIR(st.st_mode));
659 dt_type_device(struct dt_state *s, int nargs)
662 return (!stat(s->value, &st) &&
663 (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode)));
667 dt_type_file(struct dt_state *s, int nargs)
670 return (!stat(s->value, &st) && S_ISREG(st.st_mode));
674 static struct dt_fun dt_types[] = {
675 { "or", dt_type_or },
676 { "and", dt_type_and },
677 { "not", dt_type_not },
678 { "neg", dt_type_neg },
679 { "list", dt_type_list },
680 { "min", dt_type_min },
681 { "max", dt_type_max },
682 { "range", dt_type_range },
683 { "minlength", dt_type_minlen },
684 { "maxlength", dt_type_maxlen },
685 { "rangelength", dt_type_rangelen },
686 { "integer", dt_type_int },
687 { "uinteger", dt_type_uint },
688 { "float", dt_type_float },
689 { "ufloat", dt_type_ufloat },
690 { "bool", dt_type_bool },
691 { "string", dt_type_string },
692 { "ip4addr", dt_type_ip4addr },
693 { "ip6addr", dt_type_ip6addr },
694 { "ipaddr", dt_type_ipaddr },
695 { "cidr4", dt_type_cidr4 },
696 { "cidr6", dt_type_cidr6 },
697 { "cidr", dt_type_cidr },
698 { "netmask4", dt_type_netmask4 },
699 { "netmask6", dt_type_netmask6 },
700 { "ipmask4", dt_type_ipmask4 },
701 { "ipmask6", dt_type_ipmask6 },
702 { "ipmask", dt_type_ipmask },
703 { "port", dt_type_port },
704 { "portrange", dt_type_portrange },
705 { "macaddr", dt_type_macaddr },
706 { "uciname", dt_type_uciname },
707 { "wpakey", dt_type_wpakey },
708 { "wepkey", dt_type_wepkey },
709 { "hostname", dt_type_hostname },
710 { "host", dt_type_host },
711 { "network", dt_type_network },
712 { "phonedigit", dt_type_phonedigit },
713 { "directory", dt_type_directory },
714 { "device", dt_type_device },
715 { "file", dt_type_file },
720 static struct dt_fun *
721 dt_lookup_function(const char *s, const char *e)
723 struct dt_fun *fun = dt_types;
727 if (!strncmp(fun->name, s, e - s) && *(fun->name + (e - s)) == '\0')
737 dt_parse_atom(struct dt_state *s, const char *label, const char *end)
744 struct dt_op *op = &s->stack[s->depth];
746 if ((s->depth + 1) >= (sizeof(s->stack) / sizeof(s->stack[0])))
748 printf("Syntax error, expression too long\n");
752 while (isspace(*label))
755 /* test whether label is a float */
756 dval = strtod(label, &e);
761 op->type = OP_NUMBER;
762 op->value.number = dval;
763 op->nextop = ++s->depth;
767 else if ((*label == '"') || (*label == '\''))
769 for (p = label + 1, q = *label, esc = false; p <= end; p++)
784 op->type = OP_STRING;
785 op->length = (p - label) - 2;
786 op->value.string = label + 1;
787 op->nextop = ++s->depth;
793 printf("Syntax error, unterminated string\n");
799 p <= end && ((*p >= 'A' && *p <= 'Z') ||
800 (*p >= 'a' && *p <= 'z') ||
801 (*p >= '0' && *p <= '9') ||
805 func = dt_lookup_function(label, p);
809 printf("Syntax error, unrecognized function\n");
814 op->type = OP_FUNCTION;
815 op->value.function = func;
816 op->nextop = ++s->depth;
821 printf("Syntax error, unexpected EOF\n");
826 dt_parse_list(struct dt_state *s, const char *code, const char *end);
829 dt_parse_expr(const char *code, const char *end, struct dt_state *s)
833 if (!dt_parse_atom(s, code, end))
836 tok = &s->stack[s->depth - 1];
838 while (isspace(*tok->next))
841 if (tok->type == OP_FUNCTION)
843 if (*tok->next == '(')
847 while (isspace(*end) && end > tok->next + 1)
850 return dt_parse_list(s, tok->next + 1, end);
852 else if (tok->next == end)
854 return dt_parse_list(s, tok->next, tok->next);
857 printf("Syntax error, expected '(' or EOF after function label\n");
860 else if (tok->next == end)
865 printf("Syntax error, expected ',' after literal\n");
870 dt_parse_list(struct dt_state *s, const char *code, const char *end)
875 const char *p, *last;
881 fptr = &s->stack[s->depth - 1];
883 for (nest = 0, p = last = code, esc = false, c = *p;
885 p++, c = (p < end) ? *p : '\0')
913 if (!dt_parse_expr(last, p, s))
926 fptr->nextop = s->depth;
931 dt_step(struct dt_state *s)
934 struct dt_op *op = &s->stack[s->pos];
939 rv = op->value.boolean;
943 rv = dt_test_number(op->value.number, s->value);
947 rv = dt_test_string(op->value.string, op->value.string + op->length, s->value);
964 dt_call(struct dt_state *s)
967 struct dt_op *fptr = &s->stack[s->pos];
968 struct dt_fun *func = fptr->value.function;
972 rv = func->call(s, fptr->length);
974 s->pos = fptr->nextop;
980 dt_parse(const char *code, const char *value)
982 struct dt_state s = {
987 .value.function = &dt_types[0],
993 if (!value || !*value)
996 if (!dt_parse_list(&s, code, code + strlen(code)))