1688 lines
32 KiB
C++
1688 lines
32 KiB
C++
|
|
/***************************************************************************************
|
||
|
|
*
|
||
|
|
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||
|
|
*
|
||
|
|
* By downloading, copying, installing or using the software you agree to this license.
|
||
|
|
* If you do not agree to this license, do not download, install,
|
||
|
|
* copy or use the software.
|
||
|
|
*
|
||
|
|
* Copyright (C) 2014-2024, Happytimesoft Corporation, all rights reserved.
|
||
|
|
*
|
||
|
|
* Redistribution and use in binary forms, with or without modification, are permitted.
|
||
|
|
*
|
||
|
|
* 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 "sys_inc.h"
|
||
|
|
#include "util.h"
|
||
|
|
|
||
|
|
/***************************************************************************************/
|
||
|
|
HT_API int get_if_nums()
|
||
|
|
{
|
||
|
|
#if __WINDOWS_OS__
|
||
|
|
|
||
|
|
char ipt_buf[512];
|
||
|
|
MIB_IPADDRTABLE * ipt = (MIB_IPADDRTABLE *)ipt_buf;
|
||
|
|
ULONG ipt_len = sizeof(ipt_buf);
|
||
|
|
DWORD fr = GetIpAddrTable(ipt, &ipt_len, FALSE);
|
||
|
|
if (fr != NO_ERROR)
|
||
|
|
{
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
return ipt->dwNumEntries;
|
||
|
|
|
||
|
|
#elif defined(IOS)
|
||
|
|
|
||
|
|
int count = 0;
|
||
|
|
struct ifaddrs *if_addrs = NULL;
|
||
|
|
struct ifaddrs *if_addr = NULL;
|
||
|
|
|
||
|
|
if (0 == getifaddrs(&if_addrs))
|
||
|
|
{
|
||
|
|
for (if_addr = if_addrs; if_addr != NULL; if_addr = if_addr->ifa_next)
|
||
|
|
{
|
||
|
|
if (NULL == if_addr->ifa_addr || if_addr->ifa_addr->sa_family != AF_INET)
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
count++;
|
||
|
|
}
|
||
|
|
|
||
|
|
freeifaddrs(if_addrs);
|
||
|
|
if_addrs = NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
return count;
|
||
|
|
|
||
|
|
#elif __LINUX_OS__
|
||
|
|
|
||
|
|
SOCKET socket_fd;
|
||
|
|
struct ifreq *ifr;
|
||
|
|
struct ifconf conf;
|
||
|
|
char buff[BUFSIZ];
|
||
|
|
int i, num, count = 0;
|
||
|
|
|
||
|
|
socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||
|
|
if (socket_fd <= 0)
|
||
|
|
{
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
conf.ifc_len = BUFSIZ;
|
||
|
|
conf.ifc_buf = buff;
|
||
|
|
|
||
|
|
ioctl(socket_fd, SIOCGIFCONF, &conf);
|
||
|
|
|
||
|
|
num = conf.ifc_len / sizeof(struct ifreq);
|
||
|
|
ifr = conf.ifc_req;
|
||
|
|
|
||
|
|
for (i=0; i<num; i++)
|
||
|
|
{
|
||
|
|
if (ifr->ifr_addr.sa_family == AF_INET)
|
||
|
|
{
|
||
|
|
count++;
|
||
|
|
}
|
||
|
|
|
||
|
|
ifr++;
|
||
|
|
}
|
||
|
|
|
||
|
|
closesocket(socket_fd);
|
||
|
|
|
||
|
|
return count;
|
||
|
|
|
||
|
|
#endif
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
HT_API uint32 get_if_ip(int index)
|
||
|
|
{
|
||
|
|
#if __WINDOWS_OS__
|
||
|
|
|
||
|
|
char ipt_buf[1024];
|
||
|
|
DWORD i;
|
||
|
|
MIB_IPADDRTABLE * ipt = (MIB_IPADDRTABLE *)ipt_buf;
|
||
|
|
ULONG ipt_len = sizeof(ipt_buf);
|
||
|
|
DWORD fr = GetIpAddrTable(ipt, &ipt_len, FALSE);
|
||
|
|
if (fr != NO_ERROR)
|
||
|
|
{
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
for (i=0; i<ipt->dwNumEntries; i++)
|
||
|
|
{
|
||
|
|
if (i == index)
|
||
|
|
{
|
||
|
|
return ipt->table[i].dwAddr;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#elif defined(IOS)
|
||
|
|
|
||
|
|
int count = 0;
|
||
|
|
struct ifaddrs *if_addrs = NULL;
|
||
|
|
struct ifaddrs *if_addr = NULL;
|
||
|
|
struct sockaddr_in * sin;
|
||
|
|
uint32 ip_addr = 0;
|
||
|
|
|
||
|
|
if (0 == getifaddrs(&if_addrs))
|
||
|
|
{
|
||
|
|
for (if_addr = if_addrs; if_addr != NULL; if_addr = if_addr->ifa_next)
|
||
|
|
{
|
||
|
|
if (NULL == if_addr->ifa_addr || if_addr->ifa_addr->sa_family != AF_INET)
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (count++ == index)
|
||
|
|
{
|
||
|
|
sin = (struct sockaddr_in *)if_addr->ifa_addr;
|
||
|
|
ip_addr = sin->sin_addr.s_addr;
|
||
|
|
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
freeifaddrs(if_addrs);
|
||
|
|
if_addrs = NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
return ip_addr;
|
||
|
|
|
||
|
|
#elif __LINUX_OS__
|
||
|
|
|
||
|
|
int i;
|
||
|
|
SOCKET socket_fd;
|
||
|
|
struct ifreq *ifr;
|
||
|
|
struct ifconf conf;
|
||
|
|
char buff[BUFSIZ];
|
||
|
|
int num, count = 0;
|
||
|
|
uint32 ip_addr = 0;
|
||
|
|
|
||
|
|
socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||
|
|
|
||
|
|
conf.ifc_len = BUFSIZ;
|
||
|
|
conf.ifc_buf = buff;
|
||
|
|
|
||
|
|
ioctl(socket_fd, SIOCGIFCONF, &conf);
|
||
|
|
|
||
|
|
num = conf.ifc_len / sizeof(struct ifreq);
|
||
|
|
ifr = conf.ifc_req;
|
||
|
|
|
||
|
|
for (i=0; i<num; i++)
|
||
|
|
{
|
||
|
|
if (ifr->ifr_addr.sa_family != AF_INET)
|
||
|
|
{
|
||
|
|
ifr++;
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (count++ == index)
|
||
|
|
{
|
||
|
|
struct sockaddr_in *sin = (struct sockaddr_in *)(&ifr->ifr_addr);
|
||
|
|
ip_addr = sin->sin_addr.s_addr;
|
||
|
|
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
ifr++;
|
||
|
|
}
|
||
|
|
|
||
|
|
closesocket(socket_fd);
|
||
|
|
|
||
|
|
return ip_addr;
|
||
|
|
|
||
|
|
#endif
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
HT_API uint32 get_route_if_ip(uint32 dst_ip)
|
||
|
|
{
|
||
|
|
#if __WINDOWS_OS__
|
||
|
|
|
||
|
|
DWORD i;
|
||
|
|
DWORD dwIfIndex,fr;
|
||
|
|
char ipt_buf[1024];
|
||
|
|
MIB_IPADDRTABLE *ipt;
|
||
|
|
ULONG ipt_len;
|
||
|
|
|
||
|
|
fr = GetBestInterface(dst_ip, &dwIfIndex);
|
||
|
|
if (fr != NO_ERROR)
|
||
|
|
{
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
ipt = (MIB_IPADDRTABLE *)ipt_buf;
|
||
|
|
ipt_len = sizeof(ipt_buf);
|
||
|
|
fr = GetIpAddrTable(ipt, &ipt_len, FALSE);
|
||
|
|
if (fr != NO_ERROR)
|
||
|
|
{
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
for (i=0; i<ipt->dwNumEntries; i++)
|
||
|
|
{
|
||
|
|
if (ipt->table[i].dwIndex == dwIfIndex)
|
||
|
|
{
|
||
|
|
return ipt->table[i].dwAddr;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#elif defined(IOS)
|
||
|
|
|
||
|
|
struct ifaddrs *if_addrs = NULL;
|
||
|
|
struct ifaddrs *if_addr = NULL;
|
||
|
|
struct sockaddr_in * sin;
|
||
|
|
uint32 ip_addr = 0;
|
||
|
|
|
||
|
|
if (0 == getifaddrs(&if_addrs))
|
||
|
|
{
|
||
|
|
for (if_addr = if_addrs; if_addr != NULL; if_addr = if_addr->ifa_next)
|
||
|
|
{
|
||
|
|
if (NULL == if_addr->ifa_addr || if_addr->ifa_addr->sa_family != AF_INET)
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
sin = (struct sockaddr_in *)if_addr->ifa_addr;
|
||
|
|
|
||
|
|
if (((if_addr->ifa_flags & IFF_LOOPBACK) == 0) && (if_addr->ifa_flags & IFF_UP))
|
||
|
|
{
|
||
|
|
ip_addr = sin->sin_addr.s_addr;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
freeifaddrs(if_addrs);
|
||
|
|
if_addrs = NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
return ip_addr;
|
||
|
|
|
||
|
|
#elif __LINUX_OS__
|
||
|
|
|
||
|
|
int i;
|
||
|
|
SOCKET socket_fd;
|
||
|
|
struct ifreq *ifr;
|
||
|
|
struct ifconf conf;
|
||
|
|
char buff[BUFSIZ];
|
||
|
|
int num;
|
||
|
|
uint32 ip_addr = 0;
|
||
|
|
|
||
|
|
socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||
|
|
|
||
|
|
conf.ifc_len = BUFSIZ;
|
||
|
|
conf.ifc_buf = buff;
|
||
|
|
|
||
|
|
ioctl(socket_fd, SIOCGIFCONF, &conf);
|
||
|
|
|
||
|
|
num = conf.ifc_len / sizeof(struct ifreq);
|
||
|
|
ifr = conf.ifc_req;
|
||
|
|
|
||
|
|
for (i=0; i<num; i++)
|
||
|
|
{
|
||
|
|
if (ifr->ifr_addr.sa_family != AF_INET)
|
||
|
|
{
|
||
|
|
ifr++;
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
ioctl(socket_fd, SIOCGIFFLAGS, ifr);
|
||
|
|
|
||
|
|
if (((ifr->ifr_flags & IFF_LOOPBACK) == 0) && (ifr->ifr_flags & IFF_UP))
|
||
|
|
{
|
||
|
|
struct sockaddr_in *sin = (struct sockaddr_in *)(&ifr->ifr_addr);
|
||
|
|
ip_addr = sin->sin_addr.s_addr;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
ifr++;
|
||
|
|
}
|
||
|
|
|
||
|
|
closesocket(socket_fd);
|
||
|
|
|
||
|
|
return ip_addr;
|
||
|
|
|
||
|
|
#endif
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
HT_API uint32 get_default_if_ip()
|
||
|
|
{
|
||
|
|
uint32 ip = get_route_if_ip(0);
|
||
|
|
|
||
|
|
if (ip != 0)
|
||
|
|
{
|
||
|
|
return ip;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
int i;
|
||
|
|
int nums = get_if_nums();
|
||
|
|
|
||
|
|
for (i = 0; i < nums; i++)
|
||
|
|
{
|
||
|
|
ip = get_if_ip(i);
|
||
|
|
if (ip != 0 && ip != inet_addr("127.0.0.l"))
|
||
|
|
{
|
||
|
|
return ip;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
HT_API const char * get_local_ip()
|
||
|
|
{
|
||
|
|
uint32 ip = get_default_if_ip();
|
||
|
|
if (ip != 0)
|
||
|
|
{
|
||
|
|
return get_ip_str(ip);
|
||
|
|
}
|
||
|
|
|
||
|
|
return "127.0.0.1";
|
||
|
|
}
|
||
|
|
|
||
|
|
HT_API uint32 get_if_mask(int index)
|
||
|
|
{
|
||
|
|
#if __WINDOWS_OS__
|
||
|
|
|
||
|
|
char ipt_buf[1024];
|
||
|
|
DWORD i;
|
||
|
|
MIB_IPADDRTABLE * ipt = (MIB_IPADDRTABLE *)ipt_buf;
|
||
|
|
ULONG ipt_len = sizeof(ipt_buf);
|
||
|
|
DWORD fr = GetIpAddrTable(ipt, &ipt_len, FALSE);
|
||
|
|
if (fr != NO_ERROR)
|
||
|
|
{
|
||
|
|
return inet_addr("255.255.255.255");
|
||
|
|
}
|
||
|
|
|
||
|
|
for (i=0; i<ipt->dwNumEntries; i++)
|
||
|
|
{
|
||
|
|
if (i == index)
|
||
|
|
{
|
||
|
|
return ipt->table[i].dwMask;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#elif defined(IOS)
|
||
|
|
|
||
|
|
int count = 0;
|
||
|
|
struct ifaddrs *if_addrs = NULL;
|
||
|
|
struct ifaddrs *if_addr = NULL;
|
||
|
|
struct sockaddr_in * sin;
|
||
|
|
uint32 mask = inet_addr("255.255.255.255");
|
||
|
|
|
||
|
|
if (0 == getifaddrs(&if_addrs))
|
||
|
|
{
|
||
|
|
for (if_addr = if_addrs; if_addr != NULL; if_addr = if_addr->ifa_next)
|
||
|
|
{
|
||
|
|
if (NULL == if_addr->ifa_addr || if_addr->ifa_addr->sa_family != AF_INET)
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (count++ == index)
|
||
|
|
{
|
||
|
|
sin = (struct sockaddr_in *)if_addr->ifa_netmask;
|
||
|
|
mask = sin->sin_addr.s_addr;
|
||
|
|
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
freeifaddrs(if_addrs);
|
||
|
|
if_addrs = NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
return mask;
|
||
|
|
|
||
|
|
#elif __LINUX_OS__
|
||
|
|
|
||
|
|
int i;
|
||
|
|
SOCKET socket_fd;
|
||
|
|
struct ifreq *ifr;
|
||
|
|
struct ifconf conf;
|
||
|
|
char buff[BUFSIZ];
|
||
|
|
int num, count = 0;
|
||
|
|
uint32 mask = inet_addr("255.255.255.255");
|
||
|
|
|
||
|
|
socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||
|
|
|
||
|
|
conf.ifc_len = BUFSIZ;
|
||
|
|
conf.ifc_buf = buff;
|
||
|
|
|
||
|
|
ioctl(socket_fd, SIOCGIFCONF, &conf);
|
||
|
|
|
||
|
|
num = conf.ifc_len / sizeof(struct ifreq);
|
||
|
|
ifr = conf.ifc_req;
|
||
|
|
|
||
|
|
for (i=0; i<num; i++)
|
||
|
|
{
|
||
|
|
if (ifr->ifr_addr.sa_family != AF_INET)
|
||
|
|
{
|
||
|
|
ifr++;
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (count++ == index)
|
||
|
|
{
|
||
|
|
struct sockaddr_in *sin = (struct sockaddr_in *)(&ifr->ifr_netmask);
|
||
|
|
|
||
|
|
ioctl(socket_fd, SIOCGIFNETMASK, ifr);
|
||
|
|
|
||
|
|
mask = sin->sin_addr.s_addr;
|
||
|
|
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
ifr++;
|
||
|
|
}
|
||
|
|
|
||
|
|
closesocket(socket_fd);
|
||
|
|
|
||
|
|
return mask;
|
||
|
|
|
||
|
|
#endif
|
||
|
|
|
||
|
|
return inet_addr("255.255.255.255");
|
||
|
|
}
|
||
|
|
|
||
|
|
HT_API uint32 get_route_if_mask(uint32 dst_ip)
|
||
|
|
{
|
||
|
|
#if __WINDOWS_OS__
|
||
|
|
|
||
|
|
DWORD i;
|
||
|
|
DWORD dwIfIndex,fr;
|
||
|
|
char ipt_buf[1024];
|
||
|
|
MIB_IPADDRTABLE *ipt;
|
||
|
|
ULONG ipt_len;
|
||
|
|
|
||
|
|
fr = GetBestInterface(dst_ip, &dwIfIndex);
|
||
|
|
if (fr != NO_ERROR)
|
||
|
|
{
|
||
|
|
return inet_addr("255.255.255.255");
|
||
|
|
}
|
||
|
|
|
||
|
|
ipt = (MIB_IPADDRTABLE *)ipt_buf;
|
||
|
|
ipt_len = sizeof(ipt_buf);
|
||
|
|
fr = GetIpAddrTable(ipt,&ipt_len,FALSE);
|
||
|
|
if (fr != NO_ERROR)
|
||
|
|
{
|
||
|
|
return inet_addr("255.255.255.255");
|
||
|
|
}
|
||
|
|
|
||
|
|
for (i=0; i<ipt->dwNumEntries; i++)
|
||
|
|
{
|
||
|
|
if (ipt->table[i].dwIndex == dwIfIndex)
|
||
|
|
{
|
||
|
|
return ipt->table[i].dwMask;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#elif defined(IOS)
|
||
|
|
|
||
|
|
struct ifaddrs *if_addrs = NULL;
|
||
|
|
struct ifaddrs *if_addr = NULL;
|
||
|
|
struct sockaddr_in * sin;
|
||
|
|
uint32 mask = inet_addr("255.255.255.255");
|
||
|
|
|
||
|
|
if (0 == getifaddrs(&if_addrs))
|
||
|
|
{
|
||
|
|
for (if_addr = if_addrs; if_addr != NULL; if_addr = if_addr->ifa_next)
|
||
|
|
{
|
||
|
|
if (NULL == if_addr->ifa_addr || if_addr->ifa_addr->sa_family != AF_INET)
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
sin = (struct sockaddr_in *)if_addr->ifa_netmask;
|
||
|
|
|
||
|
|
if (((if_addr->ifa_flags & IFF_LOOPBACK) == 0) && (if_addr->ifa_flags & IFF_UP))
|
||
|
|
{
|
||
|
|
mask = sin->sin_addr.s_addr;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
freeifaddrs(if_addrs);
|
||
|
|
if_addrs = NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
return mask;
|
||
|
|
|
||
|
|
#elif __LINUX_OS__
|
||
|
|
|
||
|
|
int i;
|
||
|
|
SOCKET socket_fd;
|
||
|
|
struct ifreq *ifr;
|
||
|
|
struct ifconf conf;
|
||
|
|
char buff[BUFSIZ];
|
||
|
|
int num;
|
||
|
|
uint32 mask = inet_addr("255.255.255.255");
|
||
|
|
|
||
|
|
socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||
|
|
|
||
|
|
conf.ifc_len = BUFSIZ;
|
||
|
|
conf.ifc_buf = buff;
|
||
|
|
|
||
|
|
ioctl(socket_fd, SIOCGIFCONF, &conf);
|
||
|
|
|
||
|
|
num = conf.ifc_len / sizeof(struct ifreq);
|
||
|
|
ifr = conf.ifc_req;
|
||
|
|
|
||
|
|
for (i=0; i<num; i++)
|
||
|
|
{
|
||
|
|
if (ifr->ifr_addr.sa_family != AF_INET)
|
||
|
|
{
|
||
|
|
ifr++;
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
ioctl(socket_fd, SIOCGIFFLAGS, ifr);
|
||
|
|
|
||
|
|
if (((ifr->ifr_flags & IFF_LOOPBACK) == 0) && (ifr->ifr_flags & IFF_UP))
|
||
|
|
{
|
||
|
|
struct sockaddr_in *sin = (struct sockaddr_in *)(&ifr->ifr_netmask);
|
||
|
|
|
||
|
|
ioctl(socket_fd, SIOCGIFNETMASK, ifr);
|
||
|
|
|
||
|
|
mask = sin->sin_addr.s_addr;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
ifr++;
|
||
|
|
}
|
||
|
|
|
||
|
|
closesocket(socket_fd);
|
||
|
|
|
||
|
|
return mask;
|
||
|
|
|
||
|
|
#endif
|
||
|
|
|
||
|
|
return inet_addr("255.255.255.255");
|
||
|
|
}
|
||
|
|
|
||
|
|
HT_API uint32 get_default_if_mask()
|
||
|
|
{
|
||
|
|
return get_route_if_mask(0);
|
||
|
|
}
|
||
|
|
|
||
|
|
HT_API int is_local_if_net(uint32 destip)
|
||
|
|
{
|
||
|
|
int i;
|
||
|
|
int nums;
|
||
|
|
|
||
|
|
if (destip == inet_addr("127.0.0.1"))
|
||
|
|
{
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
nums = get_if_nums();
|
||
|
|
|
||
|
|
for (i = 0; i < nums; i++)
|
||
|
|
{
|
||
|
|
uint32 ip = get_if_ip(i);
|
||
|
|
uint32 mask = get_if_mask(i);
|
||
|
|
|
||
|
|
if ((ip & mask) == (destip & mask))
|
||
|
|
{
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
HT_API int get_default_if_mac(uint8 * mac)
|
||
|
|
{
|
||
|
|
#ifdef IOS
|
||
|
|
|
||
|
|
#elif __WINDOWS_OS__
|
||
|
|
|
||
|
|
IP_ADAPTER_INFO AdapterInfo[16]; // Allocate information for up to 16 NICs
|
||
|
|
DWORD dwBufLen = sizeof(AdapterInfo); // Save the memory size of buffer
|
||
|
|
|
||
|
|
DWORD dwStatus = GetAdaptersInfo( // Call GetAdapterInfo
|
||
|
|
AdapterInfo, // [out] buffer to receive data
|
||
|
|
&dwBufLen); // [in] size of receive data buffer
|
||
|
|
|
||
|
|
PIP_ADAPTER_INFO pAdapterInfo = AdapterInfo;// Contains pointer to current adapter info
|
||
|
|
if (pAdapterInfo)
|
||
|
|
{
|
||
|
|
memcpy(mac, pAdapterInfo->Address, 6);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
#elif __LINUX_OS__
|
||
|
|
|
||
|
|
int i;
|
||
|
|
SOCKET socket_fd;
|
||
|
|
struct ifreq *ifr;
|
||
|
|
struct ifreq ifreq;
|
||
|
|
struct ifconf conf;
|
||
|
|
char buff[BUFSIZ];
|
||
|
|
int num;
|
||
|
|
|
||
|
|
socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||
|
|
|
||
|
|
conf.ifc_len = BUFSIZ;
|
||
|
|
conf.ifc_buf = buff;
|
||
|
|
|
||
|
|
ioctl(socket_fd, SIOCGIFCONF, &conf);
|
||
|
|
|
||
|
|
num = conf.ifc_len / sizeof(struct ifreq);
|
||
|
|
ifr = conf.ifc_req;
|
||
|
|
|
||
|
|
for (i=0; i<num; i++)
|
||
|
|
{
|
||
|
|
if (ifr->ifr_addr.sa_family != AF_INET)
|
||
|
|
{
|
||
|
|
ifr++;
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
ioctl(socket_fd, SIOCGIFFLAGS, ifr);
|
||
|
|
|
||
|
|
if ((ifr->ifr_flags & IFF_LOOPBACK) != 0)
|
||
|
|
{
|
||
|
|
ifr++;
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
strcpy(ifreq.ifr_name, ifr->ifr_name);
|
||
|
|
|
||
|
|
if (ioctl(socket_fd, SIOCGIFHWADDR, &ifreq) < 0)
|
||
|
|
{
|
||
|
|
ifr++;
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
memcpy(mac, &ifreq.ifr_hwaddr.sa_data, 6);
|
||
|
|
|
||
|
|
close(socket_fd);
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
close(socket_fd);
|
||
|
|
#endif
|
||
|
|
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
HT_API const char * get_default_gateway()
|
||
|
|
{
|
||
|
|
static char gateway[32];
|
||
|
|
|
||
|
|
#if __WINDOWS_OS__
|
||
|
|
|
||
|
|
IP_ADAPTER_INFO AdapterInfo[16]; // Allocate information for up to 16 NICs
|
||
|
|
DWORD dwBufLen = sizeof(AdapterInfo); // Save the memory size of buffer
|
||
|
|
|
||
|
|
DWORD dwStatus = GetAdaptersInfo( // Call GetAdapterInfo
|
||
|
|
AdapterInfo, // [out] buffer to receive data
|
||
|
|
&dwBufLen); // [in] size of receive data buffer
|
||
|
|
|
||
|
|
PIP_ADAPTER_INFO pAdapterInfo = AdapterInfo;// Contains pointer to current adapter info
|
||
|
|
if (NULL == pAdapterInfo)
|
||
|
|
{
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
memset(gateway, 0, sizeof(gateway));
|
||
|
|
|
||
|
|
while (pAdapterInfo)
|
||
|
|
{
|
||
|
|
if (strcmp(pAdapterInfo->GatewayList.IpAddress.String, "0.0.0.0"))
|
||
|
|
{
|
||
|
|
strncpy(gateway, pAdapterInfo->GatewayList.IpAddress.String, sizeof(gateway)-1);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
pAdapterInfo = pAdapterInfo->Next;
|
||
|
|
}
|
||
|
|
|
||
|
|
#elif __LINUX_OS__
|
||
|
|
|
||
|
|
char line[100], *p, *c, *g, *saveptr;
|
||
|
|
int ret = 0;
|
||
|
|
|
||
|
|
FILE *fp = fopen("/proc/net/route" , "r");
|
||
|
|
if (NULL == fp)
|
||
|
|
{
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
memset(gateway, 0, sizeof(gateway));
|
||
|
|
|
||
|
|
while (fgets(line, 100, fp))
|
||
|
|
{
|
||
|
|
p = strtok_r(line, " \t", &saveptr);
|
||
|
|
c = strtok_r(NULL, " \t", &saveptr);
|
||
|
|
g = strtok_r(NULL, " \t", &saveptr);
|
||
|
|
|
||
|
|
if (p != NULL && c != NULL)
|
||
|
|
{
|
||
|
|
if (strcmp(c, "00000000") == 0)
|
||
|
|
{
|
||
|
|
if (g)
|
||
|
|
{
|
||
|
|
char *p_end;
|
||
|
|
int gw = strtol(g, &p_end, 16);
|
||
|
|
|
||
|
|
struct in_addr addr;
|
||
|
|
addr.s_addr = gw;
|
||
|
|
|
||
|
|
strcpy(gateway, inet_ntoa(addr));
|
||
|
|
ret = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
fclose(fp);
|
||
|
|
|
||
|
|
if (ret == 0)
|
||
|
|
{
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
#endif
|
||
|
|
|
||
|
|
return gateway;
|
||
|
|
}
|
||
|
|
|
||
|
|
HT_API const char * get_dns_server()
|
||
|
|
{
|
||
|
|
static char dns[32] = {'\0'};
|
||
|
|
|
||
|
|
#if __WINDOWS_OS__
|
||
|
|
|
||
|
|
IP_ADAPTER_ADDRESSES addr[16], *paddr;
|
||
|
|
DWORD len = sizeof(addr);
|
||
|
|
|
||
|
|
memset(dns, 0, sizeof(dns));
|
||
|
|
|
||
|
|
if (NO_ERROR == GetAdaptersAddresses(AF_INET, 0, 0, addr, &len) && len >= sizeof(IP_ADAPTER_ADDRESSES))
|
||
|
|
{
|
||
|
|
paddr = addr;
|
||
|
|
|
||
|
|
while (paddr)
|
||
|
|
{
|
||
|
|
PIP_ADAPTER_DNS_SERVER_ADDRESS p_ipaddr;
|
||
|
|
|
||
|
|
if (paddr->IfType & IF_TYPE_SOFTWARE_LOOPBACK)
|
||
|
|
{
|
||
|
|
paddr = paddr->Next;
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
p_ipaddr = paddr->FirstDnsServerAddress;
|
||
|
|
if (p_ipaddr)
|
||
|
|
{
|
||
|
|
struct sockaddr_in * p_inaddr = (struct sockaddr_in *)p_ipaddr->Address.lpSockaddr;
|
||
|
|
strcpy(dns, inet_ntoa(p_inaddr->sin_addr));
|
||
|
|
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
paddr = paddr->Next;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#elif __LINUX_OS__
|
||
|
|
|
||
|
|
uint32 i;
|
||
|
|
char line[100] = {'\0'};
|
||
|
|
char * p;
|
||
|
|
FILE * fp;
|
||
|
|
|
||
|
|
memset(dns, 0, sizeof(dns));
|
||
|
|
|
||
|
|
fp = fopen("/etc/resolv.conf" , "r");
|
||
|
|
if (NULL == fp)
|
||
|
|
{
|
||
|
|
log_print(HT_LOG_ERR, "open file /etc/resolv.conf failed\r\n");
|
||
|
|
return dns;
|
||
|
|
}
|
||
|
|
|
||
|
|
while (fgets(line, 100, fp))
|
||
|
|
{
|
||
|
|
p = line;
|
||
|
|
|
||
|
|
while (*p == ' ') p++; // skip space
|
||
|
|
|
||
|
|
if (strncasecmp(p, "nameserver", 10) != 0)
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
p += 10;
|
||
|
|
|
||
|
|
while (*p == ' ') p++; // skip space
|
||
|
|
|
||
|
|
i = 0;
|
||
|
|
|
||
|
|
while (*p != '\0')
|
||
|
|
{
|
||
|
|
if (*p == ' ' || *p == '\n')
|
||
|
|
{
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (i < sizeof(dns) - 1)
|
||
|
|
{
|
||
|
|
dns[i++] = *p++;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
dns[i] = '\0';
|
||
|
|
|
||
|
|
if (is_ip_address(dns))
|
||
|
|
{
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
dns[0] = '\0';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
return dns;
|
||
|
|
}
|
||
|
|
|
||
|
|
HT_API const char * get_mask_by_prefix_len(int len)
|
||
|
|
{
|
||
|
|
int i;
|
||
|
|
static char mask_str[32] = {'\0'};
|
||
|
|
uint32 mask = 0;
|
||
|
|
|
||
|
|
len = (len > 32 ? 32 : len);
|
||
|
|
|
||
|
|
for (i = 0; i < len; i++)
|
||
|
|
{
|
||
|
|
mask |= (1 << (31 - i));
|
||
|
|
}
|
||
|
|
|
||
|
|
memset(mask_str, 0, sizeof(mask_str));
|
||
|
|
snprintf(mask_str, sizeof(mask_str), "%u.%u.%u.%u", (mask & 0xFF000000) >> 24, (mask & 0x00FF0000) >> 16,
|
||
|
|
(mask & 0x0000FF00) >> 8, (mask & 0x000000FF));
|
||
|
|
|
||
|
|
return mask_str;
|
||
|
|
}
|
||
|
|
|
||
|
|
HT_API int get_prefix_len_by_mask(const char * mask)
|
||
|
|
{
|
||
|
|
int i;
|
||
|
|
int len = 0;
|
||
|
|
uint32 n = inet_addr(mask);
|
||
|
|
|
||
|
|
n = ntohl(n);
|
||
|
|
|
||
|
|
for (i = 0; i < 32; i++)
|
||
|
|
{
|
||
|
|
if (n & ((uint32)1 << (31 - i)))
|
||
|
|
{
|
||
|
|
len++;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return len;
|
||
|
|
}
|
||
|
|
|
||
|
|
HT_API const char * get_ip_str(uint32 ipaddr /* network byte order */)
|
||
|
|
{
|
||
|
|
struct in_addr addr;
|
||
|
|
|
||
|
|
addr.s_addr = ipaddr;
|
||
|
|
|
||
|
|
return inet_ntoa(addr);
|
||
|
|
}
|
||
|
|
|
||
|
|
HT_API uint32 get_address_by_name(const char * host_name)
|
||
|
|
{
|
||
|
|
uint32 addr = 0;
|
||
|
|
|
||
|
|
if (is_ip_address(host_name))
|
||
|
|
{
|
||
|
|
addr = inet_addr(host_name);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
struct hostent * remoteHost = gethostbyname(host_name);
|
||
|
|
if (remoteHost)
|
||
|
|
{
|
||
|
|
addr = *(unsigned long *)(remoteHost->h_addr);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return addr;
|
||
|
|
}
|
||
|
|
|
||
|
|
HT_API char * lowercase(char * str)
|
||
|
|
{
|
||
|
|
uint32 i;
|
||
|
|
|
||
|
|
for (i = 0; i < strlen(str); ++i)
|
||
|
|
{
|
||
|
|
str[i] = tolower(str[i]);
|
||
|
|
}
|
||
|
|
|
||
|
|
return str;
|
||
|
|
}
|
||
|
|
|
||
|
|
HT_API char * uppercase(char * str)
|
||
|
|
{
|
||
|
|
uint32 i;
|
||
|
|
|
||
|
|
for (i = 0; i < strlen(str); ++i)
|
||
|
|
{
|
||
|
|
str[i] = toupper(str[i]);
|
||
|
|
}
|
||
|
|
|
||
|
|
return str;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
HT_API int unicode(char ** dst, char * src)
|
||
|
|
{
|
||
|
|
char *ret;
|
||
|
|
int l, i;
|
||
|
|
|
||
|
|
if (!src)
|
||
|
|
{
|
||
|
|
*dst = NULL;
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
l = MIN(64, (int)strlen(src));
|
||
|
|
ret = (char *)malloc(2*l);
|
||
|
|
if (NULL == ret)
|
||
|
|
{
|
||
|
|
*dst = NULL;
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
for (i = 0; i < l; ++i)
|
||
|
|
{
|
||
|
|
ret[2*i] = src[i];
|
||
|
|
ret[2*i+1] = '\0';
|
||
|
|
}
|
||
|
|
|
||
|
|
*dst = ret;
|
||
|
|
|
||
|
|
return 2*l;
|
||
|
|
}
|
||
|
|
|
||
|
|
HT_API BOOL bin_to_hex_str(uint8 * bin, int binlen, char * hex, int hexlen)
|
||
|
|
{
|
||
|
|
uint16 i;
|
||
|
|
uint8 j;
|
||
|
|
|
||
|
|
if (hexlen <= binlen*2)
|
||
|
|
{
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
for (i = 0; i < binlen; i++)
|
||
|
|
{
|
||
|
|
j = (bin[i] >> 4) & 0xf;
|
||
|
|
|
||
|
|
if (j <= 9)
|
||
|
|
{
|
||
|
|
hex[i*2] = (j + '0');
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
hex[i*2] = (j + 'a' - 10);
|
||
|
|
}
|
||
|
|
|
||
|
|
j = bin[i] & 0xf;
|
||
|
|
|
||
|
|
if (j <= 9)
|
||
|
|
{
|
||
|
|
hex[i*2+1] = (j + '0');
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
hex[i*2+1] = (j + 'a' - 10);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
hex[binlen*2] = '\0';
|
||
|
|
|
||
|
|
return TRUE;
|
||
|
|
};
|
||
|
|
|
||
|
|
HT_API int hex_str_to_bin(char * hex, int hexlen, uint8 * bin, int binlen)
|
||
|
|
{
|
||
|
|
int i;
|
||
|
|
|
||
|
|
if (binlen < hexlen/2)
|
||
|
|
{
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
for (i=0; i<hexlen/2; i++)
|
||
|
|
{
|
||
|
|
if (hex[i*2] >= '0' && hex[i*2] <= '9')
|
||
|
|
{
|
||
|
|
bin[i] = (hex[i*2] - '0') << 4;
|
||
|
|
}
|
||
|
|
else if (hex[i*2] >= 'a' && hex[i*2] <= 'z')
|
||
|
|
{
|
||
|
|
bin[i] = (hex[i*2] - 'a' + 10) << 4;
|
||
|
|
}
|
||
|
|
else if (hex[i*2] >= 'A' && hex[i*2] <= 'Z')
|
||
|
|
{
|
||
|
|
bin[i] = (hex[i*2] - 'A' + 10) << 4;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (hex[i*2+1] >= '0' && hex[i*2+1] <= '9')
|
||
|
|
{
|
||
|
|
bin[i] |= (hex[i*2+1] - '0');
|
||
|
|
}
|
||
|
|
else if (hex[i*2+1] >= 'a' && hex[i*2+1] <= 'z')
|
||
|
|
{
|
||
|
|
bin[i] |= hex[i*2+1] - 'a' + 10;
|
||
|
|
}
|
||
|
|
else if (hex[i*2+1] >= 'A' && hex[i*2+1] <= 'Z')
|
||
|
|
{
|
||
|
|
bin[i] |= hex[i*2+1] - 'A' + 10;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return i;
|
||
|
|
}
|
||
|
|
|
||
|
|
static char hextab[17] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 0};
|
||
|
|
|
||
|
|
HT_API int url_encode(const char * src, const int srcsize, char * dst, const int dstsize)
|
||
|
|
{
|
||
|
|
int i;
|
||
|
|
int j;
|
||
|
|
char ch;
|
||
|
|
|
||
|
|
if ((NULL == src) || (NULL == dst) || (srcsize <= 0) || (dstsize <= 0))
|
||
|
|
{
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
for (i = 0, j = 0; i < srcsize && j < dstsize; ++i)
|
||
|
|
{
|
||
|
|
ch = src[i];
|
||
|
|
|
||
|
|
if (((ch >= 'A') && (ch <= 'Z')) ||
|
||
|
|
((ch >= 'a') && (ch <= 'z')) ||
|
||
|
|
((ch >= '0') && (ch <= '9')) ||
|
||
|
|
ch == '.' || ch == '-' || ch == '_' || ch == '*')
|
||
|
|
{
|
||
|
|
dst[j++] = ch;
|
||
|
|
}
|
||
|
|
else if (ch == ' ')
|
||
|
|
{
|
||
|
|
dst[j++] = '+';
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if (j+3 < dstsize)
|
||
|
|
{
|
||
|
|
dst[j] = '%';
|
||
|
|
dst[j+1] = hextab[ch >> 4];
|
||
|
|
dst[j+2] = hextab[ch & 15];
|
||
|
|
|
||
|
|
j+=3;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
dst[j] = '\0';
|
||
|
|
|
||
|
|
return j;
|
||
|
|
}
|
||
|
|
|
||
|
|
HT_API int url_decode(char * dst, char const * src, uint32 len)
|
||
|
|
{
|
||
|
|
char * p_dst = dst;
|
||
|
|
const char * p_src = src;
|
||
|
|
|
||
|
|
while (len > 0)
|
||
|
|
{
|
||
|
|
int before = 0;
|
||
|
|
int after = 0;
|
||
|
|
|
||
|
|
if (*p_src == '+')
|
||
|
|
{
|
||
|
|
++p_src;
|
||
|
|
--len;
|
||
|
|
*p_dst++ = ' ';
|
||
|
|
}
|
||
|
|
else if (*p_src == '%' && len >= 3 && sscanf(p_src+1, "%n%2hhx%n", &before, p_dst, &after) == 1)
|
||
|
|
{
|
||
|
|
uint32 size = after - before; // should be 1 or 2
|
||
|
|
|
||
|
|
++p_dst;
|
||
|
|
p_src += (1 + size);
|
||
|
|
len -= (1 + size);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
*p_dst++ = *p_src++;
|
||
|
|
--len;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
*p_dst = '\0';
|
||
|
|
|
||
|
|
return (int)(p_dst - dst);
|
||
|
|
}
|
||
|
|
|
||
|
|
void url_split(char const* url, char *proto, int proto_size,
|
||
|
|
char *user, int user_size,
|
||
|
|
char *pass, int pass_size,
|
||
|
|
char *host, int host_size,
|
||
|
|
int *port, char *path, int path_size)
|
||
|
|
{
|
||
|
|
uint32 len;
|
||
|
|
const char *p, *ls, *ls2, *at, *col, *brk;
|
||
|
|
|
||
|
|
if (port)
|
||
|
|
*port = -1;
|
||
|
|
if (proto_size > 0)
|
||
|
|
proto[0] = 0;
|
||
|
|
if (user_size > 0)
|
||
|
|
user[0] = 0;
|
||
|
|
if (pass_size > 0)
|
||
|
|
pass[0] = 0;
|
||
|
|
if (host_size > 0)
|
||
|
|
host[0] = 0;
|
||
|
|
if (path_size > 0)
|
||
|
|
path[0] = 0;
|
||
|
|
|
||
|
|
/* parse protocol */
|
||
|
|
if ((p = strchr(url, ':')))
|
||
|
|
{
|
||
|
|
if (proto)
|
||
|
|
{
|
||
|
|
len = MIN(proto_size - 1, p - url);
|
||
|
|
strncpy(proto, url, len);
|
||
|
|
proto[len] = '\0';
|
||
|
|
}
|
||
|
|
|
||
|
|
p++; /* skip ':' */
|
||
|
|
if (*p == '/')
|
||
|
|
p++;
|
||
|
|
if (*p == '/')
|
||
|
|
p++;
|
||
|
|
}
|
||
|
|
else if (path)
|
||
|
|
{
|
||
|
|
/* no protocol means plain filename */
|
||
|
|
len = MIN(path_size - 1, (int)strlen(url));
|
||
|
|
strncpy(path, url, len);
|
||
|
|
path[len] = '\0';
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (NULL == p)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* separate path from hostname */
|
||
|
|
ls = strchr(p, '/');
|
||
|
|
ls2 = strchr(p, '?');
|
||
|
|
if (!ls)
|
||
|
|
ls = ls2;
|
||
|
|
else if (ls2)
|
||
|
|
ls = MIN(ls, ls2);
|
||
|
|
|
||
|
|
if (ls)
|
||
|
|
{
|
||
|
|
if (path)
|
||
|
|
{
|
||
|
|
len = MIN(path_size - 1, (int)strlen(ls));
|
||
|
|
strncpy(path, ls, len);
|
||
|
|
path[len] = '\0';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
ls = &p[strlen(p)]; // XXX
|
||
|
|
}
|
||
|
|
|
||
|
|
/* the rest is hostname, use that to parse auth/port */
|
||
|
|
if (ls != p)
|
||
|
|
{
|
||
|
|
/* authorization (user[:pass]@hostname) */
|
||
|
|
|
||
|
|
while ((at = strchr(p, '@')) && at < ls)
|
||
|
|
{
|
||
|
|
if ((brk = strchr(p, ':')) && brk < ls)
|
||
|
|
{
|
||
|
|
if (user)
|
||
|
|
{
|
||
|
|
url_decode(user, p, MIN(user_size-1, brk - p));
|
||
|
|
}
|
||
|
|
|
||
|
|
if (pass)
|
||
|
|
{
|
||
|
|
url_decode(pass, brk + 1, MIN(pass_size-1, at - brk - 1));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
p = at + 1; /* skip '@' */
|
||
|
|
}
|
||
|
|
|
||
|
|
if (*p == '[' && (brk = strchr(p, ']')) && brk < ls)
|
||
|
|
{
|
||
|
|
/* [host]:port */
|
||
|
|
if (host)
|
||
|
|
{
|
||
|
|
len = MIN(host_size - 1, brk - 1 - p);
|
||
|
|
strncpy(host, p + 1, len);
|
||
|
|
host[len] = '\0';
|
||
|
|
}
|
||
|
|
|
||
|
|
if (brk[1] == ':' && port)
|
||
|
|
{
|
||
|
|
*port = atoi(brk + 2);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if ((col = strchr(p, ':')) && col < ls)
|
||
|
|
{
|
||
|
|
if (host)
|
||
|
|
{
|
||
|
|
len = MIN(host_size - 1, col - p);
|
||
|
|
strncpy(host, p, len);
|
||
|
|
host[len] = '\0';
|
||
|
|
}
|
||
|
|
|
||
|
|
if (port)
|
||
|
|
{
|
||
|
|
*port = atoi(col + 1);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if (host)
|
||
|
|
{
|
||
|
|
len = MIN(host_size - 1, ls - p);
|
||
|
|
strncpy(host, p, len);
|
||
|
|
host[len] = '\0';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
HT_API time_t get_time_by_string(char * p_time_str)
|
||
|
|
{
|
||
|
|
char * ptr_s;
|
||
|
|
struct tm st;
|
||
|
|
|
||
|
|
memset(&st, 0, sizeof(struct tm));
|
||
|
|
|
||
|
|
ptr_s = p_time_str;
|
||
|
|
|
||
|
|
while (*ptr_s == ' ' || *ptr_s == '\t')
|
||
|
|
{
|
||
|
|
ptr_s++;
|
||
|
|
}
|
||
|
|
|
||
|
|
sscanf(ptr_s, "%04d-%02d-%02d %02d:%02d:%02d",
|
||
|
|
&st.tm_year, &st.tm_mon, &st.tm_mday,
|
||
|
|
&st.tm_hour, &st.tm_min, &st.tm_sec);
|
||
|
|
|
||
|
|
st.tm_year -= 1900;
|
||
|
|
st.tm_mon -= 1;
|
||
|
|
|
||
|
|
return mktime(&st);
|
||
|
|
}
|
||
|
|
|
||
|
|
HT_API void get_time_str(char * buff, int len)
|
||
|
|
{
|
||
|
|
time_t nowtime;
|
||
|
|
struct tm *t1;
|
||
|
|
|
||
|
|
time(&nowtime);
|
||
|
|
t1 = localtime(&nowtime);
|
||
|
|
|
||
|
|
snprintf(buff, len, "%04d-%02d-%02d %02d:%02d:%02d",
|
||
|
|
t1->tm_year+1900, t1->tm_mon+1, t1->tm_mday,
|
||
|
|
t1->tm_hour, t1->tm_min, t1->tm_sec);
|
||
|
|
}
|
||
|
|
|
||
|
|
HT_API void get_time_str_day_off(time_t nt, char * buff, int len, int dayoff)
|
||
|
|
{
|
||
|
|
struct tm *t1;
|
||
|
|
time_t nt1 = nt + dayoff * 24 * 3600;
|
||
|
|
|
||
|
|
t1 = localtime(&nt1);
|
||
|
|
|
||
|
|
snprintf(buff, len, "%04d-%02d-%02d %02d:%02d:%02d",
|
||
|
|
t1->tm_year+1900, t1->tm_mon+1, t1->tm_mday,
|
||
|
|
t1->tm_hour, t1->tm_min, t1->tm_sec);
|
||
|
|
}
|
||
|
|
|
||
|
|
HT_API void get_time_str_mon_off(time_t nt, char * buff, int len, int moffset)
|
||
|
|
{
|
||
|
|
struct tm *t1;
|
||
|
|
int year;
|
||
|
|
|
||
|
|
int day_of_month[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
|
||
|
|
|
||
|
|
t1 = localtime(&nt);
|
||
|
|
|
||
|
|
t1->tm_mon += moffset;
|
||
|
|
|
||
|
|
t1->tm_year += t1->tm_mon / 12;
|
||
|
|
t1->tm_mon = t1->tm_mon % 12;
|
||
|
|
|
||
|
|
year = t1->tm_year + 1900;
|
||
|
|
|
||
|
|
if ((year % 400) == 0 || ((year % 100) != 0 && (year % 4) == 0))
|
||
|
|
{
|
||
|
|
day_of_month[1] = 29;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (t1->tm_mday > day_of_month[t1->tm_mon])
|
||
|
|
{
|
||
|
|
t1->tm_mday = day_of_month[t1->tm_mon];
|
||
|
|
}
|
||
|
|
|
||
|
|
snprintf(buff, len, "%04d-%02d-%02d %02d:%02d:%02d",
|
||
|
|
t1->tm_year+1900, t1->tm_mon+1, t1->tm_mday,
|
||
|
|
t1->tm_hour, t1->tm_min, t1->tm_sec);
|
||
|
|
}
|
||
|
|
|
||
|
|
HT_API time_t get_time_by_tstring(const char * p_time_str)
|
||
|
|
{
|
||
|
|
const char * ptr_s;
|
||
|
|
struct tm st;
|
||
|
|
|
||
|
|
memset(&st, 0, sizeof(struct tm));
|
||
|
|
|
||
|
|
ptr_s = p_time_str;
|
||
|
|
|
||
|
|
while (*ptr_s == ' ' || *ptr_s == '\t')
|
||
|
|
{
|
||
|
|
ptr_s++;
|
||
|
|
}
|
||
|
|
|
||
|
|
sscanf(ptr_s, "%04d-%02d-%02dT%02d:%02d:%02d",
|
||
|
|
&st.tm_year, &st.tm_mon, &st.tm_mday,
|
||
|
|
&st.tm_hour, &st.tm_min, &st.tm_sec);
|
||
|
|
|
||
|
|
st.tm_year -= 1900;
|
||
|
|
st.tm_mon -= 1;
|
||
|
|
|
||
|
|
return mktime(&st);
|
||
|
|
}
|
||
|
|
|
||
|
|
HT_API void get_tstring_by_time(time_t t, char * buff, int len)
|
||
|
|
{
|
||
|
|
struct tm *t1;
|
||
|
|
|
||
|
|
t1 = localtime(&t);
|
||
|
|
|
||
|
|
snprintf(buff, len, "%04d-%02d-%02dT%02d:%02d:%02d",
|
||
|
|
t1->tm_year+1900, t1->tm_mon+1, t1->tm_mday,
|
||
|
|
t1->tm_hour, t1->tm_min, t1->tm_sec);
|
||
|
|
}
|
||
|
|
|
||
|
|
HT_API SOCKET tcp_connect(const char * hostname, int port, int timeout)
|
||
|
|
{
|
||
|
|
int ret;
|
||
|
|
SOCKET fd;
|
||
|
|
char portstr[10];
|
||
|
|
struct timeval tv;
|
||
|
|
struct addrinfo hints, *ai, *cur_ai;
|
||
|
|
|
||
|
|
hints.ai_family = AF_UNSPEC;
|
||
|
|
hints.ai_socktype = SOCK_STREAM;
|
||
|
|
|
||
|
|
snprintf(portstr, sizeof(portstr), "%d", port);
|
||
|
|
|
||
|
|
ret = getaddrinfo(hostname, portstr, &hints, &ai);
|
||
|
|
if (ret)
|
||
|
|
{
|
||
|
|
log_print(HT_LOG_ERR, "Failed to resolve hostname %s\r\n", hostname);
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
fd = -1;
|
||
|
|
|
||
|
|
for (cur_ai = ai; cur_ai; cur_ai = cur_ai->ai_next)
|
||
|
|
{
|
||
|
|
fd = socket(cur_ai->ai_family, cur_ai->ai_socktype, cur_ai->ai_protocol);
|
||
|
|
if (fd <= 0)
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
tv.tv_sec = timeout/1000;
|
||
|
|
tv.tv_usec = (timeout%1000) * 1000;
|
||
|
|
|
||
|
|
setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char*)&tv, sizeof(tv));
|
||
|
|
|
||
|
|
if (connect(fd, cur_ai->ai_addr, (int)(cur_ai->ai_addrlen)) < 0)
|
||
|
|
{
|
||
|
|
closesocket(fd);
|
||
|
|
fd = -1;
|
||
|
|
|
||
|
|
log_print(HT_LOG_ERR, "Connect hostname %s failed\r\n", hostname);
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
break; /* okay we got one */
|
||
|
|
}
|
||
|
|
|
||
|
|
freeaddrinfo(ai);
|
||
|
|
|
||
|
|
return fd;
|
||
|
|
}
|
||
|
|
|
||
|
|
HT_API SOCKET tcp_connect_timeout(uint32 rip, int port, int timeout)
|
||
|
|
{
|
||
|
|
SOCKET cfd;
|
||
|
|
struct sockaddr_in addr;
|
||
|
|
|
||
|
|
#if __LINUX_OS__
|
||
|
|
uint32 starttime = sys_os_get_ms();
|
||
|
|
struct timeval tv;
|
||
|
|
#elif __WINDOWS_OS__
|
||
|
|
int flag = 0;
|
||
|
|
unsigned long ul = 1;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
cfd = socket(AF_INET, SOCK_STREAM, 0);
|
||
|
|
if (cfd <= 0)
|
||
|
|
{
|
||
|
|
log_print(HT_LOG_ERR, "%s, socket failed\n", __FUNCTION__);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
addr.sin_family = AF_INET;
|
||
|
|
addr.sin_addr.s_addr = rip;
|
||
|
|
addr.sin_port = htons((uint16)port);
|
||
|
|
|
||
|
|
#if __LINUX_OS__
|
||
|
|
|
||
|
|
tv.tv_sec = timeout/1000;
|
||
|
|
tv.tv_usec = (timeout%1000) * 1000;
|
||
|
|
|
||
|
|
setsockopt(cfd, SOL_SOCKET, SO_SNDTIMEO, (char*)&tv, sizeof(tv));
|
||
|
|
|
||
|
|
while (connect(cfd, (struct sockaddr *)&addr, sizeof(addr)) == -1 && errno != EISCONN)
|
||
|
|
{
|
||
|
|
if (sys_os_get_ms() > starttime + timeout)
|
||
|
|
{
|
||
|
|
closesocket(cfd);
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (errno != EINTR)
|
||
|
|
{
|
||
|
|
closesocket(cfd);
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return cfd;
|
||
|
|
|
||
|
|
#elif __WINDOWS_OS__
|
||
|
|
|
||
|
|
ioctlsocket(cfd, FIONBIO, &ul);
|
||
|
|
|
||
|
|
if (connect(cfd, (struct sockaddr *)&addr, sizeof(addr)) != 0)
|
||
|
|
{
|
||
|
|
fd_set set;
|
||
|
|
struct timeval tv;
|
||
|
|
|
||
|
|
tv.tv_sec = timeout/1000;
|
||
|
|
tv.tv_usec = (timeout%1000) * 1000;
|
||
|
|
|
||
|
|
FD_ZERO(&set);
|
||
|
|
FD_SET(cfd, &set);
|
||
|
|
|
||
|
|
if (select((int)(cfd+1), NULL, &set, NULL, &tv) > 0)
|
||
|
|
{
|
||
|
|
int err = 0, len = sizeof(int);
|
||
|
|
|
||
|
|
getsockopt(cfd, SOL_SOCKET, SO_ERROR, (char *)&err, (socklen_t*) &len);
|
||
|
|
|
||
|
|
if (err == 0)
|
||
|
|
{
|
||
|
|
flag = 1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
flag = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
ul = 0;
|
||
|
|
ioctlsocket(cfd, FIONBIO, &ul);
|
||
|
|
|
||
|
|
if (flag == 1)
|
||
|
|
{
|
||
|
|
return cfd;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
closesocket(cfd);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
static int callCount = 0;
|
||
|
|
HT_API void network_init() {
|
||
|
|
callCount++;
|
||
|
|
log_print(HT_LOG_INFO, "Number of network_init called: %d,\n", callCount);
|
||
|
|
|
||
|
|
if (callCount == 1) { // Only initialize Winsock on the first call
|
||
|
|
log_print(HT_LOG_INFO, "Initialise network: %d,\n", callCount);
|
||
|
|
WSADATA wsaData;
|
||
|
|
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
|
||
|
|
// Handle initialization failure
|
||
|
|
log_print(HT_LOG_ERR, "%s, network_init failed\n", __FUNCTION__);//HT_LOG_INFO
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
// Function to deinitialize network resources (e.g., Winsock)
|
||
|
|
HT_API void network_deinit() {
|
||
|
|
if (callCount > 0) { // Ensure network has been initialized before deinitialization
|
||
|
|
callCount--;
|
||
|
|
log_print(HT_LOG_INFO, "Number of network_deinit called: %d,\n", callCount);
|
||
|
|
|
||
|
|
if (callCount == 0) { // Deinitialize Winsock if it's the last deinitialization
|
||
|
|
log_print(HT_LOG_INFO, "Deinitialize network\n");
|
||
|
|
if (WSACleanup() != 0) {
|
||
|
|
// Handle deinitialization failure
|
||
|
|
log_print(HT_LOG_ERR, "%s, network_deinit failed\n", __FUNCTION__);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
HT_API int daemon_init()
|
||
|
|
{
|
||
|
|
#if __LINUX_OS__
|
||
|
|
|
||
|
|
pid_t pid;
|
||
|
|
|
||
|
|
pid = fork();
|
||
|
|
|
||
|
|
if (pid == -1)
|
||
|
|
{
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
else if (pid > 0)
|
||
|
|
{
|
||
|
|
exit(0);
|
||
|
|
}
|
||
|
|
|
||
|
|
setsid();
|
||
|
|
|
||
|
|
#endif
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
#if __WINDOWS_OS__
|
||
|
|
|
||
|
|
#include <sys/timeb.h>
|
||
|
|
|
||
|
|
// used to make sure that static variables in gettimeofday() aren't
|
||
|
|
// initialized simultaneously by multiple threads
|
||
|
|
static long g_gettimeofday_lock = 0;
|
||
|
|
|
||
|
|
HT_API int gettimeofday(struct timeval * tp, int * tz)
|
||
|
|
{
|
||
|
|
static LARGE_INTEGER tickFrequency, epochOffset;
|
||
|
|
|
||
|
|
static BOOL isInitialized = FALSE;
|
||
|
|
|
||
|
|
LARGE_INTEGER tickNow;
|
||
|
|
|
||
|
|
QueryPerformanceCounter(&tickNow);
|
||
|
|
|
||
|
|
if (!isInitialized)
|
||
|
|
{
|
||
|
|
if (1 == InterlockedIncrement(&g_gettimeofday_lock))
|
||
|
|
{
|
||
|
|
// For our first call, use "ftime()", so that we get a time with a proper epoch.
|
||
|
|
// For subsequent calls, use "QueryPerformanceCount()", because it's more fine-grain.
|
||
|
|
struct timeb tb;
|
||
|
|
ftime(&tb);
|
||
|
|
|
||
|
|
tp->tv_sec = (long)tb.time;
|
||
|
|
tp->tv_usec = 1000*tb.millitm;
|
||
|
|
|
||
|
|
// Also get our counter frequency:
|
||
|
|
QueryPerformanceFrequency(&tickFrequency);
|
||
|
|
|
||
|
|
// compute an offset to add to subsequent counter times, so we get a proper epoch:
|
||
|
|
epochOffset.QuadPart = tp->tv_sec * tickFrequency.QuadPart + (tp->tv_usec * tickFrequency.QuadPart) / 1000000L - tickNow.QuadPart;
|
||
|
|
|
||
|
|
// next caller can use ticks for time calculation
|
||
|
|
isInitialized = TRUE;
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
InterlockedDecrement(&g_gettimeofday_lock);
|
||
|
|
|
||
|
|
// wait until first caller has initialized static values
|
||
|
|
while (!isInitialized)
|
||
|
|
{
|
||
|
|
Sleep(1);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// adjust our tick count so that we get a proper epoch:
|
||
|
|
tickNow.QuadPart += epochOffset.QuadPart;
|
||
|
|
|
||
|
|
tp->tv_sec = (long)(tickNow.QuadPart / tickFrequency.QuadPart);
|
||
|
|
tp->tv_usec = (long)(((tickNow.QuadPart % tickFrequency.QuadPart) * 1000000L) / tickFrequency.QuadPart);
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
#endif
|
||
|
|
|
||
|
|
|