Ejemplo n.º 1
0
static int __noinline
npf_mk_code(prop_object_t obj, int type, void **code, size_t *csize,
    prop_dictionary_t errdict)
{
	const void *cptr;
	size_t clen;
	void *bc;

	if (type != NPF_CODE_BPF) {
		return ENOTSUP;
	}
	cptr = prop_data_data_nocopy(obj);
	if (cptr == NULL || (clen = prop_data_size(obj)) == 0) {
		NPF_ERR_DEBUG(errdict);
		return EINVAL;
	}
	if (!npf_bpf_validate(cptr, clen)) {
		NPF_ERR_DEBUG(errdict);
		return EINVAL;
	}
	bc = kmem_alloc(clen, KM_SLEEP);
	memcpy(bc, cptr, clen);

	*code = bc;
	*csize = clen;
	return 0;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 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;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
0
/*
 * npf_mk_connlist: import a list of connections and load them.
 */
static int __noinline
npf_mk_connlist(prop_array_t conlist, npf_ruleset_t *natlist,
    npf_conndb_t **conndb, prop_dictionary_t errdict)
{
	prop_dictionary_t condict;
	prop_object_iterator_t it;
	npf_conndb_t *cd;
	int error = 0;

	/* Connection list - array */
	if (prop_object_type(conlist) != PROP_TYPE_ARRAY) {
		NPF_ERR_DEBUG(errdict);
		return EINVAL;
	}

	/* Create a connection database. */
	cd = npf_conndb_create();
	it = prop_array_iterator(conlist);
	while ((condict = prop_object_iterator_next(it)) != NULL) {
		/* Connection - dictionary. */
		if (prop_object_type(condict) != PROP_TYPE_DICTIONARY) {
			NPF_ERR_DEBUG(errdict);
			error = EINVAL;
			break;
		}
		/* Construct and insert the connection. */
		error = npf_conn_import(cd, condict, natlist);
		if (error) {
			NPF_ERR_DEBUG(errdict);
			break;
		}
	}
	prop_object_iterator_release(it);
	if (error) {
		npf_conn_gc(cd, true, false);
		npf_conndb_destroy(cd);
	} else {
		*conndb = cd;
	}
	return error;
}
Ejemplo n.º 9
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;
}
Ejemplo n.º 10
0
static int __noinline
npf_mk_algs(prop_array_t alglist, prop_dictionary_t errdict)
{
	prop_object_iterator_t it;
	prop_dictionary_t nadict;
	int error = 0;

	it = prop_array_iterator(alglist);
	while ((nadict = prop_object_iterator_next(it)) != NULL) {
		if (npf_mk_singlealg(nadict) == NULL) {
			NPF_ERR_DEBUG(errdict);
			error = EINVAL;
			break;
		}
	}
	prop_object_iterator_release(it);
	return error;
}
Ejemplo n.º 11
0
static int __noinline
npf_mk_rprocs(npf_rprocset_t *rpset, prop_array_t rprocs,
    prop_dictionary_t errdict)
{
	prop_object_iterator_t it;
	prop_dictionary_t rpdict;
	int error = 0;

	it = prop_array_iterator(rprocs);
	while ((rpdict = prop_object_iterator_next(it)) != NULL) {
		npf_rproc_t *rp;

		if ((rp = npf_mk_singlerproc(rpdict)) == NULL) {
			NPF_ERR_DEBUG(errdict);
			error = EINVAL;
			break;
		}
		npf_rprocset_insert(rpset, rp);
	}
	prop_object_iterator_release(it);
	return error;
}
Ejemplo n.º 12
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;
}
Ejemplo n.º 13
0
static int __noinline
npf_mk_tables(npf_tableset_t *tblset, prop_array_t tables,
    prop_dictionary_t errdict)
{
	prop_object_iterator_t it;
	prop_dictionary_t tbldict;
	int error = 0;

	/* Tables - array. */
	if (prop_object_type(tables) != PROP_TYPE_ARRAY) {
		NPF_ERR_DEBUG(errdict);
		return EINVAL;
	}

	it = prop_array_iterator(tables);
	while ((tbldict = prop_object_iterator_next(it)) != NULL) {
		const char *name;
		npf_table_t *t;
		u_int tid;
		int type;

		/* Table - dictionary. */
		if (prop_object_type(tbldict) != PROP_TYPE_DICTIONARY) {
			NPF_ERR_DEBUG(errdict);
			error = EINVAL;
			break;
		}

		/* Table name, ID and type.  Validate them. */
		if (!prop_dictionary_get_cstring_nocopy(tbldict, "name", &name)) {
			NPF_ERR_DEBUG(errdict);
			error = EINVAL;
			break;
		}
		prop_dictionary_get_uint32(tbldict, "id", &tid);
		prop_dictionary_get_int32(tbldict, "type", &type);
		error = npf_table_check(tblset, name, tid, type);
		if (error) {
			NPF_ERR_DEBUG(errdict);
			break;
		}

		/* Get the entries or binary data. */
		prop_array_t ents = prop_dictionary_get(tbldict, "entries");
		prop_object_t obj = prop_dictionary_get(tbldict, "data");
		void *blob = prop_data_data(obj);
		size_t size = prop_data_size(obj);

		if (type == NPF_TABLE_CDB && (blob == NULL || size == 0)) {
			NPF_ERR_DEBUG(errdict);
			error = EINVAL;
			break;
		}
		if (type == NPF_TABLE_HASH) {
			size = 1024; /* XXX */
		}

		/* Create and insert the table. */
		t = npf_table_create(name, tid, type, blob, size);
		if (t == NULL) {
			NPF_ERR_DEBUG(errdict);
			error = ENOMEM;
			break;
		}
		error = npf_tableset_insert(tblset, t);
		KASSERT(error == 0);

		if (ents && (error = npf_mk_table_entries(t, ents)) != 0) {
			NPF_ERR_DEBUG(errdict);
			break;
		}
	}
	prop_object_iterator_release(it);
	/*
	 * Note: in a case of error, caller will free the tableset.
	 */
	return error;
}
Ejemplo n.º 14
0
static int __noinline
npf_mk_tables(npf_tableset_t *tblset, prop_array_t tables,
    prop_dictionary_t errdict)
{
	prop_object_iterator_t it;
	prop_dictionary_t tbldict;
	int error = 0;

	/* Tables - array. */
	if (prop_object_type(tables) != PROP_TYPE_ARRAY) {
		NPF_ERR_DEBUG(errdict);
		return EINVAL;
	}

	it = prop_array_iterator(tables);
	while ((tbldict = prop_object_iterator_next(it)) != NULL) {
		prop_dictionary_t ent;
		prop_object_iterator_t eit;
		prop_array_t entries;
		npf_table_t *t;
		u_int tid;
		int type;

		/* Table - dictionary. */
		if (prop_object_type(tbldict) != PROP_TYPE_DICTIONARY) {
			NPF_ERR_DEBUG(errdict);
			error = EINVAL;
			break;
		}

		/* Table ID and type. */
		prop_dictionary_get_uint32(tbldict, "id", &tid);
		prop_dictionary_get_int32(tbldict, "type", &type);

		/* Validate them, check for duplicate IDs. */
		error = npf_table_check(tblset, tid, type);
		if (error)
			break;

		/* Create and insert the table. */
		t = npf_table_create(tid, type, 1024);	/* XXX */
		if (t == NULL) {
			NPF_ERR_DEBUG(errdict);
			error = ENOMEM;
			break;
		}
		error = npf_tableset_insert(tblset, t);
		KASSERT(error == 0);

		/* Entries. */
		entries = prop_dictionary_get(tbldict, "entries");
		if (prop_object_type(entries) != PROP_TYPE_ARRAY) {
			NPF_ERR_DEBUG(errdict);
			error = EINVAL;
			break;
		}
		eit = prop_array_iterator(entries);
		while ((ent = prop_object_iterator_next(eit)) != NULL) {
			const npf_addr_t *addr;
			npf_netmask_t mask;
			int alen;

			/* Get address and mask.  Add a table entry. */
			prop_object_t obj = prop_dictionary_get(ent, "addr");
			addr = (const npf_addr_t *)prop_data_data_nocopy(obj);
			prop_dictionary_get_uint8(ent, "mask", &mask);
			alen = prop_data_size(obj);

			error = npf_table_insert(tblset, tid, alen, addr, mask);
			if (error)
				break;
		}
		prop_object_iterator_release(eit);
		if (error)
			break;
	}
	prop_object_iterator_release(it);
	/*
	 * Note: in a case of error, caller will free the tableset.
	 */
	return error;
}