Пример #1
0
__dso_public void
npf_ifmap_detach(npf_t *npf, ifnet_t *ifp)
{
	/* Diagnostic. */
	npf_config_enter(npf);
	npf->ifops->setmeta(ifp, (void *)(uintptr_t)0);
	npf_config_exit(npf);
}
Пример #2
0
__dso_public void
npf_ifmap_attach(npf_t *npf, ifnet_t *ifp)
{
	const npf_ifops_t *ifops = npf->ifops;
	u_int i;

	npf_config_enter(npf);
	i = npf_ifmap_lookup(npf, ifops->getname(ifp));
	ifops->setmeta(ifp, (void *)(uintptr_t)i);
	npf_config_exit(npf);
}
Пример #3
0
u_int
npf_ifmap_register(npf_t *npf, const char *ifname)
{
	npf_ifmap_t *nim;
	ifnet_t *ifp;
	u_int i;

	npf_config_enter(npf);
	if ((i = npf_ifmap_lookup(npf, ifname)) != 0) {
		goto out;
	}
	if ((i = npf_ifmap_new(npf)) == 0) {
		goto out;
	}
	nim = &npf->ifmap[i - 1];
	strlcpy(nim->n_ifname, ifname, IFNAMSIZ);

	if ((ifp = npf->ifops->lookup(ifname)) != NULL) {
		npf->ifops->setmeta(ifp, (void *)(uintptr_t)i);
	}
out:
	npf_config_exit(npf);
	return i;
}
Пример #4
0
/*
 * 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;
}
Пример #5
0
/*
 * npfctl_save: export the config dictionary as it was submitted,
 * including the current snapshot of the connections.  Additionally,
 * indicate whether the ruleset is currently active.
 */
int
npfctl_save(u_long cmd, void *data)
{
	struct plistref *pref = data;
	prop_array_t rulelist, natlist, tables, rprocs, conlist;
	prop_dictionary_t npf_dict = NULL;
	int error;

	rulelist = prop_array_create();
	natlist = prop_array_create();
	tables = prop_array_create();
	rprocs = prop_array_create();
	conlist = prop_array_create();

	/*
	 * Serialise the connections and NAT policies.
	 */
	npf_config_enter();
	error = npf_conndb_export(conlist);
	if (error) {
		goto out;
	}
	error = npf_ruleset_export(npf_config_ruleset(), rulelist);
	if (error) {
		goto out;
	}
	error = npf_ruleset_export(npf_config_natset(), natlist);
	if (error) {
		goto out;
	}
	error = npf_tableset_export(npf_config_tableset(), tables);
	if (error) {
		goto out;
	}
	error = npf_rprocset_export(npf_config_rprocs(), rprocs);
	if (error) {
		goto out;
	}
	prop_array_t alglist = npf_alg_export();

	npf_dict = prop_dictionary_create();
	prop_dictionary_set_uint32(npf_dict, "version", NPF_VERSION);
	prop_dictionary_set_and_rel(npf_dict, "algs", alglist);
	prop_dictionary_set_and_rel(npf_dict, "rules", rulelist);
	prop_dictionary_set_and_rel(npf_dict, "nat", natlist);
	prop_dictionary_set_and_rel(npf_dict, "tables", tables);
	prop_dictionary_set_and_rel(npf_dict, "rprocs", rprocs);
	prop_dictionary_set_and_rel(npf_dict, "conn-list", conlist);
	prop_dictionary_set_bool(npf_dict, "active", npf_pfil_registered_p());
	error = prop_dictionary_copyout_ioctl(pref, cmd, npf_dict);
out:
	npf_config_exit();

	if (!npf_dict) {
		prop_object_release(rulelist);
		prop_object_release(natlist);
		prop_object_release(tables);
		prop_object_release(rprocs);
		prop_object_release(conlist);
	} else {
		prop_object_release(npf_dict);
	}
	return error;
}