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 for (i = 0; i < 129; i++) {
81 net_mask_array[i] = malloc(4 *
sizeof(uint32_t));
82 if (net_mask_array[i] == NULL) {
83 for (
int k = 0; k < i; k++) {
84 free(net_mask_array[i]);
90 net_mask_array[i][0] = 0xFFFFFFFF >> (i == 0 || i >= 32 ? 0 : 32 - i);
91 net_mask_array[i][1] = i <= 32 ? 0 : 0xFFFFFFFF >> (i >= 64 ? 0 : 64 - i);
92 net_mask_array[i][2] = i <= 64 ? 0 : 0xFFFFFFFF >> (i >= 96 ? 0 : 96 - i);
93 net_mask_array[i][3] = i <= 96 ? 0 : 0xFFFFFFFF >> (128 - i);
96 for (j = 0; j < 4; ++j) {
97 net_mask_array[i][j] = (
bit_endian_swap((net_mask_array[i][j] & 0x000000FF) >> 0) << 0) |
104 return net_mask_array;
117 for (index = 0; index < 129; index++) {
118 free(net_mask_array[index]);
120 free(net_mask_array);
139 if (ip_cmp_result == 0) {
140 return memcmp(&n1->
mask, &n2->
mask, 4);
142 return ip_cmp_result;
162 if (ip_cmp_result == 0) {
163 return memcmp(&n1->
mask, &n2->
mask, 4);
165 return ip_cmp_result;
181 for (i = 0; i < 4; i++) {
182 masked_ipv6->
ui32[i] = ip->
ui32[i] & net_mask_array[mask][i];
196 uint32_t **net_mask_array)
213 for (i = 0; i < 4; i++) {
230 if (new_node == NULL) {
231 fprintf(stderr,
"ERROR allocating memory for network interval node\n");
237 fprintf(stderr,
"ERROR allocating memory for network interval\n");
241 new_node->
next = NULL;
250 fprintf(stderr,
"ERROR allocating memory for data pointers\n");
272 if (new_interval_node == NULL) {
277 new_interval_node->
next = position->
next;
278 position->
next = new_interval_node;
280 return new_interval_node;
295 uint32_t tmp = 0xffffffff;
297 for (i = 3; i >=0; i--) {
298 ip_dec->ui32[i] = htonl(ntohl(ip->
ui32[i]) - 1);
299 if (
ip_dec->ui32[i] != tmp) {
305 ip_dec->ui32[2] = htonl(ntohl(ip->
ui32[2]) - 1);
306 ip_dec->ui32[3] = 0xffffffff;
322 uint32_t tmp = 0xffffffff;
324 for (i = 3; i >= 0; i--) {
325 ip_inc->ui32[i] = htonl(ntohl(ip->
ui32[i]) + 1);
326 if (ip->
ui32[i] < tmp) {
332 ip_inc->ui32[2] = htonl(ntohl(ip->
ui32[2]) + 1);
333 ip_inc->ui32[3] = 0xffffffff;
346 void **data_collector;
347 uint32_t data_collector_cnt = 0;
349 if (prefix_context == NULL) {
350 fprintf(stderr,
"ERROR NULL pointer passed to ipps_destroy\n");
355 if (data_collector == NULL) {
356 fprintf(stderr,
"ERROR allocating memory for freed data collector\n");
361 for (i = 0; i < prefix_context->
v4_count; ++i) {
368 data_collector_cnt = 0;
369 for (i = 0; i < prefix_context->
v6_count; ++i) {
375 free(data_collector);
378 free(prefix_context);
389 if (prefix_context == NULL) {
390 fprintf(stderr,
"ERROR allocating memory for network mask array\n");
399 return prefix_context;
415 if (network_list == NULL) {
416 fprintf(stderr,
"ERROR Network list is not initialized");
421 fprintf(stderr,
"ERROR Network lists are empty, nothing to do");
427 if (prefix_context == NULL) {
433 if (net_mask_array == NULL) {
434 fprintf(stderr,
"ERROR allocating memory for network mask array\n");
453 if ((networks_v4 = malloc(i_v4_alloc *
sizeof(
ipps_network_t *))) == NULL ||
454 (networks_v6 = malloc(i_v6_alloc *
sizeof(
ipps_network_t *))) == NULL) {
459 fprintf(stderr,
"ERROR allocating sorted network structures\n");
464 for (index = 0; index < network_list->
net_count; ++index)
466 current_net = &network_list->
networks[index];
468 masked_ip = ¤t_net->
addr;
472 if (i_v6_alloc < i_v6) {
474 tmp = realloc(networks_v6, i_v6_alloc *
sizeof(
ipps_network_t *));
476 fprintf(stderr,
"ERROR allocating memory for ipv6 network collector\n");
486 networks_v6[i_v6-1] = current_net;
488 masked_ip = ¤t_net->
addr;
489 masked_ip->
ui32[2] = masked_ip->
ui32[2] & net_mask_array[current_net->
mask][0];
492 if (i_v4_alloc < i_v4) {
494 tmp = realloc(networks_v4, i_v4_alloc *
sizeof(
ipps_network_t *));
496 fprintf(stderr,
"ERROR allocating memory for ipv6 network collector\n");
505 networks_v4[i_v4 - 1] = current_net;
509 if (i_v4 > 0 && networks_v4[0] != NULL) {
514 &prefix_context->
v4_count, net_mask_array);
526 if (i_v6 > 0 && networks_v6[0] != NULL) {
531 &prefix_context->
v6_count, net_mask_array);
544 return prefix_context;
564 fprintf(stderr,
"ERROR allocating memory for network mask array\n");
588 void *new_data = malloc(data_len);
589 if (new_data == NULL) {
590 fprintf(stderr,
"ERROR allocating memory for network mask array\n");
594 memcpy(new_data, data, data_len);
603 fprintf(stderr,
"ERROR allocating memory for network mask array\n");
633 uint32_t *context_counter, uint32_t **net_mask_array)
635 uint32_t interval_counter = 0;
647 if (interval_list == NULL) {
664 conductor = interval_list;
667 for (index = 1; index < network_count; ++index) {
671 while (conductor != NULL) {
675 if (ip_cmp_result >= 0) {
677 if (ip_cmp_result > 0) {
680 if (ip_cmp_result > 0) {
684 fprintf(stderr,
"ERROR Inserting to list");
687 }
else if (ip_cmp_result < 0) {
691 fprintf(stderr,
"ERROR Inserting to list");
698 fprintf(stderr,
"ERROR Inserting to list");
702 }
else if (ip_cmp_result < 0) {
705 if (ip_cmp_result > 0) {
717 ¤t_interval.
high_ip) == NULL) {
769 if (end_of_list == conductor) {
770 end_of_list = conductor->
next->next;
774 else if (ip_cmp_result < 0) {
778 fprintf(stderr,
"ERROR Inserting to list");
802 if (end_of_list == conductor) {
803 end_of_list = conductor->
next;
811 if (ip_cmp_result > 0) {
822 if (end_of_list == conductor) {
823 end_of_list = conductor->
next;
832 }
else if (ip_cmp_result < 0) {
836 fprintf(stderr,
"ERROR Inserting to list");
852 }
else if (ip_cmp_result < 0) {
855 conductor = conductor->
next;
858 fprintf(stderr,
"ERROR Inserting to list");
864 if (conductor == NULL) {
872 end_of_list = end_of_list->
next;
880 conductor = end_of_list;
886 if (prefix_context == NULL) {
887 fprintf(stderr,
"ERROR allocating memory for prefix interval_search_context\n");
894 conductor = interval_list;
897 *context_counter = interval_counter;
900 while (conductor != NULL) {
902 memcpy(array_iterator, conductor->
interval, size_of_pref_interval);
906 interval_list = conductor->
next;
909 conductor = interval_list;
912 return prefix_context;
929 int first, last, middle;
932 uint8_t *middle_interval;
934 int ip_high_cmp_result;
935 int ip_low_cmp_result;
942 size_t low_ip_offset;
943 size_t high_ip_offset;
946 if (prefix_context->
v6_count == 0) {
950 last = prefix_context->
v6_count - 1;
951 middle = (first + last)>>1;
956 high_ip_offset = ip_addr_len;
958 ip_addr_start = (uint8_t *)ip;
961 if (prefix_context->
v4_count == 0) {
965 last = prefix_context->
v4_count - 1;
966 middle = (first + last)>>1;
971 high_ip_offset = ip_addr_len + 8;
974 ip_addr_start = ((uint8_t *)ip) + 8;
977 while (first <= last ) {
978 middle_interval = (uint8_t *)(interval_array + middle);
980 ip_low_cmp_result = memcmp(middle_interval + low_ip_offset, ip_addr_start, addr_cmp_len);
981 ip_high_cmp_result = memcmp(middle_interval + high_ip_offset, ip_addr_start, addr_cmp_len);
983 if (ip_low_cmp_result <= 0 && ip_high_cmp_result >= 0) {
986 }
else if (ip_high_cmp_result > 0) {
991 middle = (first + last) >> 1;
1008 for (j = 0; j < interval->
data_cnt; ++j) {
1009 for (k = 0; k < *data_coll_cnt; ++k) {
1010 if (interval->
data_array[j] == (*data_collector)[k]) {
1016 if (k == *data_coll_cnt) {
1019 tmp = realloc(*data_collector, ((*data_coll_cnt) +
COLLECTORSLOTS) *
sizeof(
void *));
1021 fprintf(stderr,
"ERROR allocating memory for network mask array\n");
1024 *data_collector = tmp;
1027 (*data_collector)[*data_coll_cnt] = interval->
data_array[j];
1046 void **data_collector;
1047 uint32_t data_collector_cnt = 0;
1051 if (data_collector == NULL) {
1052 fprintf(stderr,
"ERROR allocating memory for freed data collector\n");
1056 while (interval_list != NULL) {
1057 tmp_interval = interval_list;
1058 interval_list = interval_list->
next;
1066 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_node_t * new_interval(const ip_addr_t *low_ip, const ip_addr_t *high_ip)
ipps_context_t * ipps_init(ipps_network_list_t *network_list)
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)
int cmp_net_v6(const void *v1, const void *v2)
int ipps_search(ip_addr_t *ip, ipps_context_t *prefix_context, void ***data)
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 destroy_list(ipps_interval_node_t *interval_list)
ipps_interval_t * init_context(ipps_network_t **networks, uint32_t network_count, uint32_t *context_counter, uint32_t **net_mask_array)
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()
void mask_ipv6(ip_addr_t *ip, uint32_t mask, ip_addr_t *masked_ipv6, uint32_t **net_mask_array)
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.