#include "cat_network_util.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
#else
#include <arpa/inet.h>
#include <ifaddrs.h>
#include <net/if.h>
#include <netdb.h>
#include <unistd.h>
#define NI_MAXHOST 1025
#define NI_NUMERICHOST 0x00000002
#define IFF_UP 0x1
#define IFF_LOOPBACK 0x8
#endif
int ipAddressLevel(struct in_addr *addr, int offset) {
uint32_t a = addr->s_addr;
if ((a & 0xFF) == 10) {
return 1 + offset;
} else if (((a & 0xFF) == 172) && ((a >> 8 & 0xF0) == 16)) {
return 1 + offset;
} else if (((a & 0xFF) == 192) && ((a >> 8 & 0xFF) == 168)) {
return 1 + offset;
} else {
return 3 + offset;
}
}
#ifndef WIN32
int getLocalHostIp(char *ip) {
struct ifaddrs *ifaddrs = NULL;
if (getifaddrs(&ifaddrs)) {
return -1;
}
struct in_addr res = {0};
int res_level = 0, tmp_level = 0;
char ipBuf[64];
struct ifaddrs *ifa;
for (ifa = ifaddrs; NULL != ifa; ifa = ifa->ifa_next) {
char hostname[NI_MAXHOST];
if (ifa->ifa_addr->sa_family == AF_INET) {
if (!(ifa->ifa_flags & IFF_UP)) {
continue;
}
if (ifa->ifa_flags & IFF_LOOPBACK) {
continue;
}
getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), hostname, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
struct in_addr *addr = &((struct sockaddr_in *) ifa->ifa_addr)->sin_addr;
if (NULL == inet_ntop(AF_INET, addr, ipBuf, 16)) {
continue;
}
int offset = strcmp(ipBuf, hostname) == 0 ? 0 : 1;
if (0 == res.s_addr) {
res = *addr;
res_level = ipAddressLevel(&res, offset);
} else if (res_level < (tmp_level = ipAddressLevel(addr, offset))) {
res = *addr;
res_level = tmp_level;
}
}
}
freeifaddrs(ifaddrs);
if (0 == res.s_addr) {
return -1;
} else {
return NULL == inet_ntop(AF_INET, &res, ip, 16) ? -1 : 0;
}
}
#else
int getLocalHostIp(char *ip) {
char hostname[255];
PHOSTENT hostinfo = NULL;
u_int32 ipValue = 0;
if (gethostname(hostname, sizeof(hostname)) == 0)
{
if ((hostinfo = gethostbyname(hostname)) != NULL)
{
memcpy(&ipValue, *hostinfo->h_addr_list, 4);
}
}
if (ipValue == 0)
{
return -1;
}
struct in_addr inaddr;
inaddr.s_addr = ipValue;
strcpy(ipBuf, inet_ntoa(inaddr));
return 0;
}
#endif
int getLocalHostIpHex(char *ipHexBuf) {
char ip[64] = {0};
if (getLocalHostIp(ip) < 0 || ip[0] == '\0') {
return -1;
}
int a[4];
sscanf(ip, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]);
sprintf(ipHexBuf, "%02x%02x%02x%02x", a[0], a[1], a[2], a[3]);
return 0;
}