static int __noinline npf_mk_rules(npf_ruleset_t *rlset, prop_array_t rules, npf_rprocset_t *rpset, prop_dictionary_t errdict) { prop_object_iterator_t it; prop_dictionary_t rldict; int error; if (prop_object_type(rules) != PROP_TYPE_ARRAY) { NPF_ERR_DEBUG(errdict); return EINVAL; } error = 0; it = prop_array_iterator(rules); while ((rldict = prop_object_iterator_next(it)) != NULL) { npf_rule_t *rl = NULL; /* Generate a single rule. */ error = npf_mk_singlerule(rldict, rpset, &rl, errdict); if (error) { break; } npf_ruleset_insert(rlset, rl); } prop_object_iterator_release(it); /* * Note: in a case of error, caller will free the ruleset. */ return error; }
int npfctl_remove_rule(u_long cmd, void *data) { struct plistref *pref = data; prop_dictionary_t dict, errdict; prop_object_t obj; const char *name; int error, numrules; /* Retrieve and construct the rule. */ error = prop_dictionary_copyin_ioctl(pref, cmd, &dict); if (error) { return error; } /* Dictionary for error reporting. */ errdict = prop_dictionary_create(); obj = prop_dictionary_get(dict, "name"); name = prop_string_cstring_nocopy(obj); npf_rule_t *rl; error = npf_mk_singlerule(dict, prop_array_create(), &rl, errdict); npf_core_enter(); numrules = npf_named_ruleset_remove(name, npf_core_ruleset(), rl); npf_core_exit(); prop_object_release(dict); /* Error report. */ prop_dictionary_set_int32(errdict, "errno", error); prop_dictionary_set_int32(errdict, "numrules", numrules); prop_dictionary_copyout_ioctl(pref, cmd, errdict); prop_object_release(errdict); return error; }
static int __noinline npf_mk_natlist(npf_ruleset_t *nset, prop_array_t natlist, prop_dictionary_t errdict) { prop_object_iterator_t it; prop_dictionary_t natdict; int error; /* NAT policies - array. */ if (prop_object_type(natlist) != PROP_TYPE_ARRAY) { NPF_ERR_DEBUG(errdict); return EINVAL; } error = 0; it = prop_array_iterator(natlist); while ((natdict = prop_object_iterator_next(it)) != NULL) { npf_rule_t *rl = NULL; npf_natpolicy_t *np; /* NAT policy - dictionary. */ if (prop_object_type(natdict) != PROP_TYPE_DICTIONARY) { NPF_ERR_DEBUG(errdict); error = EINVAL; break; } /* * NAT policies are standard rules, plus additional * information for translation. Make a rule. */ error = npf_mk_singlerule(natdict, NULL, &rl, errdict); if (error) { break; } npf_ruleset_insert(nset, rl); /* If rule is named, it is a group with NAT policies. */ if (prop_dictionary_get(natdict, "name") && prop_dictionary_get(natdict, "subrules")) { continue; } /* Allocate a new NAT policy and assign to the rule. */ np = npf_nat_newpolicy(natdict, nset); if (np == NULL) { NPF_ERR_DEBUG(errdict); error = ENOMEM; break; } npf_rule_setnat(rl, np); } prop_object_iterator_release(it); /* * Note: in a case of error, caller will free entire NAT ruleset * with assigned NAT policies. */ return error; }
static int __noinline npf_mk_rules(npf_ruleset_t *rlset, prop_array_t rules, prop_array_t rprocs, prop_dictionary_t errdict) { prop_object_iterator_t it; prop_dictionary_t rldict, rpdict; int error; /* Rule procedures and the ruleset - arrays. */ if (prop_object_type(rprocs) != PROP_TYPE_ARRAY || prop_object_type(rules) != PROP_TYPE_ARRAY) { NPF_ERR_DEBUG(errdict); return EINVAL; } it = prop_array_iterator(rprocs); while ((rpdict = prop_object_iterator_next(it)) != NULL) { if (prop_dictionary_get(rpdict, "rproc-ptr")) { prop_object_iterator_release(it); NPF_ERR_DEBUG(errdict); return EINVAL; } } prop_object_iterator_release(it); error = 0; it = prop_array_iterator(rules); while ((rldict = prop_object_iterator_next(it)) != NULL) { prop_array_t subrules; npf_ruleset_t *rlsetsub; npf_rule_t *rl; /* Generate a single rule. */ error = npf_mk_singlerule(rldict, rprocs, &rl, errdict); if (error) { break; } npf_ruleset_insert(rlset, rl); /* Check for sub-rules and generate, if any. */ subrules = prop_dictionary_get(rldict, "subrules"); if (subrules == NULL) { /* No subrules, next.. */ continue; } rlsetsub = npf_rule_subset(rl); error = npf_mk_subrules(rlsetsub, subrules, rprocs, errdict); if (error) break; } prop_object_iterator_release(it); /* * Note: in a case of error, caller will free the ruleset. */ return error; }
static int npf_insert_nat_rule(prop_dictionary_t natdict, prop_dictionary_t errdict) { int error; npf_natpolicy_t *np; npf_rule_t *rl; printf("npf_insert_nat_rule\n"); if (prop_object_type(natdict) != PROP_TYPE_DICTIONARY) { printf("rossz tipus!\n"); NPF_ERR_DEBUG(errdict); return EINVAL; } /* * NAT policies are standard rules, plus additional * information for translation. Make a rule. */ error = npf_mk_singlerule(natdict, NULL, &rl, errdict); if (error) { printf("hiba a mksinglerule alatt\n"); return error; } npf_core_enter(); printf("most ruleset inserteljuk\n"); npf_ruleset_insert(npf_core_natset(), rl); /* Allocate a new NAT policy and assign to the rule. */ np = npf_nat_newpolicy(natdict, npf_core_natset()); if (np == NULL) { printf("hiba a newpolicy alatt\n"); NPF_ERR_DEBUG(errdict); return ENOMEM; } npf_rule_setnat(rl, np); npf_core_exit(); return 0; }
static int __noinline npf_mk_subrules(npf_ruleset_t *rlset, prop_array_t rules, prop_array_t rprocs, prop_dictionary_t errdict) { prop_object_iterator_t it; prop_dictionary_t rldict; int error = 0; if (prop_object_type(rules) != PROP_TYPE_ARRAY) { NPF_ERR_DEBUG(errdict); return EINVAL; } it = prop_array_iterator(rules); while ((rldict = prop_object_iterator_next(it)) != NULL) { npf_rule_t *rl; error = npf_mk_singlerule(rldict, rprocs, &rl, errdict); if (error) { break; } npf_ruleset_insert(rlset, rl); } prop_object_iterator_release(it); return error; }
/* * npfctl_rule: add or remove dynamic rules in the specified ruleset. */ int npfctl_rule(u_long cmd, void *data) { struct plistref *pref = data; prop_dictionary_t npf_rule, retdict = NULL; npf_ruleset_t *rlset; npf_rule_t *rl = NULL; const char *ruleset_name; uint32_t rcmd = 0; int error; error = prop_dictionary_copyin_ioctl(pref, cmd, &npf_rule); if (error) { return error; } prop_dictionary_get_uint32(npf_rule, "command", &rcmd); if (!prop_dictionary_get_cstring_nocopy(npf_rule, "ruleset-name", &ruleset_name)) { error = EINVAL; goto out; } if (rcmd == NPF_CMD_RULE_ADD) { retdict = prop_dictionary_create(); if (npf_mk_singlerule(npf_rule, NULL, &rl, retdict) != 0) { error = EINVAL; goto out; } } npf_config_enter(); rlset = npf_config_ruleset(); switch (rcmd) { case NPF_CMD_RULE_ADD: { if ((error = npf_ruleset_add(rlset, ruleset_name, rl)) == 0) { /* Success. */ uint64_t id = npf_rule_getid(rl); prop_dictionary_set_uint64(retdict, "id", id); rl = NULL; } break; } case NPF_CMD_RULE_REMOVE: { uint64_t id; if (!prop_dictionary_get_uint64(npf_rule, "id", &id)) { error = EINVAL; break; } error = npf_ruleset_remove(rlset, ruleset_name, id); break; } case NPF_CMD_RULE_REMKEY: { prop_object_t obj = prop_dictionary_get(npf_rule, "key"); const void *key = prop_data_data_nocopy(obj); size_t len = prop_data_size(obj); if (len == 0 || len > NPF_RULE_MAXKEYLEN) { error = EINVAL; break; } error = npf_ruleset_remkey(rlset, ruleset_name, key, len); break; } case NPF_CMD_RULE_LIST: { retdict = npf_ruleset_list(rlset, ruleset_name); if (!retdict) { error = ESRCH; } break; } case NPF_CMD_RULE_FLUSH: { error = npf_ruleset_flush(rlset, ruleset_name); break; } default: error = EINVAL; break; } /* Destroy any removed rules. */ if (!error && rcmd != NPF_CMD_RULE_ADD && rcmd != NPF_CMD_RULE_LIST) { npf_config_sync(); npf_ruleset_gc(rlset); } npf_config_exit(); if (rl) { KASSERT(error); npf_rule_free(rl); } out: if (retdict) { prop_object_release(npf_rule); prop_dictionary_copyout_ioctl(pref, cmd, retdict); prop_object_release(retdict); } return error; }