DTS Application Library  0.2.3
Application library containing referenced objects and interfaces to common libraries
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Groups Pages
winiface.cpp
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdint.h>
3 #include "include/dtsapp.h"
4 
11 static PIP_ADAPTER_ADDRESSES get_adaptorinfo(int obufsize, int tries) {
12  PIP_ADAPTER_ADDRESSES ainfo = NULL;
13  int i = 1;
14  unsigned long buflen;
15 
16  buflen = obufsize * i;
17 
18  do {
19  if (!(ainfo = (IP_ADAPTER_ADDRESSES *)malloc(buflen))) {
20  return NULL;
21  }
22 
23  if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, ainfo, &buflen) == ERROR_BUFFER_OVERFLOW) {
24  free(ainfo);
25  ainfo = NULL;
26  } else {
27  break;
28  }
29 
30  i++;
31  } while (i <= tries);
32 
33  return ainfo;
34 }
35 
43 const char *inet_ntop(int af, const void *src, char *dest, socklen_t size) {
44  union sockstruct sa;
45  int res = 0;
46  char serv[NI_MAXSERV];
47 
48  memset(&sa, 0, sizeof(sa));
49  sa.ss.ss_family = af;
50 
51  switch(af) {
52  case AF_INET:
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);
55  break;
56  case AF_INET6:
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);
59  break;
60  }
61  return (!res) ? dest : NULL;
62 }
63 
64 static void free_ifinfo(void *data) {
65  struct ifinfo *ifinf = (struct ifinfo*)data;
66 
67  if (ifinf->ifaddr) {
68  free((void*)ifinf->ifaddr);
69  }
70  if (ifinf->ipv4addr) {
71  free((void*)ifinf->ipv4addr);
72  }
73  if (ifinf->ipv6addr) {
74  free((void*)ifinf->ipv6addr);
75  }
76 }
77 
78 
83 struct ifinfo *get_ifinfo(const char *iface) {
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;
92 
93  if (!(ainfo = get_adaptorinfo(15000, 3))) {
94  return NULL;
95  }
96 
97  for(cinfo = ainfo; cinfo; cinfo = cinfo->Next) {
98  if (strcmp(cinfo->AdapterName, iface)) {
99  continue;
100  }
101 
102  if (!(ifinf = (struct ifinfo*)objalloc(sizeof(*ifinf),free_ifinfo))) {
103  return NULL;
104  }
105 
106  ifinf->idx = (int)cinfo->IfIndex;
107 
108  if (cinfo->PhysicalAddressLength == 6) {
109  unsigned int i;
110  char tmp[4];
111  char tmp2[18] = "";
112  for (i = 0; i < cinfo->PhysicalAddressLength; i++) {
113  if (i == (cinfo->PhysicalAddressLength - 1)) {
114  sprintf(tmp,"%.2X", (int)cinfo->PhysicalAddress[i]);
115  } else {
116  sprintf(tmp,"%.2X:", (int)cinfo->PhysicalAddress[i]);
117  }
118  strcat(tmp2, tmp);
119  }
120  ifinf->ifaddr = strdup(tmp2);
121  } else {
122  ifinf->ifaddr = NULL;
123  }
124 
125  for (pUnicast = cinfo->FirstUnicastAddress; pUnicast ;pUnicast = pUnicast->Next) {
126  ss = (struct sockaddr_storage*)pUnicast->Address.lpSockaddr;
127  switch(ss->ss_family) {
128  case AF_INET:
129  nscore = score_ipv4((struct sockaddr_in*)ss, tmphn, NI_MAXHOST);
130  if (score4 < nscore) {
131  score4 = nscore;
132  strcpy(host4, tmphn);
133  }
134  break;
135  case AF_INET6:
136  nscore = score_ipv6((struct sockaddr_in6*)ss, tmphn, NI_MAXHOST);
137  if (score6 < nscore) {
138  score6 = nscore;
139  strcpy(host6, tmphn);
140  }
141  break;
142  }
143  }
144  ifinf->ipv4addr = (strlenzero(host4)) ? NULL : strdup(host4);
145  ifinf->ipv6addr = (strlenzero(host6)) ? NULL : strdup(host6);
146  break;
147  }
148 
149  if (ainfo) {
150  free(ainfo);
151  }
152 
153  return ifinf;
154 }
155 
156 
int strlenzero(const char *str)
Check if a string is zero length.
Definition: util.c:341
const char * ifaddr
MAC address of interface.
Definition: dtsapp.h:180
void * objalloc(int size, objdestroy)
Allocate a referenced lockable object.
Definition: refobj.c:129
Data structure containing interface information.
Definition: dtsapp.h:176
int score_ipv6(struct sockaddr_in6 *sa6, char *ipaddr, int iplen)
Return a score for a IPv6 addrress.
Definition: interface.c:746
int idx
Interface index required for at least IPv6 multicast support.
Definition: dtsapp.h:178
struct ifinfo * get_ifinfo(const char *iface)
Return interface info for a specified interface.
Definition: winiface.cpp:83
int score_ipv4(struct sockaddr_in *sa4, char *ipaddr, int iplen)
Return a score for a IPv4 addrress.
Definition: interface.c:718
DTS Application library API Include file.
const char * ipv6addr
IPv6 address priorised by Local/6in4.
Definition: dtsapp.h:184
const char * ipv4addr
IPv4 address priorotised by Routed/Reserved/Zeroconf.
Definition: dtsapp.h:182
struct sockaddr_in sa4
IPv4 socket addr structure.
Definition: dtsapp.h:88
struct sockaddr_storage ss
Sockaddr storage is a &quot;magic&quot; struct been able to hold IPv4 or IPv6.
Definition: dtsapp.h:92
struct sockaddr sa
Base socket addr structure.
Definition: dtsapp.h:82
const char * inet_ntop(int af, const void *src, char *dest, socklen_t size)
Win32 implementation of inet_ntop.
Definition: winiface.cpp:43
struct sockaddr_in6 sa6
IPv6 socket addr structure.
Definition: dtsapp.h:90
Socket union describing all address types.
Definition: dtsapp.h:80