Main/Assets/Plugins/iOS/IOSAddrInfo.mm

64 lines
2.0 KiB
Plaintext
Raw Permalink Normal View History

2025-01-25 04:38:09 +08:00
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <err.h>
#define OUTSTR_SIZE 4096
extern "C"
{
const char* copyStr( const char* str )
{
char* s = (char*)malloc(strlen(str) + 1);
strcpy(s, str);
return s;
}
const char* IOSGetAddressInfo(const char *host )
{
if( NULL == host )
return copyStr("ERROR_HOSTNULL");
char outstr[OUTSTR_SIZE];
struct addrinfo hints, *res, *res0;
memset(&hints, 0, sizeof(hints));
//AF_INET(只返回ipv4)AF_INET6(只返回ipv6)和AF_UNSPEC(函数返回的是适用于指定主机名和服务名且适合任何协议族的地址)
//如果某个主机既有AAAA记录(IPV6)地址同时又有A记录(IPV4)地址那么AAAA记录将作为sockaddr_in6结构返回而A记录则作为sockaddr_in结构返回
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_DEFAULT;
printf("getaddrinfo: %s\n", host);
//获取地址信息,这个函数支持ipv4和ipv6
int error = getaddrinfo(host, "http", &hints, &res0);
if (error != 0 )
{
printf("getaddrinfo: %s\n", gai_strerror(error));
return copyStr("ERROR_GETADDR");
}
memset( outstr, 0, sizeof(char)*OUTSTR_SIZE );
struct sockaddr_in6* addr6;
struct sockaddr_in* addr;
const char* solvedaddr;
char ipbuf[32];
for (res = res0; res; res = res->ai_next)
{
if (res->ai_family == AF_INET6)
{
addr6 =( struct sockaddr_in6*)res->ai_addr;
//把二进制的ip转换为点数格式的ip地址 ipv6格式
solvedaddr = inet_ntop(AF_INET6, &addr6->sin6_addr, ipbuf, sizeof(ipbuf));
strcat ( outstr, "ipv6|");
strcat ( outstr, solvedaddr);
}
else
{
addr =( struct sockaddr_in*)res->ai_addr;
//把二进制的ip转换为点数格式的ip地址 ipv4格式
solvedaddr = inet_ntop(AF_INET, &addr->sin_addr, ipbuf, sizeof(ipbuf));
strcat ( outstr, "ipv4|");
strcat ( outstr, solvedaddr);
}
strcat ( outstr, "|");
}
return copyStr(outstr);
}
}