Files
openGauss-server/src/include/iprange/iprange.h
2022-03-04 23:22:16 +08:00

192 lines
5.8 KiB
C++

/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* -------------------------------------------------------------------------
*
* iprange.h
* define operation functions for ip type data
*
* IDENTIFICATION
* src/include/iprange/iprange.h
*
* -------------------------------------------------------------------------
*/
#ifndef IPRANGE_AUDIT_H_
#define IPRANGE_AUDIT_H_
#include <stdint.h>
#include <string>
#include <unordered_set>
#include <vector>
typedef unsigned char ipv6arr[16];
typedef struct IPV6_64_s
{
uint64_t lower;
uint64_t upper;
} IPV6_64;
typedef struct IPV6_32_s
{
uint32_t a;
uint32_t b;
uint32_t c;
uint32_t d;
} IPV6_32;
typedef union IPV6_s
{
IPV6_64 ip_64;
IPV6_32 ip_32;
} IPV6;
inline bool operator< (const IPV6 lhs, const IPV6 rhs){ return lhs.ip_64.upper < rhs.ip_64.upper || lhs.ip_64.lower < rhs.ip_64.lower; }
inline bool operator> (const IPV6 lhs, const IPV6 rhs){ return rhs < lhs; }
inline bool operator<=(const IPV6 lhs, const IPV6 rhs){ return !(lhs > rhs); }
inline bool operator>=(const IPV6 lhs, const IPV6 rhs){ return !(lhs < rhs); }
inline const IPV6 operator~(const IPV6 ip)
{
IPV6 new_ip;
new_ip.ip_64.lower = ~ip.ip_64.lower;
new_ip.ip_64.upper = ~ip.ip_64.upper;
return new_ip;
}
inline bool operator==(const IPV6 lhs, const IPV6 rhs)
{
return lhs.ip_64.lower == rhs.ip_64.lower && lhs.ip_64.upper == rhs.ip_64.upper;
}
inline const IPV6 operator+(const IPV6 lhs, const IPV6 rhs)
{
uint64_t tmp;
IPV6 new_ip {0,0};
if (lhs.ip_32.b == 0x0000FFFF) {
new_ip.ip_32.a = lhs.ip_32.a + rhs.ip_32.a;
new_ip.ip_32.b = 0x0000FFFF;
return new_ip;
}
new_ip.ip_32.a = tmp = ((int64_t)lhs.ip_32.a) + rhs.ip_32.a;
new_ip.ip_32.b = tmp = ((int64_t)lhs.ip_32.b) + rhs.ip_32.b + (tmp >> 32);
new_ip.ip_32.c = tmp = ((int64_t)lhs.ip_32.c) + rhs.ip_32.c + (tmp >> 32);
new_ip.ip_32.d = ((int64_t)lhs.ip_32.d) + rhs.ip_32.d + (tmp >> 32);
return new_ip;
}
inline const IPV6 operator+(const IPV6 lhs, const int i)
{
IPV6 new_ip {0,0};
new_ip.ip_64.lower = i;
return lhs + new_ip;
}
inline const IPV6 operator-(const IPV6 lhs, const IPV6 rhs)
{
if (lhs.ip_32.b == 0x0000FFFF) {
IPV6 new_ip {0,0};
new_ip.ip_32.a = lhs.ip_32.a - rhs.ip_32.a;
new_ip.ip_32.b = 0x0000FFFF;
return new_ip;
}
uint64_t tmp;
IPV6 new_ip {0,0};
new_ip.ip_32.a = tmp = ((int64_t)lhs.ip_32.a) - rhs.ip_32.a;
new_ip.ip_32.b = tmp = ((int64_t)lhs.ip_32.b) - rhs.ip_32.b - (tmp>>63);
new_ip.ip_32.c = tmp = ((int64_t)lhs.ip_32.c) - rhs.ip_32.c - (tmp>>63);
new_ip.ip_32.d = ((int64_t)lhs.ip_32.d) - rhs.ip_32.d - (tmp>>63);
return new_ip;
}
inline const IPV6 operator-(const IPV6 lhs, const int i)
{
IPV6 new_ip {0,0};
new_ip.ip_64.lower = i;
return lhs - new_ip;
}
inline const IPV6 operator&(const IPV6 lhs, const IPV6 rhs)
{
IPV6 new_ip;
new_ip.ip_64.lower = lhs.ip_64.lower & rhs.ip_64.lower;
new_ip.ip_64.upper = lhs.ip_64.upper & rhs.ip_64.upper;
return new_ip;
}
inline const IPV6 operator|(const IPV6 lhs, const IPV6 rhs)
{
IPV6 new_ip;
new_ip.ip_64.lower = lhs.ip_64.lower | rhs.ip_64.lower;
new_ip.ip_64.upper = lhs.ip_64.upper | rhs.ip_64.upper;
return new_ip;
}
typedef struct Range_s
{
Range_s(const IPV6 _from = IPV6(), const IPV6 _to = IPV6()):from(_from), to(_to){}
IPV6 from;
IPV6 to;
} Range;
class IPRange
{
public:
IPRange();
~IPRange();
static bool is_range_valid(const std::string range);
bool add_ranges(const std::unordered_set<std::string> ranges);
bool add_range(Range *new_range);
bool add_range(const char *range, size_t range_len);
bool remove_ranges(const std::unordered_set<std::string> ranges);
bool remove_range(const char *range, size_t range_len);
std::unordered_set<std::string> get_ranges_set();
bool is_in_range(const char *ip_str);
bool is_in_range(const IPV6 *ip);
bool is_in_range(const uint32_t ipv4);
bool is_intersect(const IPRange *arg);
bool empty() const;
const std::string& get_err_str() { return m_err_str; }
std::string ip_to_str(const IPV6 *ip) const;
bool str_to_ip(const char* ip_str, IPV6 *ip);
private:
typedef std::vector<Range> Ranges_t;
Ranges_t m_ranges;
std::string m_err_str;
bool parse_range(const char* range, size_t range_len, Range *new_range);
bool parse_slash(const char* range, size_t range_len, const char *ptr, Range *new_range);
bool parse_hyphen(const char* range, size_t range_len, const char *ptr, Range *new_range);
bool parse_mask(const char* range, size_t range_len, const char *ptr, Range *new_range);
bool parse_single(const char* range, size_t range_len, Range *new_range);
bool binary_search(const IPV6 ip) const;
bool mask_range(Range *range, unsigned short cidr);
void handle_remove_intersection(Ranges_t *new_ranges, const Range *remove_range, Range *exist_range);
bool handle_add_intersection(Range *new_range, const Range *exist_range);
void copy_without_spaces(char buf[], size_t buf_len, const char *original, size_t original_len) const;
void net_ipv6_to_host_order(IPV6 *ip, const struct sockaddr_in6 *sa) const;
void net_ipv4_to_host_order(IPV6 *ip, const struct in_addr *addr) const;
};
#endif // IPRANGE_AUDIT_H_