static void bpf_parse(struct xt_option_call *cb) { xtables_option_parse(cb); switch (cb->entry->id) { case O_BCODE_STDIN: bpf_parse_string(cb, cb->arg, ','); break; default: xtables_error(PARAMETER_PROBLEM, "bpf: unknown option"); } }
int bpf_parse_ops(int argc, char **argv, struct sock_filter *bpf_ops, bool from_file) { char *bpf_string, *token, separator = ','; int ret = 0, i = 0; bool need_release; __u16 bpf_len = 0; if (argc < 1) return -EINVAL; if (bpf_parse_string(argv[0], from_file, &bpf_len, &bpf_string, &need_release, separator)) return -EINVAL; if (bpf_len == 0 || bpf_len > BPF_MAXINSNS) { ret = -EINVAL; goto out; } token = bpf_string; while ((token = strchr(token, separator)) && (++token)[0]) { if (i >= bpf_len) { fprintf(stderr, "Real program length exceeds encoded " "length parameter!\n"); ret = -EINVAL; goto out; } if (sscanf(token, "%hu %hhu %hhu %u,", &bpf_ops[i].code, &bpf_ops[i].jt, &bpf_ops[i].jf, &bpf_ops[i].k) != 4) { fprintf(stderr, "Error at instruction %d!\n", i); ret = -EINVAL; goto out; } i++; } if (i != bpf_len) { fprintf(stderr, "Parsed program length is less than encoded" "length parameter!\n"); ret = -EINVAL; goto out; } ret = bpf_len; out: if (need_release) free(bpf_string); return ret; }