85b69aff74e283877ec52348ccc2240472076f01
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_ip4addr(struct dt_state
*s
, int nargs
)
320 return inet_pton(AF_INET
, s
->value
, &a
);
324 dt_type_ip6addr(struct dt_state
*s
, int nargs
)
327 return inet_pton(AF_INET6
, s
->value
, &a
);
331 dt_type_ipaddr(struct dt_state
*s
, int nargs
)
333 return (dt_type_ip4addr(s
, 0) || dt_type_ip6addr(s
, 0));
337 dt_type_netmask4(struct dt_state
*s
, int nargs
)
342 if (!inet_pton(AF_INET
, s
->value
, &a
))
348 a
.s_addr
= ntohl(a
.s_addr
);
350 for (i
= 0; (i
< 32) && !(a
.s_addr
& (1 << i
)); i
++);
352 return ((uint32_t)(~((1 << i
) - 1)) == a
.s_addr
);
356 dt_type_netmask6(struct dt_state
*s
, int nargs
)
361 if (!inet_pton(AF_INET6
, s
->value
, &a
))
364 for (i
= 0; (i
< 16) && (a
.s6_addr
[i
] == 0xFF); i
++);
369 if ((a
.s6_addr
[i
] != 255) && (a
.s6_addr
[i
] != 254) &&
370 (a
.s6_addr
[i
] != 252) && (a
.s6_addr
[i
] != 248) &&
371 (a
.s6_addr
[i
] != 240) && (a
.s6_addr
[i
] != 224) &&
372 (a
.s6_addr
[i
] != 192) && (a
.s6_addr
[i
] != 128) &&
376 for (; (i
< 16) && (a
.s6_addr
[i
] == 0); i
++);
382 dt_type_cidr4(struct dt_state
*s
, int nargs
)
386 char *p
, buf
[sizeof("255.255.255.255/32\0")];
388 if (strlen(s
->value
) >= sizeof(buf
))
391 strcpy(buf
, s
->value
);
392 p
= strchr(buf
, '/');
398 n
= strtoul(p
, &p
, 10);
400 if ((*p
!= 0) || (n
> 32))
404 return inet_pton(AF_INET
, buf
, &a
);
408 dt_type_cidr6(struct dt_state
*s
, int nargs
)
412 char *p
, buf
[sizeof("FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:255.255.255.255/128\0")];
414 if (strlen(s
->value
) >= sizeof(buf
))
417 strcpy(buf
, s
->value
);
418 p
= strchr(buf
, '/');
424 n
= strtoul(p
, &p
, 10);
426 if ((*p
!= 0) || (n
> 128))
430 return inet_pton(AF_INET6
, buf
, &a
);
434 dt_type_cidr(struct dt_state
*s
, int nargs
)
436 return (dt_type_cidr4(s
, 0) || dt_type_cidr6(s
, 0));
440 dt_type_ipmask4(struct dt_state
*s
, int nargs
)
445 char *p
, buf
[sizeof("255.255.255.255/255.255.255.255\0")];
447 if (strlen(s
->value
) >= sizeof(buf
))
450 strcpy(buf
, s
->value
);
451 p
= strchr(buf
, '/');
459 rv
= dt_type_netmask4(s
, 0);
466 return inet_pton(AF_INET
, buf
, &a
);
470 dt_type_ipmask6(struct dt_state
*s
, int nargs
)
475 char *p
, buf
[sizeof("FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:255.255.255.255/"
476 "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:255.255.255.255\0")];
478 if (strlen(s
->value
) >= sizeof(buf
))
481 strcpy(buf
, s
->value
);
482 p
= strchr(buf
, '/');
490 rv
= dt_type_netmask6(s
, 0);
497 return inet_pton(AF_INET6
, buf
, &a
);
501 dt_type_ipmask(struct dt_state
*s
, int nargs
)
503 return (dt_type_ipmask4(s
, 0) || dt_type_ipmask6(s
, 0));
507 dt_type_port(struct dt_state
*s
, int nargs
)
512 n
= strtoul(s
->value
, &e
, 10);
514 return (e
> s
->value
&& *e
== 0 && n
<= 65535);
518 dt_type_portrange(struct dt_state
*s
, int nargs
)
523 n
= strtoul(s
->value
, &e
, 10);
525 if (e
== s
->value
|| *e
!= '-')
528 m
= strtoul(e
+ 1, &e
, 10);
530 return (*e
== 0 && n
<= 65535 && m
<= 65535 && n
<= m
);
534 dt_type_macaddr(struct dt_state
*s
, int nargs
)
536 return !!ether_aton(s
->value
);
540 dt_type_uciname(struct dt_state
*s
, int nargs
)
545 *p
&& ((*p
>= 'A' && *p
<= 'Z') || (*p
>= 'a' && *p
<= 'z') ||
546 (*p
>= '0' && *p
<= '9') || (*p
== '_'));
553 dt_type_wpakey(struct dt_state
*s
, int nargs
)
555 int len
= strlen(s
->value
);
556 const char *p
= s
->value
;
566 return (len
>= 8 && len
<= 63);
570 dt_type_wepkey(struct dt_state
*s
, int nargs
)
572 int len
= strlen(s
->value
);
573 const char *p
= s
->value
;
575 if (!strncmp(p
, "s:", 2))
581 if (len
== 10 || len
== 26)
589 return (len
== 5 || len
== 13);
593 dt_type_hostname(struct dt_state
*s
, int nargs
)
595 const char *p
, *last
;
597 for (p
= last
= s
->value
; *p
; p
++)
601 if ((p
- last
) == 0 || (p
- last
) > 63)
607 else if ((*p
>= 'A' && *p
<= 'Z') || (*p
>= 'a' && *p
<= 'z') ||
608 (*p
>= '0' && *p
<= '9') || (*p
== '_') || (*p
== '-'))
616 return ((p
- last
) > 0 && (p
- last
) <= 255);
620 dt_type_host(struct dt_state
*s
, int nargs
)
622 return (dt_type_hostname(s
, 0) || dt_type_ipaddr(s
, 0));
626 dt_type_network(struct dt_state
*s
, int nargs
)
628 return (dt_type_uciname(s
, 0) || dt_type_host(s
, 0));
632 dt_type_phonedigit(struct dt_state
*s
, int nargs
)
637 *p
&& ((*p
>= '0' && *p
<= '9') || (*p
== '*') || (*p
== '#') ||
638 (*p
== '!') || (*p
== '.'));
645 dt_type_directory(struct dt_state
*s
, int nargs
)
648 return (!stat(s
->value
, &st
) && S_ISDIR(st
.st_mode
));
653 dt_type_device(struct dt_state
*s
, int nargs
)
656 return (!stat(s
->value
, &st
) &&
657 (S_ISBLK(st
.st_mode
) || S_ISCHR(st
.st_mode
)));
661 dt_type_file(struct dt_state
*s
, int nargs
)
664 return (!stat(s
->value
, &st
) && S_ISREG(st
.st_mode
));
668 static struct dt_fun dt_types
[] = {
669 { "or", dt_type_or
},
670 { "and", dt_type_and
},
671 { "not", dt_type_not
},
672 { "neg", dt_type_neg
},
673 { "list", dt_type_list
},
674 { "min", dt_type_min
},
675 { "max", dt_type_max
},
676 { "range", dt_type_range
},
677 { "minlength", dt_type_minlen
},
678 { "maxlength", dt_type_maxlen
},
679 { "rangelength", dt_type_rangelen
},
680 { "integer", dt_type_int
},
681 { "uinteger", dt_type_uint
},
682 { "float", dt_type_float
},
683 { "ufloat", dt_type_ufloat
},
684 { "bool", dt_type_bool
},
685 { "ip4addr", dt_type_ip4addr
},
686 { "ip6addr", dt_type_ip6addr
},
687 { "ipaddr", dt_type_ipaddr
},
688 { "cidr4", dt_type_cidr4
},
689 { "cidr6", dt_type_cidr6
},
690 { "cidr", dt_type_cidr
},
691 { "netmask4", dt_type_netmask4
},
692 { "netmask6", dt_type_netmask6
},
693 { "ipmask4", dt_type_ipmask4
},
694 { "ipmask6", dt_type_ipmask6
},
695 { "ipmask", dt_type_ipmask
},
696 { "port", dt_type_port
},
697 { "portrange", dt_type_portrange
},
698 { "macaddr", dt_type_macaddr
},
699 { "uciname", dt_type_uciname
},
700 { "wpakey", dt_type_wpakey
},
701 { "wepkey", dt_type_wepkey
},
702 { "hostname", dt_type_hostname
},
703 { "host", dt_type_host
},
704 { "network", dt_type_network
},
705 { "phonedigit", dt_type_phonedigit
},
706 { "directory", dt_type_directory
},
707 { "device", dt_type_device
},
708 { "file", dt_type_file
},
713 static struct dt_fun
*
714 dt_lookup_function(const char *s
, const char *e
)
716 struct dt_fun
*fun
= dt_types
;
720 if (!strncmp(fun
->name
, s
, e
- s
) && *(fun
->name
+ (e
- s
)) == '\0')
730 dt_parse_atom(struct dt_state
*s
, const char *label
, const char *end
)
737 struct dt_op
*op
= &s
->stack
[s
->depth
];
739 if ((s
->depth
+ 1) >= (sizeof(s
->stack
) / sizeof(s
->stack
[0])))
741 printf("Syntax error, expression too long\n");
745 while (isspace(*label
))
748 /* test whether label is a float */
749 dval
= strtod(label
, &e
);
754 op
->type
= OP_NUMBER
;
755 op
->value
.number
= dval
;
756 op
->nextop
= ++s
->depth
;
760 else if ((*label
== '"') || (*label
== '\''))
762 for (p
= label
+ 1, q
= *label
, esc
= false; p
<= end
; p
++)
777 op
->type
= OP_STRING
;
778 op
->length
= (p
- label
) - 2;
779 op
->value
.string
= label
+ 1;
780 op
->nextop
= ++s
->depth
;
786 printf("Syntax error, unterminated string\n");
792 p
<= end
&& ((*p
>= 'A' && *p
<= 'Z') ||
793 (*p
>= 'a' && *p
<= 'z') ||
794 (*p
>= '0' && *p
<= '9') ||
798 func
= dt_lookup_function(label
, p
);
802 printf("Syntax error, unrecognized function\n");
807 op
->type
= OP_FUNCTION
;
808 op
->value
.function
= func
;
809 op
->nextop
= ++s
->depth
;
814 printf("Syntax error, unexpected EOF\n");
819 dt_parse_list(struct dt_state
*s
, const char *code
, const char *end
);
822 dt_parse_expr(const char *code
, const char *end
, struct dt_state
*s
)
826 if (!dt_parse_atom(s
, code
, end
))
829 tok
= &s
->stack
[s
->depth
- 1];
831 while (isspace(*tok
->next
))
834 if (tok
->type
== OP_FUNCTION
)
836 if (*tok
->next
== '(')
840 while (isspace(*end
) && end
> tok
->next
+ 1)
843 return dt_parse_list(s
, tok
->next
+ 1, end
);
845 else if (tok
->next
== end
)
847 return dt_parse_list(s
, tok
->next
, tok
->next
);
850 printf("Syntax error, expected '(' or EOF after function label\n");
853 else if (tok
->next
== end
)
858 printf("Syntax error, expected ',' after literal\n");
863 dt_parse_list(struct dt_state
*s
, const char *code
, const char *end
)
868 const char *p
, *last
;
874 fptr
= &s
->stack
[s
->depth
- 1];
876 for (nest
= 0, p
= last
= code
, esc
= false, c
= *p
;
878 p
++, c
= (p
< end
) ? *p
: '\0')
906 if (!dt_parse_expr(last
, p
, s
))
919 fptr
->nextop
= s
->depth
;
924 dt_step(struct dt_state
*s
)
927 struct dt_op
*op
= &s
->stack
[s
->pos
];
932 rv
= op
->value
.boolean
;
936 rv
= dt_test_number(op
->value
.number
, s
->value
);
940 rv
= dt_test_string(op
->value
.string
, op
->value
.string
+ op
->length
, s
->value
);
957 dt_call(struct dt_state
*s
)
960 struct dt_op
*fptr
= &s
->stack
[s
->pos
];
961 struct dt_fun
*func
= fptr
->value
.function
;
965 rv
= func
->call(s
, fptr
->length
);
967 s
->pos
= fptr
->nextop
;
973 dt_parse(const char *code
, const char *value
)
975 struct dt_state s
= {
980 .value
.function
= &dt_types
[0],
986 if (!value
|| !*value
)
989 if (!dt_parse_list(&s
, code
, code
+ strlen(code
)))