blob: f514c554de530ee51c67307ba665d12196510ca6 [file] [log] [blame]
/*
* 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;
}