/* * 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 #include #include #include 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 ranges); bool add_range(Range *new_range); bool add_range(const char *range, size_t range_len); bool remove_ranges(const std::unordered_set ranges); bool remove_range(const char *range, size_t range_len); std::unordered_set 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 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_