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_fill_table: fill NPF table with entries from a specified file. */ static void npfctl_fill_table(nl_table_t *tl, u_int type, const char *fname) { char *buf = NULL; int l = 0; FILE *fp; size_t n; fp = fopen(fname, "r"); if (fp == NULL) { err(EXIT_FAILURE, "open '%s'", fname); } while (l++, getline(&buf, &n, fp) != -1) { fam_addr_mask_t fam; int alen; if (*buf == '\n' || *buf == '#') { continue; } if (!npfctl_parse_cidr(buf, &fam, &alen)) { errx(EXIT_FAILURE, "%s:%d: invalid table entry", fname, l); } if (type == NPF_TABLE_HASH && fam.fam_mask != NPF_NO_NETMASK) { errx(EXIT_FAILURE, "%s:%d: mask used with the hash table", fname, l); } /* Create and add a table entry. */ npf_table_add_entry(tl, alen, &fam.fam_addr, fam.fam_mask); } if (buf != NULL) { free(buf); } }