| /* |
| * Copyright 2015 Twitter, Inc. |
| * |
| * Licensed 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 "basics/iputils.h" |
| #include <stdio.h> |
| #include <arpa/inet.h> |
| #include <ifaddrs.h> |
| #include <netdb.h> |
| #include <unistd.h> |
| #include <string> |
| #include "glog/logging.h" |
| #include "basics/sptypes.h" |
| #include "basics/sprcodes.h" |
| |
| bool IpUtils::checkIPAddress(const std::string& ip_addr, const IPAddress_Set& aset) { |
| auto it = aset.find(ip_addr); |
| return it != aset.end() ? true : false; |
| } |
| |
| std::string IpUtils::getHostName() { |
| char hostname[BUFSIZ]; |
| struct addrinfo hints, *info; |
| int gai_result; |
| |
| ::gethostname(hostname, sizeof(hostname)); |
| |
| memset(&hints, 0, sizeof hints); |
| hints.ai_family = AF_UNSPEC; /*either IPV4 or IPV6*/ |
| hints.ai_socktype = SOCK_STREAM; |
| hints.ai_flags = AI_CANONNAME; |
| |
| if ((gai_result = ::getaddrinfo(hostname, nullptr, &hints, &info)) != 0) { |
| LOG(WARNING) << "getaddrinfo returned non zero result " << gai_strerror(gai_result); |
| return std::string(hostname); |
| } |
| |
| if (!info) { |
| return std::string(hostname); |
| } |
| |
| std::string cannonical_name = info->ai_canonname; |
| freeaddrinfo(info); |
| return cannonical_name; |
| } |
| |
| sp_int32 IpUtils::getIPAddressHost(IPAddress_Set& aset) { |
| if (!getIPAddress(aset)) return SP_NOTOK; |
| |
| aset.insert(getHostName()); |
| return SP_OK; |
| } |
| |
| sp_int32 IpUtils::getIPAddress(IPAddress_Set& aset) { |
| struct ifaddrs* ifAddrStruct = nullptr; |
| struct ifaddrs* ifa = nullptr; |
| |
| aset.clear(); |
| getifaddrs(&ifAddrStruct); |
| |
| for (ifa = ifAddrStruct; ifa != nullptr; ifa = ifa->ifa_next) { |
| if (ifa->ifa_addr->sa_family == AF_INET) { |
| struct sockaddr_in* addr_in = (struct sockaddr_in*)ifa->ifa_addr; |
| char addressBuffer[INET_ADDRSTRLEN]; |
| inet_ntop(AF_INET, &addr_in->sin_addr, addressBuffer, INET_ADDRSTRLEN); |
| |
| // We don't need the loopback address |
| if (strcmp("lo", ifa->ifa_name)) aset.insert(std::string(addressBuffer)); |
| } |
| } |
| |
| if (ifAddrStruct != nullptr) freeifaddrs(ifAddrStruct); |
| return aset.empty() ? SP_NOTOK : SP_OK; |
| } |
| |
| sp_int32 IpUtils::getIPV6Address(IPAddress_Set& aset) { |
| struct ifaddrs* ifAddrStruct = nullptr; |
| struct ifaddrs* ifa = nullptr; |
| |
| aset.clear(); |
| getifaddrs(&ifAddrStruct); |
| |
| for (ifa = ifAddrStruct; ifa != nullptr; ifa = ifa->ifa_next) { |
| if (ifa->ifa_addr->sa_family == AF_INET6) { |
| struct sockaddr_in6* addr_in = (struct sockaddr_in6*)ifa->ifa_addr; |
| char addressBuffer[INET6_ADDRSTRLEN]; |
| inet_ntop(AF_INET6, &addr_in->sin6_addr, addressBuffer, INET6_ADDRSTRLEN); |
| |
| // We don't need the loopback address |
| if (strcmp("lo", ifa->ifa_name)) aset.insert(std::string(addressBuffer)); |
| } |
| } |
| |
| if (ifAddrStruct != nullptr) freeifaddrs(ifAddrStruct); |
| return aset.empty() ? SP_NOTOK : SP_OK; |
| } |
| |
| sp_int32 IpUtils::getAddressInfo(struct sockaddr_in& t, const char* host, int family, int type) { |
| struct addrinfo hints, *res; |
| |
| memset(&hints, 0, sizeof(hints)); |
| hints.ai_family = family; |
| hints.ai_socktype = type; |
| int error = getaddrinfo(host, nullptr, &hints, &res); |
| if (error == 0) { |
| t = *((struct sockaddr_in*)res->ai_addr); |
| freeaddrinfo(res); |
| } |
| return error; |
| } |