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; }
/* * 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; }
/* * 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; }
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; }
/* * 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); } }
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; }