END_TEST START_TEST(test_empty_sets_equal) { ip_set_t set1, set2; ipset_init(&set1); ipset_init(&set2); fail_unless(ipset_is_equal(&set1, &set2), "Empty sets should be equal"); ipset_done(&set1); ipset_done(&set2); }
END_TEST START_TEST(test_empty_sets_not_unequal) { ip_set_t set1, set2; ipset_init(&set1); ipset_init(&set2); fail_if(ipset_is_not_equal(&set1, &set2), "Empty sets should not be unequal"); ipset_done(&set1); ipset_done(&set2); }
int init_acl(const char *path, int mode) { acl_mode = mode; // initialize ipset ipset_init_library(); ipset_init(&acl_ipv4_set); ipset_init(&acl_ipv6_set); FILE *f = fopen(path, "r"); if (f == NULL) { LOGE("Invalid acl path."); return -1; } char line[256]; while (!feof(f)) if (fgets(line, 256, f)) { // Trim the newline int len = strlen(line); if (len > 0 && line[len - 1] == '\n') { line[len - 1] = '\0'; } char host[256]; int cidr; parse_addr_cidr(line, host, &cidr); struct cork_ip addr; int err = cork_ip_init(&addr, host); if (!err) { if (addr.version == 4) { if (cidr >= 0) { ipset_ipv4_add_network(&acl_ipv4_set, &(addr.ip.v4), cidr); } else { ipset_ipv4_add(&acl_ipv4_set, &(addr.ip.v4)); } } else if (addr.version == 6) { if (cidr >= 0) { ipset_ipv6_add_network(&acl_ipv6_set, &(addr.ip.v6), cidr); } else { ipset_ipv6_add(&acl_ipv6_set, &(addr.ip.v6)); } } } } fclose(f); return 0; }
END_TEST START_TEST(test_ipv6_memory_size_2) { ip_set_t set; size_t expected, actual; ipset_init(&set); ipset_ipv6_add_network(&set, &IPV6_ADDR_1, 24); #if GLIB_SIZEOF_VOID_P == 4 expected = 300; #elif GLIB_SIZEOF_VOID_P == 8 expected = 600; #else # error "Unknown architecture: not 32-bit or 64-bit" #endif actual = ipset_memory_size(&set); fail_unless(expected == actual, "Expected set to be %zu bytes, got %zu bytes", expected, actual); ipset_done(&set); }
struct ip_set * ipset_new(void) { struct ip_set *result = cork_new(struct ip_set); ipset_init(result); return result; }
END_TEST START_TEST(test_ipv4_iterate_network_01) { struct ip_set set; ipset_init(&set); struct cork_ip ip1; cork_ip_init(&ip1, "192.168.0.0"); fail_if(ipset_ip_add_network(&set, &ip1, 31), "Element should not be present"); struct ipset_iterator *it = ipset_iterate_networks(&set, true); fail_if(it == NULL, "IP set iterator is NULL"); fail_if(it->finished, "IP set shouldn't be empty"); fail_unless(cork_ip_equal(&ip1, &it->addr), "IP address 0 doesn't match"); fail_unless(it->cidr_prefix == 31, "IP CIDR prefix 0 doesn't match"); ipset_iterator_advance(it); fail_unless(it->finished, "IP set should contain 1 elements"); ipset_iterator_free(it); ipset_done(&set); }
END_TEST START_TEST(test_store_empty) { ip_set_t set; ip_set_t *read_set; ipset_init(&set); GOutputStream *ostream = g_memory_output_stream_new(NULL, 0, g_realloc, g_free); GMemoryOutputStream *mostream = G_MEMORY_OUTPUT_STREAM(ostream); fail_unless(ipset_save(ostream, &set, NULL), "Could not save set"); GInputStream *istream = g_memory_input_stream_new_from_data (g_memory_output_stream_get_data(mostream), g_memory_output_stream_get_data_size(mostream), NULL); read_set = ipset_load(istream, NULL); fail_if(read_set == NULL, "Could not read set"); fail_unless(ipset_is_equal(&set, read_set), "Set not same after saving/loading"); g_object_unref(ostream); g_object_unref(istream); ipset_done(&set); ipset_free(read_set); }
END_TEST START_TEST(test_ipv6_iterate_01) { struct ip_set set; ipset_init(&set); struct cork_ip ip1; cork_ip_init(&ip1, "fe80::1"); fail_if(ipset_ip_add(&set, &ip1), "Element should not be present"); struct ipset_iterator *it = ipset_iterate(&set, true); fail_if(it == NULL, "IP set iterator is NULL"); fail_if(it->finished, "IP set shouldn't be empty"); fail_unless(cork_ip_equal(&ip1, &it->addr), "IP address 0 doesn't match"); fail_unless(it->cidr_prefix == IPV6_BIT_SIZE, "IP CIDR prefix 0 doesn't match"); ipset_iterator_advance(it); fail_unless(it->finished, "IP set should contain 1 element"); ipset_iterator_free(it); ipset_done(&set); }
END_TEST START_TEST(test_ipv6_inequality_1) { ip_set_t set1, set2; ipset_init(&set1); ipset_ipv6_add(&set1, &IPV6_ADDR_1); ipset_init(&set2); ipset_ipv6_add_network(&set2, &IPV6_ADDR_1, 32); fail_unless(ipset_is_not_equal(&set1, &set2), "Expected {x} != {x}"); ipset_done(&set1); ipset_done(&set2); }
END_TEST START_TEST(test_ipv4_equality_1) { ip_set_t set1, set2; ipset_init(&set1); ipset_ipv4_add(&set1, &IPV4_ADDR_1); ipset_init(&set2); ipset_ipv4_add(&set2, &IPV4_ADDR_1); fail_unless(ipset_is_equal(&set1, &set2), "Expected {x} == {x}"); ipset_done(&set1); ipset_done(&set2); }
int init_acl(const char *path) { // initialize ipset ipset_init_library(); ipset_init(&acl_ip_set); // initialize array cork_string_array_init(&acl_domain_array); FILE *f = fopen(path, "r"); if (f == NULL) { LOGE("Invalid acl path."); return -1; } char line[256]; while(!feof(f)) { if (fgets(line, 256, f)) { // Trim the newline int len = strlen(line); if (len > 0 && line[len - 1] == '\n') { line[len - 1] = '\0'; } char *host = NULL; int cidr; parse_addr_cidr(line, &host, &cidr); if (cidr == -1) { cork_string_array_append(&acl_domain_array, host); } else { struct cork_ipv4 addr; int err = cork_ipv4_init(&addr, host); if (!err) { if (cidr >= 0) ipset_ipv4_add_network(&acl_ip_set, &addr, cidr); else ipset_ipv4_add(&acl_ip_set, &addr); } } if (host != NULL) free(host); } } fclose(f); return 0; }
END_TEST START_TEST(test_generic_ip_iterate_02) { struct ip_set set; ipset_init(&set); /* * These addresses are carefully constructed so that the same BDD * variable assignments are used to store both, apart from the * IPv4/v6 discriminator variable. The goal is get a BDD that has * EITHER in the assignment for variable 0, but isn't simply the * empty or full set. */ struct cork_ip ip1; cork_ip_init(&ip1, "192.168.0.1"); /* 0xc0a80001 */ struct cork_ip ip2; cork_ip_init(&ip2, "c0a8:0001::"); fail_if(ipset_ip_add(&set, &ip1), "Element should not be present"); fail_if(ipset_ip_add_network(&set, &ip2, 32), "Element should not be present"); struct ipset_iterator *it = ipset_iterate_networks(&set, true); fail_if(it == NULL, "IP set iterator is NULL"); fail_if(it->finished, "IP set shouldn't be empty"); fail_unless(cork_ip_equal(&ip1, &it->addr), "IP address 0 doesn't match"); fail_unless(it->cidr_prefix == 32, "IP CIDR prefix 0 doesn't match"); ipset_iterator_advance(it); fail_if(it->finished, "IP set should have more than 1 element"); fail_unless(cork_ip_equal(&ip2, &it->addr), "IP address 1 doesn't match"); fail_unless(it->cidr_prefix == 32, "IP CIDR prefix 1 doesn't match"); ipset_iterator_advance(it); fail_unless(it->finished, "IP set should contain 2 elements"); ipset_iterator_free(it); ipset_done(&set); }
END_TEST START_TEST(test_ipv6_bad_netmask_02) { ip_set_t set; ipset_init(&set); ipset_ipv6_add_network(&set, &IPV6_ADDR_1, 129); fail_unless(ipset_is_empty(&set), "Bad netmask shouldn't change set"); ipset_done(&set); }
bool iptables_init(void) { #ifdef _HAVE_LIBIPSET_ if (!ipset_init()) { log_message(LOG_INFO, "Unable to initialise ipsets"); global_data->using_ipsets = false; return false; } #endif return true; }
IPSET * ipset_new( int family ) { IPSET * p = (IPSET *)SnortAlloc( sizeof(IPSET)); if( family == IPV4_FAMILY ) { ipset_init( p ); } else { ipset6_init( p ); } return p; }
END_TEST START_TEST(test_ipv6_insert_network_01) { ip_set_t set; ipset_init(&set); fail_if(ipset_ipv6_add_network(&set, &IPV6_ADDR_1, 32), "Element should not be present"); fail_unless(ipset_ipv6_add_network(&set, &IPV6_ADDR_1, 32), "Element should be present"); ipset_done(&set); }
END_TEST START_TEST(test_ipv6_iterate_network_03) { struct ip_set set; ipset_init(&set); /* * If we add all of the IP addresses in a network individually, we * should still get the network as a whole from the iterator. */ struct cork_ip ip1; cork_ip_init(&ip1, "fe80::"); struct cork_ip ip2; cork_ip_init(&ip2, "fe80::1"); fail_if(ipset_ip_add(&set, &ip1), "Element should not be present"); fail_if(ipset_ip_add(&set, &ip2), "Element should not be present"); struct ipset_iterator *it = ipset_iterate_networks(&set, true); fail_if(it == NULL, "IP set iterator is NULL"); fail_if(it->finished, "IP set shouldn't be empty"); fail_unless(cork_ip_equal(&ip1, &it->addr), "IP address 0 doesn't match"); fail_unless(it->cidr_prefix == 127, "IP CIDR prefix 0 doesn't match"); ipset_iterator_advance(it); fail_unless(it->finished, "IP set should contain 1 elements"); ipset_iterator_free(it); ipset_done(&set); }
END_TEST START_TEST(test_ipv4_insert_network_02) { ip_set_t set; ipset_init(&set); ipset_ip_t ip; ipset_ip_from_string(&ip, "192.168.1.100"); fail_if(ipset_ip_add_network(&set, &ip, 24), "Element should not be present"); fail_unless(ipset_ipv4_add_network(&set, &IPV4_ADDR_1, 24), "Element should be present"); ipset_done(&set); }
END_TEST START_TEST(test_ipv6_insert_network_02) { ip_set_t set; ipset_init(&set); ipset_ip_t ip; ipset_ip_from_string(&ip, "fe80::21e:c2ff:fe9f:e8e1"); fail_if(ipset_ip_add_network(&set, &ip, 32), "Element should not be present"); fail_unless(ipset_ipv6_add_network(&set, &IPV6_ADDR_1, 32), "Element should be present"); ipset_done(&set); }
END_TEST START_TEST(test_generic_ip_iterate_01) { struct ip_set set; ipset_init(&set); struct cork_ip ip1; cork_ip_init(&ip1, "0.0.0.0"); struct cork_ip ip2; cork_ip_init(&ip2, "::"); struct ipset_iterator *it = ipset_iterate_networks(&set, false); fail_if(it == NULL, "IP set iterator is NULL"); fail_if(it->finished, "IP set shouldn't be empty"); fail_unless(cork_ip_equal(&ip1, &it->addr), "IP address 0 doesn't match"); fail_unless(it->cidr_prefix == 0, "IP CIDR prefix 0 doesn't match"); ipset_iterator_advance(it); fail_if(it->finished, "IP set should have more than 1 element"); fail_unless(cork_ip_equal(&ip2, &it->addr), "IP address 1 doesn't match"); fail_unless(it->cidr_prefix == 0, "IP CIDR prefix 1 doesn't match"); ipset_iterator_advance(it); fail_unless(it->finished, "IP set should contain 2 elements"); ipset_iterator_free(it); ipset_done(&set); }
END_TEST /*----------------------------------------------------------------------- * IPv6 tests */ START_TEST(test_ipv6_insert_01) { ip_set_t set; ipset_init(&set); fail_if(ipset_ipv6_add(&set, &IPV6_ADDR_1), "Element should not be present"); fail_unless(ipset_ipv6_add(&set, &IPV6_ADDR_1), "Element should be present"); ipset_done(&set); }
static void one_test(long num_elements) { ip_set_t set; long i; size_t size; double size_per_element; ipset_init(&set); for (i = 0; i < num_elements; i++) { ipv4_addr_t ip; random_ip(&ip); ipset_ipv4_add(&set, &ip); } size = ipset_memory_size(&set); size_per_element = ((double) size) / num_elements; fprintf(stdout, "%lu %zu %.3f\n", num_elements, size, size_per_element); ipset_done(&set); }
int init_acl(const char *path) { // initialize ipset ipset_init_library(); ipset_init(&white_list_ipv4); ipset_init(&white_list_ipv6); ipset_init(&black_list_ipv4); ipset_init(&black_list_ipv6); ipset_init(&outbound_block_list_ipv4); ipset_init(&outbound_block_list_ipv6); cork_dllist_init(&black_list_rules); cork_dllist_init(&white_list_rules); cork_dllist_init(&outbound_block_list_rules); struct ip_set *list_ipv4 = &black_list_ipv4; struct ip_set *list_ipv6 = &black_list_ipv6; struct cork_dllist *rules = &black_list_rules; FILE *f = fopen(path, "r"); if (f == NULL) { LOGE("Invalid acl path."); return -1; } char buf[257]; while (!feof(f)) if (fgets(buf, 256, f)) { // Trim the newline int len = strlen(buf); if (len > 0 && buf[len - 1] == '\n') { buf[len - 1] = '\0'; } char *comment = strchr(buf, '#'); if (comment) { *comment = '\0'; } char *line = trimwhitespace(buf); if (strlen(line) == 0) { continue; } if (strcmp(line, "[outbound_block_list]") == 0) { list_ipv4 = &outbound_block_list_ipv4; list_ipv6 = &outbound_block_list_ipv6; rules = &outbound_block_list_rules; continue; } else if (strcmp(line, "[black_list]") == 0 || strcmp(line, "[bypass_list]") == 0) { list_ipv4 = &black_list_ipv4; list_ipv6 = &black_list_ipv6; rules = &black_list_rules; continue; } else if (strcmp(line, "[white_list]") == 0 || strcmp(line, "[proxy_list]") == 0) { list_ipv4 = &white_list_ipv4; list_ipv6 = &white_list_ipv6; rules = &white_list_rules; continue; } else if (strcmp(line, "[reject_all]") == 0 || strcmp(line, "[bypass_all]") == 0) { acl_mode = WHITE_LIST; continue; } else if (strcmp(line, "[accept_all]") == 0 || strcmp(line, "[proxy_all]") == 0) { acl_mode = BLACK_LIST; continue; } else if (strcmp(line, "[remote_dns]") == 0) { continue; } char host[257]; int cidr; parse_addr_cidr(line, host, &cidr); struct cork_ip addr; int err = cork_ip_init(&addr, host); if (!err) { if (addr.version == 4) { if (cidr >= 0) { ipset_ipv4_add_network(list_ipv4, &(addr.ip.v4), cidr); } else { ipset_ipv4_add(list_ipv4, &(addr.ip.v4)); } } else if (addr.version == 6) { if (cidr >= 0) { ipset_ipv6_add_network(list_ipv6, &(addr.ip.v6), cidr); } else { ipset_ipv6_add(list_ipv6, &(addr.ip.v6)); } } } else { rule_t *rule = new_rule(); accept_rule_arg(rule, line); init_rule(rule); add_rule(rules, rule); } } fclose(f); return 0; }
int main(int argc, char **argv) { ipset_init_library(); /* * Parse the command-line options. */ GError *error = NULL; GOptionContext *context; context = g_option_context_new("INPUT FILES"); g_option_context_add_main_entries(context, entries, NULL); if (!g_option_context_parse(context, &argc, &argv, &error)) { fprintf(stderr, "Error parsing command-line options: %s\n", error->message); exit(1); } /* * Verify that the user specified at least one SiLK file to read. */ if (argc <= 1) { #if GLIB_MINOR_VERSION < 14 fprintf(stderr, "ERROR: You need to specify at " "least one input file.\n"); #else fprintf(stderr, "ERROR: You need to specify at " "least one input file.\n\n%s", g_option_context_get_help(context, TRUE, NULL)); #endif exit(1); } /* * Set up logging. */ g_log_set_handler("ipset", G_LOG_LEVEL_DEBUG, ignore_log_message, NULL); /* * Read in the IP set files specified on the command line. */ ip_set_t set; ipset_init(&set); int i; for (i = 1; i < argc; i++) { const char *filename = argv[i]; FILE *stream; gboolean close_stream; /* * Create a FILE object for the file. */ if (strcmp(filename, "-") == 0) { fprintf(stderr, "Opening stdin...\n"); filename = "stdin"; stream = stdin; close_stream = FALSE; } else { fprintf(stderr, "Opening file %s...\n", filename); stream = fopen(filename, "rb"); if (stream == NULL) { fprintf(stderr, "Cannot open file %s:\n %s\n", filename, strerror(errno)); exit(1); } close_stream = TRUE; } /* * Read in one IP address per line in the file. */ gsize ip_count = 0; #define MAX_LINELENGTH 4096 gchar line[MAX_LINELENGTH]; while (fgets(line, MAX_LINELENGTH, stream) != NULL) { /* * Reserve enough space for an IPv6 address. */ guint32 addr[4]; int rc; /* * Try to parse the line as an IPv4 address. If that * works, add it to the set. */ rc = inet_pton(AF_INET, line, addr); if (rc == 1) { ipset_ipv4_add(&set, addr); g_free(line); continue; } /* * If that didn't work, try IPv6. */ rc = inet_pton(AF_INET6, line, addr); if (rc == 1) { ipset_ipv6_add(&set, addr); g_free(line); continue; } /* * Otherwise, we've got an error. */ fprintf(stderr, "\"%s\" is not a valid IP address.\n", line); exit(1); } if (ferror(stream)) { /* * There was an error reading from the stream. */ fprintf(stderr, "Error reading from %s:\n %s\n", filename, strerror(errno)); exit(1); } fprintf(stderr, "Read %" G_GSIZE_FORMAT " IP addresses from %s.\n", ip_count, filename); /* * Free the streams before opening the next file. */ if (close_stream) { fclose(stream); } } fprintf(stderr, "Set uses %" G_GSIZE_FORMAT " bytes of memory.\n", ipset_memory_size(&set)); /* * Serialize the IP set to the desired output file. */ FILE *ostream; gboolean close_ostream; if ((output_filename == NULL) || (strcmp(output_filename, "-") == 0)) { fprintf(stderr, "Writing to stdout...\n"); ostream = stdout; output_filename = "stdout"; close_ostream = FALSE; } else { fprintf(stderr, "Writing to file %s...\n", output_filename); ostream = fopen(output_filename, "wb"); if (ostream == NULL) { fprintf(stderr, "Cannot open file %s:\n %s\n", output_filename, strerror(errno)); exit(1); } close_ostream = TRUE; } if (!ipset_save(ostream, &set, &error)) { fprintf(stderr, "Error saving IP set:\n %s\n", error->message); exit(1); } /* * Close the output stream for exiting. */ if (close_ostream) { fclose(ostream); } return 0; }