11 static PIP_ADAPTER_ADDRESSES get_adaptorinfo(
int obufsize,
int tries) {
12 PIP_ADAPTER_ADDRESSES ainfo = NULL;
16 buflen = obufsize * i;
19 if (!(ainfo = (IP_ADAPTER_ADDRESSES *)malloc(buflen))) {
23 if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, ainfo, &buflen) == ERROR_BUFFER_OVERFLOW) {
43 const char *
inet_ntop(
int af,
const void *src,
char *dest, socklen_t size) {
46 char serv[NI_MAXSERV];
48 memset(&sa, 0,
sizeof(sa));
53 memcpy(&sa.
sa4.sin_addr, src,
sizeof(
struct in_addr));
54 res = getnameinfo(&sa.
sa,
sizeof(
struct sockaddr_in), dest, size, serv, NI_MAXSERV, NI_NUMERICHOST | NI_NUMERICSERV);
57 memcpy(&sa.
sa6.sin6_addr, src,
sizeof(
struct in6_addr));
58 res = getnameinfo(&sa.
sa,
sizeof(
struct sockaddr_in6), dest, size, serv, NI_MAXSERV, NI_NUMERICHOST | NI_NUMERICSERV);
61 return (!res) ? dest : NULL;
64 static void free_ifinfo(
void *data) {
68 free((
void*)ifinf->
ifaddr);
84 PIP_ADAPTER_ADDRESSES ainfo = NULL, cinfo;
85 PIP_ADAPTER_UNICAST_ADDRESS pUnicast;
86 struct sockaddr_storage *ss;
87 char tmphn[NI_MAXHOST];
88 char host4[NI_MAXHOST];
89 char host6[NI_MAXHOST];
90 int score4 = 0, score6 = 0, nscore;
91 struct ifinfo *ifinf = NULL;
93 if (!(ainfo = get_adaptorinfo(15000, 3))) {
97 for(cinfo = ainfo; cinfo; cinfo = cinfo->Next) {
98 if (strcmp(cinfo->AdapterName, iface)) {
102 if (!(ifinf = (
struct ifinfo*)
objalloc(
sizeof(*ifinf),free_ifinfo))) {
106 ifinf->
idx = (int)cinfo->IfIndex;
108 if (cinfo->PhysicalAddressLength == 6) {
112 for (i = 0; i < cinfo->PhysicalAddressLength; i++) {
113 if (i == (cinfo->PhysicalAddressLength - 1)) {
114 sprintf(tmp,
"%.2X", (
int)cinfo->PhysicalAddress[i]);
116 sprintf(tmp,
"%.2X:", (
int)cinfo->PhysicalAddress[i]);
120 ifinf->
ifaddr = strdup(tmp2);
125 for (pUnicast = cinfo->FirstUnicastAddress; pUnicast ;pUnicast = pUnicast->Next) {
126 ss = (
struct sockaddr_storage*)pUnicast->Address.lpSockaddr;
127 switch(ss->ss_family) {
129 nscore =
score_ipv4((
struct sockaddr_in*)ss, tmphn, NI_MAXHOST);
130 if (score4 < nscore) {
132 strcpy(host4, tmphn);
136 nscore =
score_ipv6((
struct sockaddr_in6*)ss, tmphn, NI_MAXHOST);
137 if (score6 < nscore) {
139 strcpy(host6, tmphn);
int strlenzero(const char *str)
Check if a string is zero length.
const char * ifaddr
MAC address of interface.
void * objalloc(int size, objdestroy)
Allocate a referenced lockable object.
Data structure containing interface information.
int score_ipv6(struct sockaddr_in6 *sa6, char *ipaddr, int iplen)
Return a score for a IPv6 addrress.
int idx
Interface index required for at least IPv6 multicast support.
struct ifinfo * get_ifinfo(const char *iface)
Return interface info for a specified interface.
int score_ipv4(struct sockaddr_in *sa4, char *ipaddr, int iplen)
Return a score for a IPv4 addrress.
DTS Application library API Include file.
const char * ipv6addr
IPv6 address priorised by Local/6in4.
const char * ipv4addr
IPv4 address priorotised by Routed/Reserved/Zeroconf.
struct sockaddr_in sa4
IPv4 socket addr structure.
struct sockaddr_storage ss
Sockaddr storage is a "magic" struct been able to hold IPv4 or IPv6.
struct sockaddr sa
Base socket addr structure.
const char * inet_ntop(int af, const void *src, char *dest, socklen_t size)
Win32 implementation of inet_ntop.
struct sockaddr_in6 sa6
IPv6 socket addr structure.
Socket union describing all address types.