// Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. #include "util/cidr.h" #include #include "common/logging.h" #include "gutil/strings/split.h" namespace doris { CIDR::CIDR() : _address(0), _netmask(0xffffffff) {} void CIDR::reset() { _address = 0; _netmask = 0xffffffff; } bool CIDR::reset(const std::string& cidr_str) { reset(); // check if have mask std::string cidr_format_str = cidr_str; int32_t have_mask = cidr_str.find("/"); if (have_mask == -1) { cidr_format_str.assign(cidr_str + "/32"); } VLOG_CRITICAL << "cidr format str: " << cidr_format_str; std::vector cidr_items = strings::Split(cidr_format_str, "/"); if (cidr_items.size() != 2) { LOG(WARNING) << "wrong CIDR format. network=" << cidr_str; return false; } if (cidr_items[1].empty()) { LOG(WARNING) << "wrong CIDR mask format. network=" << cidr_str; return false; } char* endptr = nullptr; int32_t mask_length = strtol(cidr_items[1].c_str(), &endptr, 10); if ((errno == ERANGE && (mask_length == LONG_MAX || mask_length == LONG_MIN)) || (errno != 0 && mask_length == 0)) { char errmsg[64]; strerror_r(errno, errmsg, 64); LOG(WARNING) << "wrong CIDR mask format. network=" << cidr_str << ", mask_length=" << mask_length << ", errno=" << errno << ", errmsg=" << errmsg; return false; } if (mask_length <= 0 || mask_length > 32) { LOG(WARNING) << "wrong CIDR mask format. network=" << cidr_str << ", mask_length=" << mask_length; return false; } uint32_t address = 0; if (!ip_to_int(cidr_items[0], &address)) { LOG(WARNING) << "wrong CIDR IP value. network=" << cidr_str; return false; } _address = address; _netmask = 0xffffffff; _netmask = _netmask << (32 - mask_length); return true; } bool CIDR::ip_to_int(const std::string& ip_str, uint32_t* value) { struct in_addr addr; int flag = inet_aton(ip_str.c_str(), &addr); if (flag == 0) { return false; } *value = ntohl(addr.s_addr); return true; } bool CIDR::contains(uint32_t ip_int) { if ((_address & _netmask) == (ip_int & _netmask)) { return true; } return false; } bool CIDR::contains(const std::string& ip) { uint32_t ip_int = 0; if (!ip_to_int(ip, &ip_int)) { return false; } return contains(ip_int); } } // end namespace doris