예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
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;
}
예제 #5
0
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;
}
예제 #6
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;
}
예제 #7
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;
}