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) { 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; }
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; }