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_ncode(prop_object_t obj, void **code, size_t *csize, prop_dictionary_t errdict) { const void *ncptr; int nc_err, errat; size_t nc_size; void *nc; /* * Allocate, copy and validate n-code. XXX: Inefficient. */ ncptr = prop_data_data_nocopy(obj); nc_size = prop_data_size(obj); if (ncptr == NULL || nc_size > NPF_NCODE_LIMIT) { NPF_ERR_DEBUG(errdict); return ERANGE; } nc = npf_ncode_alloc(nc_size); if (nc == NULL) { NPF_ERR_DEBUG(errdict); return ENOMEM; } memcpy(nc, ncptr, nc_size); nc_err = npf_ncode_validate(nc, nc_size, &errat); if (nc_err) { npf_ncode_free(nc, nc_size); prop_dictionary_set_int32(errdict, "ncode-error", nc_err); prop_dictionary_set_int32(errdict, "ncode-errat", errat); return EINVAL; } *code = nc; *csize = nc_size; return 0; }
nl_table_t * npf_table_create(const char *name, u_int id, int type) { prop_dictionary_t tldict; prop_array_t tblents; nl_table_t *tl; tl = malloc(sizeof(*tl)); if (tl == NULL) { return NULL; } tldict = prop_dictionary_create(); if (tldict == NULL) { free(tl); return NULL; } prop_dictionary_set_cstring(tldict, "name", name); prop_dictionary_set_uint32(tldict, "id", id); prop_dictionary_set_int32(tldict, "type", type); tblents = prop_array_create(); if (tblents == NULL) { prop_object_release(tldict); free(tl); return NULL; } prop_dictionary_set(tldict, "entries", tblents); prop_object_release(tblents); tl->ntl_dict = tldict; return tl; }
int testcase_set_signal(prop_dictionary_t testcase, int sig) { prop_dictionary_t dict = testcase_get_result_dict(testcase); return !prop_dictionary_set_int32(dict, "signal", sig); }
int testcase_set_exit_value(prop_dictionary_t testcase, int exitval) { prop_dictionary_t dict = testcase_get_result_dict(testcase); return !prop_dictionary_set_int32(dict, "exit_value", exitval); }
int testcase_set_result(prop_dictionary_t testcase, int result) { prop_dictionary_t dict = testcase_get_result_dict(testcase); return !prop_dictionary_set_int32(dict, "result", result); }
int npf_rule_setprio(nl_rule_t *rl, pri_t pri) { prop_dictionary_t rldict = rl->nrl_dict; prop_dictionary_set_int32(rldict, "priority", pri); return 0; }
int npf_nat_insert(nl_config_t *ncf, nl_nat_t *nt, pri_t pri __unused) { prop_dictionary_t rldict = nt->nrl_dict; prop_dictionary_set_int32(rldict, "priority", NPF_PRI_LAST); prop_array_add(ncf->ncf_nat_list, rldict); return 0; }
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 int __noinline npf_mk_singlerule(prop_dictionary_t rldict, prop_array_t rps, npf_rule_t **rl, prop_dictionary_t errdict) { const char *rnm; npf_rproc_t *rp; prop_object_t obj; size_t nc_size; void *nc; int p, error; /* Rule - dictionary. */ if (prop_object_type(rldict) != PROP_TYPE_DICTIONARY) { NPF_ERR_DEBUG(errdict); return EINVAL; } error = 0; obj = prop_dictionary_get(rldict, "ncode"); if (obj) { /* N-code (binary data). */ error = npf_mk_ncode(obj, &nc, &nc_size, errdict); if (error) { goto err; } } else { /* No n-code. */ nc = NULL; nc_size = 0; } /* Check for rule procedure. */ if (rps && prop_dictionary_get_cstring_nocopy(rldict, "rproc", &rnm)) { rp = npf_mk_rproc(rps, rnm); if (rp == NULL) { if (nc) { npf_ncode_free(nc, nc_size); /* XXX */ } NPF_ERR_DEBUG(errdict); error = EINVAL; goto err; } } else { rp = NULL; } /* Finally, allocate and return the rule. */ *rl = npf_rule_alloc(rldict, rp, nc, nc_size); KASSERT(*rl != NULL); return 0; err: prop_dictionary_get_int32(rldict, "priority", &p); /* XXX */ prop_dictionary_set_int32(errdict, "id", p); return error; }
void wsdv_keymap_save_default(void) { int32_t v; char key[MAX_KEY_SIZE]; char val[MAX_VAL_SIZE]; pd = prop_dictionary_create(); snprintf(key, MAX_KEY_SIZE-1, "%d", 0x29); //snprintf(val, MAX_VAL_SIZE-1, "%d", 0x29); prop_dictionary_set_int32(pd, key, 0x29); prop_dictionary_externalize_to_file(pd, "map1.plist"); }
nl_nat_t * npf_nat_create(int type, u_int flags, const char *ifname, int af, npf_addr_t *addr, npf_netmask_t mask, in_port_t port) { nl_rule_t *rl; prop_dictionary_t rldict; prop_data_t addrdat; uint32_t attr; size_t sz; if (af == AF_INET) { sz = sizeof(struct in_addr); } else if (af == AF_INET6) { sz = sizeof(struct in6_addr); } else { return NULL; } attr = NPF_RULE_PASS | NPF_RULE_FINAL | (type == NPF_NATOUT ? NPF_RULE_OUT : NPF_RULE_IN); /* Create a rule for NAT policy. Next, will add translation data. */ rl = npf_rule_create(NULL, attr, ifname); if (rl == NULL) { return NULL; } rldict = rl->nrl_dict; /* Translation type and flags. */ prop_dictionary_set_int32(rldict, "type", type); prop_dictionary_set_uint32(rldict, "flags", flags); /* Translation IP and mask. */ addrdat = prop_data_create_data(addr, sz); if (addrdat == NULL) { npf_rule_destroy(rl); return NULL; } prop_dictionary_set(rldict, "translation-ip", addrdat); prop_dictionary_set_uint32(rldict, "translation-mask", mask); prop_object_release(addrdat); /* Translation port (for redirect case). */ prop_dictionary_set_uint16(rldict, "translation-port", port); return (nl_nat_t *)rl; }
/* * npfctl_update_rule: reload a specific rule identified by the name. */ int npfctl_update_rule(u_long cmd, void *data) { struct plistref *pref = data; prop_dictionary_t dict, errdict; prop_array_t subrules; prop_object_t obj; npf_ruleset_t *rlset; const char *name; int error; /* 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(); /* Create the ruleset and construct sub-rules. */ rlset = npf_ruleset_create(); subrules = prop_dictionary_get(dict, "subrules"); error = npf_mk_subrules(rlset, subrules, NULL, errdict); if (error) { goto out; } /* Lookup the rule by name, and replace its subset (sub-rules). */ obj = prop_dictionary_get(dict, "name"); name = prop_string_cstring_nocopy(obj); if (npf_ruleset_replace(name, rlset) == NULL) { /* Not found. */ error = ENOENT; out: /* Error path. */ npf_ruleset_destroy(rlset); } prop_object_release(dict); /* Error report. */ prop_dictionary_set_int32(errdict, "errno", error); prop_dictionary_copyout_ioctl(pref, cmd, errdict); prop_object_release(errdict); return error; }
/* * Get description of all tables loaded to device from kernel * and send it to libdevmapper. * * Output dictionary for every table: * * <key>cmd_data</key> * <array> * <dict> * <key>type<key> * <string>...</string> * * <key>start</key> * <integer>...</integer> * * <key>length</key> * <integer>...</integer> * * <key>params</key> * <string>...</string> * </dict> * </array> * */ int dm_table_status_ioctl(prop_dictionary_t dm_dict) { dm_dev_t *dmv; dm_table_t *tbl; dm_table_entry_t *table_en; prop_array_t cmd_array; prop_dictionary_t target_dict; uint32_t rec_size, minor; const char *name, *uuid; char *params; int flags; int table_type; dmv = NULL; uuid = NULL; name = NULL; params = NULL; flags = 0; rec_size = 0; prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME, &name); prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID, &uuid); prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags); prop_dictionary_get_uint32(dm_dict, DM_IOCTL_MINOR, &minor); cmd_array = prop_array_create(); if ((dmv = dm_dev_lookup(name, uuid, minor)) == NULL) { DM_REMOVE_FLAG(flags, DM_EXISTS_FLAG); return ENOENT; } /* * if DM_QUERY_INACTIVE_TABLE_FLAG is passed we need to query * INACTIVE TABLE */ if (flags & DM_QUERY_INACTIVE_TABLE_FLAG) table_type = DM_TABLE_INACTIVE; else table_type = DM_TABLE_ACTIVE; if (dm_table_get_target_count(&dmv->table_head, DM_TABLE_ACTIVE)) DM_ADD_FLAG(flags, DM_ACTIVE_PRESENT_FLAG); else { DM_REMOVE_FLAG(flags, DM_ACTIVE_PRESENT_FLAG); if (dm_table_get_target_count(&dmv->table_head, DM_TABLE_INACTIVE)) DM_ADD_FLAG(flags, DM_INACTIVE_PRESENT_FLAG); else { DM_REMOVE_FLAG(flags, DM_INACTIVE_PRESENT_FLAG); } } if (dmv->flags & DM_SUSPEND_FLAG) DM_ADD_FLAG(flags, DM_SUSPEND_FLAG); prop_dictionary_set_uint32(dm_dict, DM_IOCTL_MINOR, dmv->minor); aprint_debug("Status of device tables: %s--%d\n", name, dmv->table_head.cur_active_table); tbl = dm_table_get_entry(&dmv->table_head, table_type); SLIST_FOREACH(table_en, tbl, next) { target_dict = prop_dictionary_create(); aprint_debug("%016" PRIu64 ", length %016" PRIu64 ", target %s\n", table_en->start, table_en->length, table_en->target->name); prop_dictionary_set_uint64(target_dict, DM_TABLE_START, table_en->start); prop_dictionary_set_uint64(target_dict, DM_TABLE_LENGTH, table_en->length); prop_dictionary_set_cstring(target_dict, DM_TABLE_TYPE, table_en->target->name); /* dm_table_get_cur_actv.table ?? */ prop_dictionary_set_int32(target_dict, DM_TABLE_STAT, dmv->table_head.cur_active_table); if (flags & DM_STATUS_TABLE_FLAG) { params = table_en->target->status (table_en->target_config); if (params != NULL) { prop_dictionary_set_cstring(target_dict, DM_TABLE_PARAMS, params); kfree(params, M_DM); } } prop_array_add(cmd_array, target_dict); prop_object_release(target_dict); }
/* * npfctl_reload: store passed data i.e. update settings, create passed * tables, rules and atomically activate all them. */ int npfctl_reload(u_long cmd, void *data) { struct plistref *pref = data; prop_dictionary_t npf_dict, errdict; prop_array_t natlist, tables, rprocs, rules; npf_tableset_t *tblset = NULL; npf_ruleset_t *rlset = NULL; npf_ruleset_t *nset = NULL; bool flush; int error; /* Retrieve the dictionary. */ #ifndef _NPF_TESTING error = prop_dictionary_copyin_ioctl(pref, cmd, &npf_dict); if (error) return error; #else npf_dict = (prop_dictionary_t)pref; #endif /* Dictionary for error reporting. */ errdict = prop_dictionary_create(); /* NAT policies. */ nset = npf_ruleset_create(); natlist = prop_dictionary_get(npf_dict, "translation"); error = npf_mk_natlist(nset, natlist, errdict); if (error) { goto fail; } /* Tables. */ tblset = npf_tableset_create(); tables = prop_dictionary_get(npf_dict, "tables"); error = npf_mk_tables(tblset, tables, errdict); if (error) { goto fail; } /* Rules and rule procedures. */ rlset = npf_ruleset_create(); rprocs = prop_dictionary_get(npf_dict, "rprocs"); rules = prop_dictionary_get(npf_dict, "rules"); error = npf_mk_rules(rlset, rules, rprocs, errdict); if (error) { goto fail; } flush = false; prop_dictionary_get_bool(npf_dict, "flush", &flush); /* * Finally - reload ruleset, tableset and NAT policies. * Operation will be performed as a single transaction. */ npf_reload(npf_dict, rlset, tblset, nset, flush); /* Turn on/off session tracking accordingly. */ npf_session_tracking(!flush); /* Done. Since data is consumed now, we shall not destroy it. */ tblset = NULL; rlset = NULL; nset = NULL; fail: /* * Note: destroy rulesets first, to drop references to the tableset. */ KASSERT(error == 0 || (nset || rlset || tblset)); if (nset) { npf_ruleset_destroy(nset); } if (rlset) { npf_ruleset_destroy(rlset); } if (tblset) { npf_tableset_destroy(tblset); } if (error) { prop_object_release(npf_dict); } /* Error report. */ prop_dictionary_set_int32(errdict, "errno", error); #ifndef _NPF_TESTING prop_dictionary_copyout_ioctl(pref, cmd, errdict); #endif prop_object_release(errdict); return 0; }
/* * npfctl_load: store passed data i.e. update settings, create passed * tables, rules and atomically activate all them. */ int npfctl_load(u_long cmd, void *data) { struct plistref *pref = data; prop_dictionary_t npf_dict, errdict; prop_array_t alglist, natlist, tables, rprocs, rules, conlist; npf_tableset_t *tblset = NULL; npf_rprocset_t *rpset = NULL; npf_ruleset_t *rlset = NULL; npf_ruleset_t *nset = NULL; npf_conndb_t *conndb = NULL; uint32_t ver = 0; size_t nitems; bool flush; int error; /* Retrieve the dictionary. */ #ifndef _NPF_TESTING error = prop_dictionary_copyin_ioctl(pref, cmd, &npf_dict); if (error) return error; #else npf_dict = (prop_dictionary_t)pref; #endif /* Dictionary for error reporting and version check. */ errdict = prop_dictionary_create(); prop_dictionary_get_uint32(npf_dict, "version", &ver); if (ver != NPF_VERSION) { error = EPROGMISMATCH; goto fail; } /* ALGs. */ alglist = prop_dictionary_get(npf_dict, "algs"); error = npf_mk_algs(alglist, errdict); if (error) { goto fail; } /* NAT policies. */ natlist = prop_dictionary_get(npf_dict, "nat"); if ((nitems = prop_array_count(natlist)) > NPF_MAX_RULES) { error = E2BIG; goto fail; } nset = npf_ruleset_create(nitems); error = npf_mk_natlist(nset, natlist, errdict); if (error) { goto fail; } /* Tables. */ tables = prop_dictionary_get(npf_dict, "tables"); if ((nitems = prop_array_count(tables)) > NPF_MAX_TABLES) { error = E2BIG; goto fail; } tblset = npf_tableset_create(nitems); error = npf_mk_tables(tblset, tables, errdict); if (error) { goto fail; } /* Rule procedures. */ rprocs = prop_dictionary_get(npf_dict, "rprocs"); if ((nitems = prop_array_count(rprocs)) > NPF_MAX_RPROCS) { error = E2BIG; goto fail; } rpset = npf_rprocset_create(); error = npf_mk_rprocs(rpset, rprocs, errdict); if (error) { goto fail; } /* Rules. */ rules = prop_dictionary_get(npf_dict, "rules"); if ((nitems = prop_array_count(rules)) > NPF_MAX_RULES) { error = E2BIG; goto fail; } rlset = npf_ruleset_create(nitems); error = npf_mk_rules(rlset, rules, rpset, errdict); if (error) { goto fail; } /* Connections (if loading any). */ if ((conlist = prop_dictionary_get(npf_dict, "conn-list")) != NULL) { error = npf_mk_connlist(conlist, nset, &conndb, errdict); if (error) { goto fail; } } flush = false; prop_dictionary_get_bool(npf_dict, "flush", &flush); /* * Finally - perform the load. */ npf_config_load(rlset, tblset, nset, rpset, conndb, flush); /* Done. Since data is consumed now, we shall not destroy it. */ tblset = NULL; rpset = NULL; rlset = NULL; nset = NULL; fail: /* * Note: destroy rulesets first, to drop references to the tableset. */ KASSERT(error == 0 || (nset || rpset || rlset || tblset)); if (nset) { npf_ruleset_destroy(nset); } if (rlset) { npf_ruleset_destroy(rlset); } if (rpset) { npf_rprocset_destroy(rpset); } if (tblset) { npf_tableset_destroy(tblset); } prop_object_release(npf_dict); /* Error report. */ #ifndef _NPF_TESTING prop_dictionary_set_int32(errdict, "errno", error); prop_dictionary_copyout_ioctl(pref, cmd, errdict); prop_object_release(errdict); error = 0; #endif return error; }
prop_dictionary_t testcase_from_struct(struct testcase *testcase) { int i, r; prop_dictionary_t dict, testcase_dict; prop_array_t a; char *s; testcase_dict = prop_dictionary_create(); if (testcase_dict == NULL) err(1, "could not create testcase dict"); r = prop_dictionary_set_cstring(testcase_dict, "name", testcase->name); if (r == 0) err(1, "prop_dictionary operation failed"); r = prop_dictionary_set_cstring(testcase_dict, "type", testcase->type_str); if (r == 0) err(1, "prop_dictionary operation failed"); a = prop_array_create_with_capacity(testcase->argc+1); if (a == NULL) err(1, "prop_array_create for argv failed"); s = strrchr(testcase->name, '/'); r = prop_array_set_cstring(a, 0, (s == NULL) ? testcase->name : s+1); if (r == 0) err(1, "prop_array_set_cstring operation failed"); for (i = 1; i <= testcase->argc; i++) { r = prop_array_set_cstring(a, i, testcase->argv[i-1]); if (r == 0) err(1, "prop_array_set_cstring operation failed"); } r = prop_dictionary_set(testcase_dict, "args", a); if (r == 0) err(1, "prop_dictionary_set \"args\" failed"); dict = prop_dictionary_create(); if (dict == NULL) err(1, "could not create dict"); r = prop_dictionary_set_int32(dict, "timeout_in_secs", (int32_t)testcase->opts.timeout_in_secs); if (r == 0) err(1, "prop_dictionary operation failed"); r = prop_dictionary_set_uint32(dict, "flags", testcase->opts.flags); if (r == 0) err(1, "prop_dictionary operation failed"); if (testcase->opts.pre_cmd != NULL) { r = prop_dictionary_set_cstring(dict, "pre_cmd", testcase->opts.pre_cmd); if (r == 0) err(1, "prop_dictionary operation failed"); } if (testcase->opts.post_cmd != NULL) { r = prop_dictionary_set_cstring(dict, "post_cmd", testcase->opts.post_cmd); if (r == 0) err(1, "prop_dictionary operation failed"); } r = prop_dictionary_set_uint32(dict, "runas_uid", (uint32_t)testcase->opts.runas_uid); if (r == 0) err(1, "prop_dictionary operation failed"); r = prop_dictionary_set_cstring(dict, "make_cmd", (testcase->opts.make_cmd != NULL) ? testcase->opts.make_cmd : "make"); if (r == 0) err(1, "prop_dictionary operation failed"); r = prop_dictionary_set(testcase_dict, "opts", dict); if (r == 0) err(1, "prop_dictionary operation failed"); return testcase_dict; }