60 in = (in & 0xF0) >> 4 | (in & 0x0F) << 4;
61 in = (in & 0xCC) >> 2 | (in & 0x33) << 2;
62 in = (in & 0xAA) >> 1 | (in & 0x55) << 1;
75 uint32_t **net_mask_array = malloc(129 *
sizeof(uint32_t *));
76 if (net_mask_array == NULL) {
80 net_mask_array[0] = calloc(4,
sizeof(uint32_t));
81 for (i = 1; i < 129; i++) {
82 net_mask_array[i] = malloc(4 *
sizeof(uint32_t));
83 if (net_mask_array[i] == NULL) {
84 for (
int k = 0; k < i; k++) {
85 free(net_mask_array[i]);
91 net_mask_array[i][0] = 0xFFFFFFFF >> (i == 0 || i >= 32 ? 0 : 32 - i);
92 net_mask_array[i][1] = i <= 32 ? 0 : 0xFFFFFFFF >> (i >= 64 ? 0 : 64 - i);
93 net_mask_array[i][2] = i <= 64 ? 0 : 0xFFFFFFFF >> (i >= 96 ? 0 : 96 - i);
94 net_mask_array[i][3] = i <= 96 ? 0 : 0xFFFFFFFF >> (128 - i);
97 for (j = 0; j < 4; ++j) {
98 net_mask_array[i][j] = (
bit_endian_swap((net_mask_array[i][j] & 0x000000FF) >> 0) << 0) |
105 return net_mask_array;
118 for (index = 0; index < 129; index++) {
119 free(net_mask_array[index]);
121 free(net_mask_array);
140 if (ip_cmp_result == 0) {
141 return memcmp(&n1->
mask, &n2->
mask, 4);
143 return ip_cmp_result;
163 if (ip_cmp_result == 0) {
164 return memcmp(&n1->
mask, &n2->
mask, 4);
166 return ip_cmp_result;
182 for (i = 0; i < 4; i++) {
183 masked_ipv6->
ui32[i] = ip->
ui32[i] & net_mask_array[mask][i];
197 uint32_t **net_mask_array)
214 for (i = 0; i < 4; i++) {
231 if (new_node == NULL) {
232 fprintf(stderr,
"ERROR allocating memory for network interval node\n");
238 fprintf(stderr,
"ERROR allocating memory for network interval\n");
242 new_node->
next = NULL;
251 fprintf(stderr,
"ERROR allocating memory for data pointers\n");
273 if (new_interval_node == NULL) {
278 new_interval_node->
next = position->
next;
279 position->
next = new_interval_node;
281 return new_interval_node;
296 uint32_t tmp = 0xffffffff;
298 for (i = 3; i >=0; i--) {
299 ip_dec->ui32[i] = htonl(ntohl(ip->
ui32[i]) - 1);
300 if (
ip_dec->ui32[i] != tmp) {
306 ip_dec->ui32[2] = htonl(ntohl(ip->
ui32[2]) - 1);
307 ip_dec->ui32[3] = 0xffffffff;
323 uint32_t tmp = 0xffffffff;
325 for (i = 3; i >= 0; i--) {
326 ip_inc->ui32[i] = htonl(ntohl(ip->
ui32[i]) + 1);
327 if (ip->
ui32[i] < tmp) {
333 ip_inc->ui32[2] = htonl(ntohl(ip->
ui32[2]) + 1);
334 ip_inc->ui32[3] = 0xffffffff;
347 void **data_collector;
348 uint32_t data_collector_cnt = 0;
350 if (prefix_context == NULL) {
351 fprintf(stderr,
"ERROR NULL pointer passed to ipps_destroy\n");
356 if (data_collector == NULL) {
357 fprintf(stderr,
"ERROR allocating memory for freed data collector\n");
362 for (i = 0; i < prefix_context->
v4_count; ++i) {
369 data_collector_cnt = 0;
370 for (i = 0; i < prefix_context->
v6_count; ++i) {
376 free(data_collector);
379 free(prefix_context);
390 if (prefix_context == NULL) {
391 fprintf(stderr,
"ERROR allocating memory for network mask array\n");
400 return prefix_context;
416 if (network_list == NULL) {
417 fprintf(stderr,
"ERROR Network list is not initialized");
422 fprintf(stderr,
"ERROR Network lists are empty, nothing to do");
428 if (prefix_context == NULL) {
434 if (net_mask_array == NULL) {
435 fprintf(stderr,
"ERROR allocating memory for network mask array\n");
454 if ((networks_v4 = malloc(i_v4_alloc *
sizeof(
ipps_network_t *))) == NULL ||
455 (networks_v6 = malloc(i_v6_alloc *
sizeof(
ipps_network_t *))) == NULL) {
460 fprintf(stderr,
"ERROR allocating sorted network structures\n");
465 for (index = 0; index < network_list->
net_count; ++index)
467 current_net = &network_list->
networks[index];
469 masked_ip = ¤t_net->
addr;
473 if (i_v6_alloc < i_v6) {
475 tmp = realloc(networks_v6, i_v6_alloc *
sizeof(
ipps_network_t *));
477 fprintf(stderr,
"ERROR allocating memory for ipv6 network collector\n");
487 networks_v6[i_v6-1] = current_net;
489 masked_ip = ¤t_net->
addr;
490 masked_ip->
ui32[2] = masked_ip->
ui32[2] & net_mask_array[current_net->
mask][0];
493 if (i_v4_alloc < i_v4) {
495 tmp = realloc(networks_v4, i_v4_alloc *
sizeof(
ipps_network_t *));
497 fprintf(stderr,
"ERROR allocating memory for ipv6 network collector\n");
506 networks_v4[i_v4 - 1] = current_net;
510 if (i_v4 > 0 && networks_v4[0] != NULL) {
515 &prefix_context->
v4_count, net_mask_array);
527 if (i_v6 > 0 && networks_v6[0] != NULL) {
532 &prefix_context->
v6_count, net_mask_array);
545 return prefix_context;
565 fprintf(stderr,
"ERROR allocating memory for network mask array\n");
589 void *new_data = malloc(data_len);
590 if (new_data == NULL) {
591 fprintf(stderr,
"ERROR allocating memory for network mask array\n");
595 memcpy(new_data, data, data_len);
604 fprintf(stderr,
"ERROR allocating memory for network mask array\n");
634 uint32_t *context_counter, uint32_t **net_mask_array)
636 uint32_t interval_counter = 0;
648 if (interval_list == NULL) {
665 conductor = interval_list;
668 for (index = 1; index < network_count; ++index) {
672 while (conductor != NULL) {
676 if (ip_cmp_result >= 0) {
678 if (ip_cmp_result > 0) {
681 if (ip_cmp_result > 0) {
685 fprintf(stderr,
"ERROR Inserting to list");
688 }
else if (ip_cmp_result < 0) {
692 fprintf(stderr,
"ERROR Inserting to list");
699 fprintf(stderr,
"ERROR Inserting to list");
703 }
else if (ip_cmp_result < 0) {
706 if (ip_cmp_result > 0) {
718 ¤t_interval.
high_ip) == NULL) {
770 if (end_of_list == conductor) {
771 end_of_list = conductor->
next->next;
775 else if (ip_cmp_result < 0) {
779 fprintf(stderr,
"ERROR Inserting to list");
803 if (end_of_list == conductor) {
804 end_of_list = conductor->
next;
812 if (ip_cmp_result > 0) {
823 if (end_of_list == conductor) {
824 end_of_list = conductor->
next;
833 }
else if (ip_cmp_result < 0) {
837 fprintf(stderr,
"ERROR Inserting to list");
853 }
else if (ip_cmp_result < 0) {
856 conductor = conductor->
next;
859 fprintf(stderr,
"ERROR Inserting to list");
865 if (conductor == NULL) {
873 end_of_list = end_of_list->
next;
881 conductor = end_of_list;
887 if (prefix_context == NULL) {
888 fprintf(stderr,
"ERROR allocating memory for prefix interval_search_context\n");
895 conductor = interval_list;
898 *context_counter = interval_counter;
901 while (conductor != NULL) {
903 memcpy(array_iterator, conductor->
interval, size_of_pref_interval);
907 interval_list = conductor->
next;
910 conductor = interval_list;
913 return prefix_context;
930 int first, last, middle;
933 uint8_t *middle_interval;
935 int ip_high_cmp_result;
936 int ip_low_cmp_result;
943 size_t low_ip_offset;
944 size_t high_ip_offset;
947 if (prefix_context->
v6_count == 0) {
951 last = prefix_context->
v6_count - 1;
952 middle = (first + last)>>1;
957 high_ip_offset = ip_addr_len;
959 ip_addr_start = (uint8_t *)ip;
962 if (prefix_context->
v4_count == 0) {
966 last = prefix_context->
v4_count - 1;
967 middle = (first + last)>>1;
972 high_ip_offset = ip_addr_len + 8;
975 ip_addr_start = ((uint8_t *)ip) + 8;
978 while (first <= last ) {
979 middle_interval = (uint8_t *)(interval_array + middle);
981 ip_low_cmp_result = memcmp(middle_interval + low_ip_offset, ip_addr_start, addr_cmp_len);
982 ip_high_cmp_result = memcmp(middle_interval + high_ip_offset, ip_addr_start, addr_cmp_len);
984 if (ip_low_cmp_result <= 0 && ip_high_cmp_result >= 0) {
987 }
else if (ip_high_cmp_result > 0) {
992 middle = (first + last) >> 1;
1009 for (j = 0; j < interval->
data_cnt; ++j) {
1010 for (k = 0; k < *data_coll_cnt; ++k) {
1011 if (interval->
data_array[j] == (*data_collector)[k]) {
1017 if (k == *data_coll_cnt) {
1020 tmp = realloc(*data_collector, ((*data_coll_cnt) +
COLLECTORSLOTS) *
sizeof(
void *));
1022 fprintf(stderr,
"ERROR allocating memory for network mask array\n");
1025 *data_collector = tmp;
1028 (*data_collector)[*data_coll_cnt] = interval->
data_array[j];
1047 void **data_collector;
1048 uint32_t data_collector_cnt = 0;
1052 if (data_collector == NULL) {
1053 fprintf(stderr,
"ERROR allocating memory for freed data collector\n");
1057 while (interval_list != NULL) {
1058 tmp_interval = interval_list;
1059 interval_list = interval_list->
next;
1067 free(data_collector);
INLINE_IMPL int ip_cmp(const ip_addr_t *addr1, const ip_addr_t *addr2)
INLINE_IMPL int ip_is6(const ip_addr_t *addr)
int ipps_destroy(ipps_context_t *prefix_context)
ipps_context_t * new_context()
ipps_interval_t * init_context(ipps_network_t **networks, uint32_t network_count, uint32_t *context_counter, uint32_t **net_mask_array)
void ip_inc(const ip_addr_t *ip, ip_addr_t *ip_inc)
void destroy_ip_v6_net_mask_array(uint32_t **net_mask_array)
uint8_t bit_endian_swap(uint8_t in)
int free_data(ipps_interval_t *interval, void ***data_collector, uint32_t *data_coll_cnt)
ipps_interval_node_t * insert_new_interval(ipps_interval_node_t *position, const ip_addr_t *low_ip, const ip_addr_t *high_ip)
int cmp_net_v6(const void *v1, const void *v2)
int ipps_search(ip_addr_t *ip, ipps_context_t *prefix_context, void ***data)
int destroy_list(ipps_interval_node_t *interval_list)
int add_data(ipps_interval_t *interval, void *data, size_t data_len)
void ip_dec(const ip_addr_t *ip, ip_addr_t *ip_dec)
int copy_all_data(ipps_interval_t *dest, ipps_interval_t *src)
void fill_interval_by_network(const ipps_network_t *net, ipps_interval_t *inter, uint32_t **net_mask_array)
int cmp_net_v4(const void *v1, const void *v2)
uint32_t ** create_ip_v6_net_mask_array()
ipps_interval_node_t * new_interval(const ip_addr_t *low_ip, const ip_addr_t *high_ip)
void mask_ipv6(ip_addr_t *ip, uint32_t mask, ip_addr_t *masked_ipv6, uint32_t **net_mask_array)
ipps_context_t * ipps_init(ipps_network_list_t *network_list)
Init context and prefix search.
ip_addr_t high_ip
High IP of interval.
ipps_interval_t * v4_prefix_intervals
Pointer to IPv4 intervals array.
ipps_interval_t * v6_prefix_intervals
Pointer to IPv6 intervals array.
uint32_t v6_count
Number of intervals in IPv6 array.
uint32_t data_cnt
Number of currently used data pointers in 'data_array'.
void * data
Pointer to same data.
size_t data_len
Number of bytes in 'data'.
uint32_t v4_count
Number of intervals in IPv4 array.
uint32_t net_count
Number of networks in 'networks' array.
ipps_network_t * networks
Pointer to networks array.
ip_addr_t low_ip
Low IP of interval.
size_t array_len
Allocated size of 'data_array' => total available slots.
uint32_t mask
Network mask, CIDR notation, use for indexing.
void ** data_array
Array of pointers to data.
ip_addr_t addr
Network IP address.
Init context and prefix search - Internal functions and structures.
ipps_interval_t * interval
Pointer to interval structure.
struct ipps_interval_node * next
Next node in list, NULL if last node in list.