Beispiel #1
0
static int __noinline
npf_mk_table_entries(npf_table_t *t, prop_array_t entries)
{
	prop_object_iterator_t eit;
	prop_dictionary_t ent;
	int error = 0;

	if (prop_object_type(entries) != PROP_TYPE_ARRAY) {
		return EINVAL;
	}
	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(t, alen, addr, mask);
		if (error)
			break;
	}
	prop_object_iterator_release(eit);
	return error;
}
Beispiel #2
0
/*
 * npfctl_table: add, remove or query entries in the specified table.
 *
 * For maximum performance, interface is avoiding proplib(3)'s overhead.
 */
int
npfctl_table(void *data)
{
	npf_ioctl_table_t *nct = data;
	npf_tableset_t *tblset;
	int error;

	npf_core_enter(); /* XXXSMP */
	tblset = npf_core_tableset();
	switch (nct->nct_action) {
	case NPF_IOCTL_TBLENT_ADD:
		error = npf_table_insert(tblset, nct->nct_tid,
		    nct->nct_alen, &nct->nct_addr, nct->nct_mask);
		break;
	case NPF_IOCTL_TBLENT_REM:
		error = npf_table_remove(tblset, nct->nct_tid,
		    nct->nct_alen, &nct->nct_addr, nct->nct_mask);
		break;
	default:
		error = npf_table_lookup(tblset, nct->nct_tid,
		    nct->nct_alen, &nct->nct_addr);
	}
	npf_core_exit(); /* XXXSMP */
	return error;
}
Beispiel #3
0
/*
 * npfctl_table: add, remove or query entries in the specified table.
 *
 * For maximum performance, interface is avoiding proplib(3)'s overhead.
 */
int
npfctl_table(void *data)
{
	const npf_ioctl_table_t *nct = data;
	char tname[NPF_TABLE_MAXNAMELEN];
	npf_tableset_t *ts;
	npf_table_t *t;
	int s, error;

	error = copyinstr(nct->nct_name, tname, sizeof(tname), NULL);
	if (error) {
		return error;
	}

	s = npf_config_read_enter(); /* XXX */
	ts = npf_config_tableset();
	if ((t = npf_tableset_getbyname(ts, tname)) == NULL) {
		npf_config_read_exit(s);
		return EINVAL;
	}

	switch (nct->nct_cmd) {
	case NPF_CMD_TABLE_LOOKUP:
		error = npf_table_lookup(t, nct->nct_data.ent.alen,
		    &nct->nct_data.ent.addr);
		break;
	case NPF_CMD_TABLE_ADD:
		error = npf_table_insert(t, nct->nct_data.ent.alen,
		    &nct->nct_data.ent.addr, nct->nct_data.ent.mask);
		break;
	case NPF_CMD_TABLE_REMOVE:
		error = npf_table_remove(t, nct->nct_data.ent.alen,
		    &nct->nct_data.ent.addr, nct->nct_data.ent.mask);
		break;
	case NPF_CMD_TABLE_LIST:
		error = npf_table_list(t, nct->nct_data.buf.buf,
		    nct->nct_data.buf.len);
		break;
	case NPF_CMD_TABLE_FLUSH:
		error = npf_table_flush(t);
		break;
	default:
		error = EINVAL;
		break;
	}
	npf_config_read_exit(s);

	return error;
}
Beispiel #4
0
int
Mod_fw_replace(FW_handle_T handle, const char *set_name, List_T cidrs, short af)
{
    struct fw_handle *fwh = handle->fwh;
    int fd, nadded = 0;
    char *cidr, *fd_path = NULL;
    char *table = (char *) set_name;
    void *handler;
    struct List_entry *entry;
    nl_config_t *ncf;
    nl_table_t *nt;
    struct IP_addr m, n;
    int ret;
    uint8_t maskbits;
    char parsed[INET6_ADDRSTRLEN];

    if(List_size(cidrs) == 0)
        return 0;

    ncf = npf_config_create();
    nt = npf_table_create(TABLE_ID, NPF_TABLE_HASH);
    
    /* This should somehow be atomic. */
    LIST_EACH(cidrs, entry) {
        if((cidr = List_entry_value(entry)) != NULL
            && IP_str_to_addr_mask(cidr, &n, &m) != -1) 
        {
            ret = sscanf(cidr, "%39[^/]/%u", parsed, &maskbits);
            if(ret != 2 || maskbits == 0 || maskbits > IP_MAX_MASKBITS)
                continue;

            npf_table_add_entry(nt, af, (npf_addr_t *) &n, *((npf_netmask_t *) &maskbits));
            nadded++;
        }
    }

    npf_table_insert(ncf, nt);
    npf_config_submit(ncf, fwh->npfdev);
    npf_config_destroy(ncf);
    npf_table_destroy(nt);
    nt = NULL;
    ncf = NULL;

    return nadded;

err:
    return -1;
}
Beispiel #5
0
/*
 * npfctl_build_table: create an NPF table, add to the configuration and,
 * if required, fill with contents from a file.
 */
void
npfctl_build_table(const char *tid, u_int type, const char *fname)
{
	nl_table_t *tl;
	u_int id;

	id = atoi(tid);
	tl = npf_table_create(id, type);
	assert(tl != NULL);

	if (npf_table_insert(npf_conf, tl)) {
		errx(EXIT_FAILURE, "table '%d' is already defined\n", id);
	}

	if (fname) {
		npfctl_fill_table(tl, type, fname);
	}
}
Beispiel #6
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;
}