static void build_ncode(nl_rule_t *rl, unsigned short eport) { void *code; size_t len; int pflag = NC_MATCH_TCP | NC_MATCH_UDP; int srcflag = NC_MATCH_SRC; int dstflag = NC_MATCH_DST; nc_ctx_t *nc = npfctl_ncgen_create(); // npfctl_ncgen_group(nc); npf_addr_t realaddr; memset(&realaddr, 0, sizeof(npf_addr_t)); in_addr_t addr = inet_addr("192.168.0.40"); memcpy(&realaddr, &addr, sizeof(in_addr_t)); npfctl_gennc_v4cidr(nc, dstflag, &realaddr, 255); npfctl_ncgen_endgroup(nc); npfctl_ncgen_group(nc); in_port_t port = 0; memset(&port, 0, sizeof(in_port_t)); port = htons(eport); npfctl_gennc_ports(nc, (dstflag | pflag) & ~NC_MATCH_UDP, port, port); npfctl_gennc_ports(nc, (dstflag | pflag) & ~NC_MATCH_TCP, port, port); npfctl_ncgen_endgroup(nc); code = npfctl_ncgen_complete(nc, &len); printf("len: %d\n", len); npf_rule_setcode(rl, NPF_CODE_NCODE, code, len); free(code); }
static int __noinline npf_mk_singlerule(prop_dictionary_t rldict, npf_rprocset_t *rpset, npf_rule_t **rlret, prop_dictionary_t errdict) { npf_rule_t *rl; const char *rname; prop_object_t obj; int p, error = 0; /* Rule - dictionary. */ if (prop_object_type(rldict) != PROP_TYPE_DICTIONARY) { NPF_ERR_DEBUG(errdict); return EINVAL; } if ((rl = npf_rule_alloc(rldict)) == NULL) { NPF_ERR_DEBUG(errdict); return EINVAL; } /* Assign rule procedure, if any. */ if (prop_dictionary_get_cstring_nocopy(rldict, "rproc", &rname)) { npf_rproc_t *rp; if (rpset == NULL) { error = EINVAL; goto err; } if ((rp = npf_rprocset_lookup(rpset, rname)) == NULL) { NPF_ERR_DEBUG(errdict); error = EINVAL; goto err; } npf_rule_setrproc(rl, rp); } /* Filter code (binary data). */ if ((obj = prop_dictionary_get(rldict, "code")) != NULL) { int type; size_t len; void *code; prop_dictionary_get_int32(rldict, "code-type", &type); error = npf_mk_code(obj, type, &code, &len, errdict); if (error) { goto err; } npf_rule_setcode(rl, type, code, len); } *rlret = rl; return 0; err: npf_rule_free(rl); prop_dictionary_get_int32(rldict, "prio", &p); /* XXX */ prop_dictionary_set_int32(errdict, "id", p); return error; }
static bool npfctl_build_ncode(nl_rule_t *rl, sa_family_t family, const opt_proto_t *op, const filt_opts_t *fopts, bool invert) { const addr_port_t *apfrom = &fopts->fo_from; const addr_port_t *apto = &fopts->fo_to; const int proto = op->op_proto; bool nof, nop; nc_ctx_t *nc; void *code; size_t len; /* * If none specified, no n-code. */ nof = !apfrom->ap_netaddr && !apto->ap_netaddr; nop = !apfrom->ap_portrange && !apto->ap_portrange; if (family == AF_UNSPEC && proto == -1 && !op->op_opts && nof && nop) return false; int srcflag = NC_MATCH_SRC; int dstflag = NC_MATCH_DST; if (invert) { printf("invert!\n"); srcflag = NC_MATCH_DST; dstflag = NC_MATCH_SRC; } nc = npfctl_ncgen_create(); /* Build layer 4 protocol blocks. */ printf("build?\n"); int pflag = npfctl_build_proto(nc, family, op, nof, nop); /* Build IP address blocks. */ printf("from\n"); npfctl_build_vars(nc, family, apfrom->ap_netaddr, srcflag); printf("to\n"); npfctl_build_vars(nc, family, apto->ap_netaddr, dstflag); /* Build port-range blocks. */ printf("fromrange\n"); npfctl_build_vars(nc, family, apfrom->ap_portrange, srcflag | pflag); printf("torange\n"); npfctl_build_vars(nc, family, apto->ap_portrange, dstflag | pflag); /* * Complete n-code (destroys the context) and pass to the rule. */ code = npfctl_ncgen_complete(nc, &len); if (npf_debug) { printf("len: %d\n", len); extern int yylineno; printf("RULE AT LINE %d\n", yylineno); npfctl_ncgen_print(code, len); } assert(code && len > 0); if (npf_rule_setcode(rl, NPF_CODE_NCODE, code, len) == -1) { errx(EXIT_FAILURE, "npf_rule_setcode failed"); } free(code); return true; }