diff options
author | Christian Grothoff <christian@grothoff.org> | 2011-11-29 11:47:40 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2011-11-29 11:47:40 +0000 |
commit | d155690a24d645e746d7cd12e5c1d47646d96558 (patch) | |
tree | 657f47d48cf70950ba240ebc0414a71f6cac6bed | |
parent | ba232c9d203303cd2beb2994fc49c5d5b700d85c (diff) | |
download | gnunet-d155690a24d645e746d7cd12e5c1d47646d96558.tar.gz gnunet-d155690a24d645e746d7cd12e5c1d47646d96558.zip |
LRN: new code for GNUNET_OS_network_interfaces_list on W32 improving support for IPv6 and subnets/masks, see Mantis 1958
-rw-r--r-- | src/include/winproc.h | 27 | ||||
-rw-r--r-- | src/util/Makefile.am | 2 | ||||
-rw-r--r-- | src/util/os_network.c | 135 | ||||
-rw-r--r-- | src/util/win.cc | 693 | ||||
-rw-r--r-- | src/util/winproc.c | 14 |
5 files changed, 618 insertions, 253 deletions
diff --git a/src/include/winproc.h b/src/include/winproc.h index 05c4ac1bf..ac4eecdfb 100644 --- a/src/include/winproc.h +++ b/src/include/winproc.h | |||
@@ -62,6 +62,10 @@ extern "C" | |||
62 | PULONG pdwSize, BOOL bOrder); | 62 | PULONG pdwSize, BOOL bOrder); |
63 | typedef DWORD WINAPI (*TGetIfTable) (PMIB_IFTABLE pIfTable, PULONG pdwSize, | 63 | typedef DWORD WINAPI (*TGetIfTable) (PMIB_IFTABLE pIfTable, PULONG pdwSize, |
64 | BOOL bOrder); | 64 | BOOL bOrder); |
65 | typedef DWORD WINAPI (*TGetBestInterfaceEx) (struct sockaddr *, PDWORD); | ||
66 | /* TODO: Explicitly import -A variants (i.e. TCreateHardLinkA) or -W | ||
67 | * variants (TCreateHardLinkW), etc. | ||
68 | */ | ||
65 | typedef DWORD WINAPI (*TCreateHardLink) (LPCTSTR lpFileName, | 69 | typedef DWORD WINAPI (*TCreateHardLink) (LPCTSTR lpFileName, |
66 | LPCTSTR lpExistingFileName, | 70 | LPCTSTR lpExistingFileName, |
67 | LPSECURITY_ATTRIBUTES | 71 | LPSECURITY_ATTRIBUTES |
@@ -99,8 +103,6 @@ extern "C" | |||
99 | typedef SC_HANDLE WINAPI (*TOpenService) (SC_HANDLE hSCManager, | 103 | typedef SC_HANDLE WINAPI (*TOpenService) (SC_HANDLE hSCManager, |
100 | LPCTSTR lpServiceName, | 104 | LPCTSTR lpServiceName, |
101 | DWORD dwDesiredAccess); | 105 | DWORD dwDesiredAccess); |
102 | typedef DWORD WINAPI (*TGetBestInterface) (IPAddr dwDestAddr, | ||
103 | PDWORD pdwBestIfIndex); | ||
104 | typedef DWORD WINAPI (*TGetAdaptersInfo) (PIP_ADAPTER_INFO pAdapterInfo, | 106 | typedef DWORD WINAPI (*TGetAdaptersInfo) (PIP_ADAPTER_INFO pAdapterInfo, |
105 | PULONG pOutBufLen); | 107 | PULONG pOutBufLen); |
106 | typedef NET_API_STATUS WINAPI (*TNetUserAdd) (LPCWSTR, DWORD, PBYTE, PDWORD); | 108 | typedef NET_API_STATUS WINAPI (*TNetUserAdd) (LPCWSTR, DWORD, PBYTE, PDWORD); |
@@ -158,6 +160,7 @@ extern "C" | |||
158 | PSID psidGroup, PACL pDacl, | 160 | PSID psidGroup, PACL pDacl, |
159 | PACL pSacl); | 161 | PACL pSacl); |
160 | 162 | ||
163 | extern TGetBestInterfaceEx GNGetBestInterfaceEx; | ||
161 | extern TNtQuerySystemInformation GNNtQuerySystemInformation; | 164 | extern TNtQuerySystemInformation GNNtQuerySystemInformation; |
162 | extern TGetIfEntry GNGetIfEntry; | 165 | extern TGetIfEntry GNGetIfEntry; |
163 | extern TGetIpAddrTable GNGetIpAddrTable; | 166 | extern TGetIpAddrTable GNGetIpAddrTable; |
@@ -172,8 +175,7 @@ extern "C" | |||
172 | extern TStartServiceCtrlDispatcher GNStartServiceCtrlDispatcher; | 175 | extern TStartServiceCtrlDispatcher GNStartServiceCtrlDispatcher; |
173 | extern TControlService GNControlService; | 176 | extern TControlService GNControlService; |
174 | extern TOpenService GNOpenService; | 177 | extern TOpenService GNOpenService; |
175 | extern TGetBestInterface GNGetBestInterface; | 178 | extern TGetAdaptersInfo GNGetAdaptersInfo; |
176 | extern TGetAdaptersInfo GGetAdaptersInfo; | ||
177 | extern TNetUserAdd GNNetUserAdd; | 179 | extern TNetUserAdd GNNetUserAdd; |
178 | extern TNetUserSetInfo GNNetUserSetInfo; | 180 | extern TNetUserSetInfo GNNetUserSetInfo; |
179 | extern TLsaOpenPolicy GNLsaOpenPolicy; | 181 | extern TLsaOpenPolicy GNLsaOpenPolicy; |
@@ -202,6 +204,23 @@ extern "C" | |||
202 | DWORD dwAccessMask); | 204 | DWORD dwAccessMask); |
203 | char *winErrorStr (const char *prefix, int dwErr); | 205 | char *winErrorStr (const char *prefix, int dwErr); |
204 | void EnumNICs (PMIB_IFTABLE * pIfTable, PMIB_IPADDRTABLE * pAddrTable); | 206 | void EnumNICs (PMIB_IFTABLE * pIfTable, PMIB_IPADDRTABLE * pAddrTable); |
207 | |||
208 | #define ENUMNICS3_MASK_OK 0x01 | ||
209 | #define ENUMNICS3_BCAST_OK 0x02 | ||
210 | |||
211 | struct EnumNICs3_results | ||
212 | { | ||
213 | unsigned char flags; | ||
214 | int is_default; | ||
215 | char pretty_name[1001]; | ||
216 | size_t addr_size; | ||
217 | struct sockaddr address; | ||
218 | struct sockaddr mask; | ||
219 | struct sockaddr broadcast; | ||
220 | }; | ||
221 | |||
222 | int EnumNICs3 (struct EnumNICs3_results **, int *EnumNICs3_results_count); | ||
223 | void EnumNICs3_free (struct EnumNICs3_results *); | ||
205 | int GNInitWinEnv (); | 224 | int GNInitWinEnv (); |
206 | void GNShutdownWinEnv (); | 225 | void GNShutdownWinEnv (); |
207 | 226 | ||
diff --git a/src/util/Makefile.am b/src/util/Makefile.am index c62fc4246..a2e7f2449 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am | |||
@@ -17,7 +17,7 @@ libgnunetutilwin_la_LDFLAGS = \ | |||
17 | -no-undefined -Wl,--export-all-symbols | 17 | -no-undefined -Wl,--export-all-symbols |
18 | libgnunetutilwin_la_LIBADD = \ | 18 | libgnunetutilwin_la_LIBADD = \ |
19 | -lshell32 -liconv -lstdc++ \ | 19 | -lshell32 -liconv -lstdc++ \ |
20 | -lcomdlg32 -lgdi32 | 20 | -lcomdlg32 -lgdi32 -liphlpapi |
21 | WINLIB = libgnunetutilwin.la | 21 | WINLIB = libgnunetutilwin.la |
22 | endif | 22 | endif |
23 | 23 | ||
diff --git a/src/util/os_network.c b/src/util/os_network.c index 54a4e7577..a4758496e 100644 --- a/src/util/os_network.c +++ b/src/util/os_network.c | |||
@@ -25,6 +25,7 @@ | |||
25 | * @author Nils Durner | 25 | * @author Nils Durner |
26 | * @author Heikki Lindholm | 26 | * @author Heikki Lindholm |
27 | * @author Jake Dust | 27 | * @author Jake Dust |
28 | * @author LRN | ||
28 | */ | 29 | */ |
29 | 30 | ||
30 | #include "platform.h" | 31 | #include "platform.h" |
@@ -46,128 +47,26 @@ GNUNET_OS_network_interfaces_list (GNUNET_OS_NetworkInterfaceProcessor proc, | |||
46 | void *proc_cls) | 47 | void *proc_cls) |
47 | { | 48 | { |
48 | #ifdef MINGW | 49 | #ifdef MINGW |
49 | PMIB_IFTABLE pTable; | 50 | int r; |
50 | PMIB_IPADDRTABLE pAddrTable; | 51 | int i; |
51 | DWORD dwIfIdx, dwExternalNIC; | 52 | struct EnumNICs3_results *results = NULL; |
52 | IPAddr theIP; | 53 | int results_count; |
53 | 54 | ||
54 | /* Determine our external NIC */ | 55 | r = EnumNICs3 (&results, &results_count); |
55 | theIP = inet_addr ("192.0.34.166"); /* www.example.com */ | 56 | if (r != GNUNET_OK) |
56 | if ((!GNGetBestInterface) || | 57 | return; |
57 | (GNGetBestInterface (theIP, &dwExternalNIC) != NO_ERROR)) | ||
58 | { | ||
59 | dwExternalNIC = 0; | ||
60 | } | ||
61 | |||
62 | /* Enumerate NICs */ | ||
63 | EnumNICs (&pTable, &pAddrTable); | ||
64 | 58 | ||
65 | if (pTable) | 59 | for (i = 0; i < results_count; i++) |
66 | { | 60 | { |
67 | for (dwIfIdx = 0; dwIfIdx <= pTable->dwNumEntries; dwIfIdx++) | 61 | if (GNUNET_OK != proc (proc_cls, results[i].pretty_name, |
68 | { | 62 | results[i].is_default, |
69 | char szEntry[1001]; | 63 | &results[i].address, |
70 | DWORD dwIP = 0; | 64 | results[i].flags & ENUMNICS3_MASK_OK ? &results[i].mask : NULL, |
71 | PIP_ADAPTER_INFO pAdapterInfo; | 65 | results[i].flags & ENUMNICS3_BCAST_OK ? &results[i].broadcast : NULL, |
72 | PIP_ADAPTER_INFO pAdapter = NULL; | 66 | results[i].addr_size)) |
73 | DWORD dwRetVal = 0; | 67 | break; |
74 | |||
75 | /* Get IP-Address */ | ||
76 | int i; | ||
77 | |||
78 | for (i = 0; i < pAddrTable->dwNumEntries; i++) | ||
79 | { | ||
80 | if (pAddrTable->table[i].dwIndex == pTable->table[dwIfIdx].dwIndex) | ||
81 | { | ||
82 | dwIP = pAddrTable->table[i].dwAddr; | ||
83 | break; | ||
84 | } | ||
85 | } | ||
86 | |||
87 | if (dwIP) | ||
88 | { | ||
89 | BYTE bPhysAddr[MAXLEN_PHYSADDR]; | ||
90 | char *pszIfName = NULL; | ||
91 | char dst[INET_ADDRSTRLEN]; | ||
92 | struct sockaddr_in sa; | ||
93 | |||
94 | /* Get friendly interface name */ | ||
95 | pAdapterInfo = (IP_ADAPTER_INFO *) malloc (sizeof (IP_ADAPTER_INFO)); | ||
96 | ULONG ulOutBufLen = sizeof (IP_ADAPTER_INFO); | ||
97 | |||
98 | /* Make an initial call to GetAdaptersInfo to get | ||
99 | * the necessary size into the ulOutBufLen variable */ | ||
100 | if (GGetAdaptersInfo (pAdapterInfo, &ulOutBufLen) == | ||
101 | ERROR_BUFFER_OVERFLOW) | ||
102 | { | ||
103 | free (pAdapterInfo); | ||
104 | pAdapterInfo = (IP_ADAPTER_INFO *) malloc (ulOutBufLen); | ||
105 | } | ||
106 | |||
107 | if ((dwRetVal = | ||
108 | GGetAdaptersInfo (pAdapterInfo, &ulOutBufLen)) == NO_ERROR) | ||
109 | { | ||
110 | pAdapter = pAdapterInfo; | ||
111 | while (pAdapter) | ||
112 | { | ||
113 | if (pTable->table[dwIfIdx].dwIndex == pAdapter->Index) | ||
114 | { | ||
115 | char szKey[251]; | ||
116 | long lLen = 250; | ||
117 | |||
118 | sprintf (szKey, | ||
119 | "SYSTEM\\CurrentControlSet\\Control\\Network\\" | ||
120 | "{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection", | ||
121 | pAdapter->AdapterName); | ||
122 | pszIfName = (char *) malloc (251); | ||
123 | if (QueryRegistry | ||
124 | (HKEY_LOCAL_MACHINE, szKey, "Name", pszIfName, | ||
125 | &lLen) != ERROR_SUCCESS) | ||
126 | { | ||
127 | free (pszIfName); | ||
128 | pszIfName = NULL; | ||
129 | } | ||
130 | } | ||
131 | pAdapter = pAdapter->Next; | ||
132 | } | ||
133 | } | ||
134 | free (pAdapterInfo); | ||
135 | |||
136 | /* Set entry */ | ||
137 | memset (bPhysAddr, 0, MAXLEN_PHYSADDR); | ||
138 | memcpy (bPhysAddr, pTable->table[dwIfIdx].bPhysAddr, | ||
139 | pTable->table[dwIfIdx].dwPhysAddrLen); | ||
140 | |||
141 | snprintf (szEntry, 1000, "%s (%s - %I64u)", | ||
142 | pszIfName ? pszIfName : (char *) pTable-> | ||
143 | table[dwIfIdx].bDescr, inet_ntop (AF_INET, &dwIP, dst, | ||
144 | INET_ADDRSTRLEN), | ||
145 | *((unsigned long long *) bPhysAddr)); | ||
146 | szEntry[1000] = 0; | ||
147 | |||
148 | if (pszIfName) | ||
149 | free (pszIfName); | ||
150 | |||
151 | sa.sin_family = AF_INET; | ||
152 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
153 | sa.sin_len = (u_char) sizeof (struct sockaddr_in); | ||
154 | #endif | ||
155 | sa.sin_addr.S_un.S_addr = dwIP; | ||
156 | |||
157 | if (GNUNET_OK != | ||
158 | proc (proc_cls, szEntry, | ||
159 | pTable->table[dwIfIdx].dwIndex == dwExternalNIC, | ||
160 | (const struct sockaddr *) &sa, | ||
161 | NULL, | ||
162 | NULL, | ||
163 | sizeof (sa))) | ||
164 | break; | ||
165 | } | ||
166 | } | ||
167 | GlobalFree (pAddrTable); | ||
168 | GlobalFree (pTable); | ||
169 | } | 68 | } |
170 | 69 | EnumNICs3_free (results); | |
171 | return; | 70 | return; |
172 | 71 | ||
173 | #elif HAVE_GETIFADDRS && HAVE_FREEIFADDRS | 72 | #elif HAVE_GETIFADDRS && HAVE_FREEIFADDRS |
diff --git a/src/util/win.cc b/src/util/win.cc index b462033b9..594b9a210 100644 --- a/src/util/win.cc +++ b/src/util/win.cc | |||
@@ -44,161 +44,608 @@ extern "C" { | |||
44 | 44 | ||
45 | int plibc_conv_to_win_path(const char *pszUnix, char *pszWindows); | 45 | int plibc_conv_to_win_path(const char *pszUnix, char *pszWindows); |
46 | 46 | ||
47 | /** | 47 | #define _IP_ADAPTER_UNICAST_ADDRESS_HEAD \ |
48 | * Enumerate all network adapters | 48 | union { \ |
49 | */ | 49 | struct { \ |
50 | void EnumNICs(PMIB_IFTABLE *pIfTable, PMIB_IPADDRTABLE *pAddrTable) | 50 | ULONG Length; \ |
51 | { | 51 | DWORD Flags; \ |
52 | DWORD dwSize, dwRet; | 52 | }; \ |
53 | }; \ | ||
54 | |||
55 | #define _IP_ADAPTER_UNICAST_ADDRESS_BASE \ | ||
56 | SOCKET_ADDRESS Address; \ | ||
57 | IP_PREFIX_ORIGIN PrefixOrigin; \ | ||
58 | IP_SUFFIX_ORIGIN SuffixOrigin; \ | ||
59 | IP_DAD_STATE DadState; \ | ||
60 | ULONG ValidLifetime; \ | ||
61 | ULONG PreferredLifetime; \ | ||
62 | ULONG LeaseLifetime; | ||
63 | |||
64 | #define _IP_ADAPTER_UNICAST_ADDRESS_ADD_VISTA \ | ||
65 | UINT8 OnLinkPrefixLength; | ||
66 | |||
67 | |||
68 | #define _IP_ADAPTER_UNICAST_ADDRESS_DEFINE(suffix,addition) \ | ||
69 | typedef struct _IP_ADAPTER_UNICAST_ADDRESS##suffix { \ | ||
70 | _IP_ADAPTER_UNICAST_ADDRESS_HEAD \ | ||
71 | struct _IP_ADAPTER_UNICAST_ADDRESS##suffix *Next; \ | ||
72 | _IP_ADAPTER_UNICAST_ADDRESS_BASE \ | ||
73 | addition \ | ||
74 | } IP_ADAPTER_UNICAST_ADDRESS##suffix, *PIP_ADAPTER_UNICAST_ADDRESS##suffix; | ||
75 | |||
76 | /* _IP_ADAPTER_UNICAST_ADDRESS_DEFINE(,) defined in w32api headers */ | ||
77 | _IP_ADAPTER_UNICAST_ADDRESS_DEFINE(_VISTA,_IP_ADAPTER_UNICAST_ADDRESS_ADD_VISTA) | ||
78 | |||
79 | |||
80 | typedef struct _IP_ADAPTER_WINS_SERVER_ADDRESS { | ||
81 | union { | ||
82 | ULONGLONG Alignment; | ||
83 | struct { | ||
84 | ULONG Length; | ||
85 | DWORD Reserved; | ||
86 | }; | ||
87 | }; | ||
88 | struct _IP_ADAPTER_WINS_SERVER_ADDRESS *Next; | ||
89 | SOCKET_ADDRESS Address; | ||
90 | } IP_ADAPTER_WINS_SERVER_ADDRESS, *PIP_ADAPTER_WINS_SERVER_ADDRESS, *PIP_ADAPTER_WINS_SERVER_ADDRESS_LH; | ||
91 | |||
92 | typedef struct _IP_ADAPTER_GATEWAY_ADDRESS { | ||
93 | union { | ||
94 | ULONGLONG Alignment; | ||
95 | struct { | ||
96 | ULONG Length; | ||
97 | DWORD Reserved; | ||
98 | }; | ||
99 | }; | ||
100 | struct _IP_ADAPTER_GATEWAY_ADDRESS *Next; | ||
101 | SOCKET_ADDRESS Address; | ||
102 | } IP_ADAPTER_GATEWAY_ADDRESS, *PIP_ADAPTER_GATEWAY_ADDRESS, *PIP_ADAPTER_GATEWAY_ADDRESS_LH; | ||
103 | |||
104 | typedef UINT32 NET_IF_COMPARTMENT_ID; | ||
105 | typedef GUID NET_IF_NETWORK_GUID; | ||
106 | |||
107 | typedef enum _NET_IF_CONNECTION_TYPE { | ||
108 | NET_IF_CONNECTION_DEDICATED = 1, | ||
109 | NET_IF_CONNECTION_PASSIVE, | ||
110 | NET_IF_CONNECTION_DEMAND, | ||
111 | NET_IF_CONNECTION_MAXIMUM | ||
112 | } NET_IF_CONNECTION_TYPE, *PNET_IF_CONNECTION_TYPE; | ||
113 | |||
114 | typedef enum { | ||
115 | TUNNEL_TYPE_NONE = 0, | ||
116 | TUNNEL_TYPE_OTHER, | ||
117 | TUNNEL_TYPE_DIRECT, | ||
118 | TUNNEL_TYPE_6TO4, | ||
119 | TUNNEL_TYPE_ISATAP, | ||
120 | TUNNEL_TYPE_TEREDO, | ||
121 | TUNNEL_TYPE_IPHTTPS | ||
122 | } TUNNEL_TYPE, *PTUNNEL_TYPE; | ||
53 | 123 | ||
54 | *pIfTable = NULL; | 124 | /* |
125 | A DUID consists of a two-octet type code represented in network byte | ||
126 | order, followed by a variable number of octets that make up the | ||
127 | actual identifier. A DUID can be no more than 128 octets long (not | ||
128 | including the type code). | ||
129 | */ | ||
130 | #define MAX_DHCPV6_DUID_LENGTH 130 | ||
131 | |||
132 | typedef union _NET_LUID { | ||
133 | ULONG64 Value; | ||
134 | struct { | ||
135 | ULONG64 Reserved :24; | ||
136 | ULONG64 NetLuidIndex :24; | ||
137 | ULONG64 IfType :16; | ||
138 | } Info; | ||
139 | } NET_LUID, *PNET_LUID, IF_LUID; | ||
140 | |||
141 | #define MAX_DNS_SUFFIX_STRING_LENGTH 246 | ||
142 | |||
143 | typedef struct _IP_ADAPTER_DNS_SUFFIX { | ||
144 | struct _IP_ADAPTER_DNS_SUFFIX *Next; | ||
145 | WCHAR String[MAX_DNS_SUFFIX_STRING_LENGTH]; | ||
146 | } IP_ADAPTER_DNS_SUFFIX, *PIP_ADAPTER_DNS_SUFFIX; | ||
147 | |||
148 | |||
149 | |||
150 | #define _IP_ADAPTER_ADDRESSES_HEAD \ | ||
151 | union { \ | ||
152 | ULONGLONG Alignment; \ | ||
153 | struct { \ | ||
154 | ULONG Length; \ | ||
155 | DWORD IfIndex; \ | ||
156 | }; \ | ||
157 | }; | ||
158 | |||
159 | #define _IP_ADAPTER_ADDRESSES_BASE \ | ||
160 | PCHAR AdapterName; \ | ||
161 | PIP_ADAPTER_UNICAST_ADDRESS FirstUnicastAddress; \ | ||
162 | PIP_ADAPTER_ANYCAST_ADDRESS FirstAnycastAddress; \ | ||
163 | PIP_ADAPTER_MULTICAST_ADDRESS FirstMulticastAddress; \ | ||
164 | PIP_ADAPTER_DNS_SERVER_ADDRESS FirstDnsServerAddress; \ | ||
165 | PWCHAR DnsSuffix; \ | ||
166 | PWCHAR Description; \ | ||
167 | PWCHAR FriendlyName; \ | ||
168 | BYTE PhysicalAddress[MAX_ADAPTER_ADDRESS_LENGTH]; \ | ||
169 | DWORD PhysicalAddressLength; \ | ||
170 | DWORD Flags; \ | ||
171 | DWORD Mtu; \ | ||
172 | DWORD IfType; \ | ||
173 | IF_OPER_STATUS OperStatus; | ||
174 | |||
175 | #define _IP_ADAPTER_ADDRESSES_ADD_XPSP1 \ | ||
176 | DWORD Ipv6IfIndex; \ | ||
177 | DWORD ZoneIndices[16]; \ | ||
178 | PIP_ADAPTER_PREFIX FirstPrefix; \ | ||
179 | |||
180 | |||
181 | #define _IP_ADAPTER_ADDRESSES_ADD_VISTA \ | ||
182 | _IP_ADAPTER_ADDRESSES_ADD_XPSP1 \ | ||
183 | ULONG64 TransmitLinkSpeed; \ | ||
184 | ULONG64 ReceiveLinkSpeed; \ | ||
185 | PIP_ADAPTER_WINS_SERVER_ADDRESS_LH FirstWinsServerAddress; \ | ||
186 | PIP_ADAPTER_GATEWAY_ADDRESS_LH FirstGatewayAddress; \ | ||
187 | ULONG Ipv4Metric; \ | ||
188 | ULONG Ipv6Metric; \ | ||
189 | IF_LUID Luid; \ | ||
190 | SOCKET_ADDRESS Dhcpv4Server; \ | ||
191 | NET_IF_COMPARTMENT_ID CompartmentId; \ | ||
192 | NET_IF_NETWORK_GUID NetworkGuid; \ | ||
193 | NET_IF_CONNECTION_TYPE ConnectionType; \ | ||
194 | TUNNEL_TYPE TunnelType; \ | ||
195 | SOCKET_ADDRESS Dhcpv6Server; \ | ||
196 | BYTE Dhcpv6ClientDuid[MAX_DHCPV6_DUID_LENGTH]; \ | ||
197 | ULONG Dhcpv6ClientDuidLength; \ | ||
198 | ULONG Dhcpv6Iaid; | ||
199 | |||
200 | #define _IP_ADAPTER_ADDRESSES_ADD_2008_OR_VISTASP1 \ | ||
201 | _IP_ADAPTER_ADDRESSES_ADD_VISTA \ | ||
202 | PIP_ADAPTER_DNS_SUFFIX FirstDnsSuffix; | ||
203 | |||
204 | #define _IP_ADAPTER_ADDRESSES_DEFINE(suffix,addition) \ | ||
205 | typedef struct _IP_ADAPTER_ADDRESSES##suffix { \ | ||
206 | _IP_ADAPTER_ADDRESSES_HEAD \ | ||
207 | struct _IP_ADAPTER_ADDRESSES##suffix *Next; \ | ||
208 | _IP_ADAPTER_ADDRESSES_BASE \ | ||
209 | addition \ | ||
210 | } IP_ADAPTER_ADDRESSES##suffix, *PIP_ADAPTER_ADDRESSES##suffix; | ||
211 | |||
212 | |||
213 | /* _IP_ADAPTER_ADDRESSES_DEFINE(,) defined in w32api headers */ | ||
214 | _IP_ADAPTER_ADDRESSES_DEFINE(_XPSP1,_IP_ADAPTER_ADDRESSES_ADD_XPSP1) | ||
215 | _IP_ADAPTER_ADDRESSES_DEFINE(_VISTA,_IP_ADAPTER_ADDRESSES_ADD_VISTA) | ||
216 | _IP_ADAPTER_ADDRESSES_DEFINE(_2008_OR_VISTASP1,_IP_ADAPTER_ADDRESSES_ADD_2008_OR_VISTASP1) | ||
217 | |||
218 | static int | ||
219 | EnumNICs_IPv6_get_ifs_count (SOCKET s) | ||
220 | { | ||
221 | DWORD dwret = 0, err; | ||
222 | int iret; | ||
223 | iret = WSAIoctl (s, SIO_ADDRESS_LIST_QUERY, NULL, 0, NULL, 0, | ||
224 | &dwret, NULL, NULL); | ||
225 | err = GetLastError (); | ||
226 | if (iret == SOCKET_ERROR && err == WSAEFAULT) | ||
227 | return dwret; | ||
228 | else if (iret == 0) | ||
229 | return 0; | ||
230 | return GNUNET_SYSERR; | ||
231 | } | ||
55 | 232 | ||
56 | if (pAddrTable) | 233 | static int |
57 | *pAddrTable = NULL; | 234 | EnumNICs_IPv6_get_ifs (SOCKET s, SOCKET_ADDRESS_LIST *inf, int size) |
235 | { | ||
236 | int iret; | ||
237 | DWORD dwret = 0; | ||
238 | iret = WSAIoctl (s, SIO_ADDRESS_LIST_QUERY, NULL, 0, inf, size, | ||
239 | &dwret, NULL, NULL); | ||
58 | 240 | ||
59 | if (GNGetIfTable) | 241 | if (iret != 0 || dwret != size) |
60 | { | 242 | { |
61 | dwSize = dwRet = 0; | 243 | /* It's supposed to succeed! And size should be the same */ |
244 | return GNUNET_SYSERR; | ||
245 | } | ||
246 | return GNUNET_OK; | ||
247 | } | ||
62 | 248 | ||
63 | *pIfTable = (MIB_IFTABLE *) GlobalAlloc(GPTR, sizeof(MIB_IFTABLE)); | 249 | #undef GNUNET_malloc |
250 | #define GNUNET_malloc(a) HeapAlloc(GetProcessHeap (), HEAP_ZERO_MEMORY | \ | ||
251 | HEAP_GENERATE_EXCEPTIONS, a) | ||
64 | 252 | ||
65 | /* Get size of table */ | 253 | #undef GNUNET_free |
66 | if (GNGetIfTable(*pIfTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) | 254 | #define GNUNET_free(a) HeapFree(GetProcessHeap (), 0, a) |
67 | { | ||
68 | GlobalFree(*pIfTable); | ||
69 | *pIfTable = (MIB_IFTABLE *) GlobalAlloc(GPTR, dwSize); | ||
70 | } | ||
71 | 255 | ||
72 | if ((dwRet = GNGetIfTable(*pIfTable, &dwSize, 0)) == NO_ERROR && | 256 | #undef GNUNET_free_non_null |
73 | pAddrTable) | 257 | #define GNUNET_free_non_null(a) do { if ((a) != NULL) GNUNET_free(a); } while (0) |
74 | { | ||
75 | DWORD dwIfIdx, dwSize = sizeof(MIB_IPADDRTABLE); | ||
76 | *pAddrTable = (MIB_IPADDRTABLE *) GlobalAlloc(GPTR, dwSize); | ||
77 | 258 | ||
78 | /* Make an initial call to GetIpAddrTable to get the | 259 | static int |
79 | necessary size */ | 260 | EnumNICs_IPv4_get_ifs (SOCKET s, INTERFACE_INFO **inf, int *size) |
80 | if (GNGetIpAddrTable(*pAddrTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) | 261 | { |
262 | int iret; | ||
263 | DWORD dwret = 0; | ||
264 | DWORD error; | ||
265 | INTERFACE_INFO *ii = NULL; | ||
266 | DWORD ii_size = sizeof (INTERFACE_INFO) * 15; | ||
267 | while (TRUE) | ||
268 | { | ||
269 | if (ii_size >= sizeof (INTERFACE_INFO) * 1000) | ||
270 | return GNUNET_SYSERR; | ||
271 | ii = (INTERFACE_INFO *) GNUNET_malloc (ii_size); | ||
272 | dwret = 0; | ||
273 | iret = WSAIoctl (s, SIO_GET_INTERFACE_LIST, NULL, 0, ii, ii_size, | ||
274 | &dwret, NULL, NULL); | ||
275 | error = GetLastError (); | ||
276 | if (iret == SOCKET_ERROR) | ||
277 | { | ||
278 | if (error == WSAEFAULT) | ||
81 | { | 279 | { |
82 | GlobalFree(*pAddrTable); | 280 | GNUNET_free (ii); |
83 | *pAddrTable = (MIB_IPADDRTABLE *) GlobalAlloc(GPTR, dwSize); | 281 | ii_size *= 2; |
282 | continue; | ||
84 | } | 283 | } |
85 | GNGetIpAddrTable(*pAddrTable, &dwSize, 0); | 284 | GNUNET_free (ii); |
285 | return GNUNET_SYSERR; | ||
286 | } | ||
287 | else | ||
288 | { | ||
289 | *inf = ii; | ||
290 | *size = dwret; | ||
291 | return GNUNET_OK; | ||
86 | } | 292 | } |
87 | } | 293 | } |
294 | return GNUNET_SYSERR; | ||
295 | } | ||
296 | |||
297 | int | ||
298 | EnumNICs2 (INTERFACE_INFO **ifs4, int *ifs4_len, SOCKET_ADDRESS_LIST **ifs6) | ||
299 | { | ||
300 | int result = 0; | ||
301 | SOCKET s4 = INVALID_SOCKET, s6 = INVALID_SOCKET; | ||
302 | DWORD dwret1 = 0, dwret2; | ||
303 | DWORD err1, err2; | ||
304 | int ifs4len = 0, ifs6len = 0; | ||
305 | INTERFACE_INFO *interfaces4 = NULL; | ||
306 | SOCKET_ADDRESS_LIST *interfaces6 = NULL; | ||
307 | SetLastError (0); | ||
308 | s4 = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); | ||
309 | err1 = GetLastError (); | ||
310 | SetLastError (0); | ||
311 | s6 = socket (AF_INET6, SOCK_STREAM, IPPROTO_TCP); | ||
312 | err2 = GetLastError (); | ||
313 | if (s6 != INVALID_SOCKET) | ||
314 | { | ||
315 | ifs6len = EnumNICs_IPv6_get_ifs_count (s6); | ||
316 | if (ifs6len > 0) | ||
317 | { | ||
318 | interfaces6 = (SOCKET_ADDRESS_LIST *) GNUNET_malloc (ifs6len); | ||
319 | result = EnumNICs_IPv6_get_ifs (s6, interfaces6, ifs6len) || result; | ||
320 | } | ||
321 | closesocket (s6); | ||
322 | s6 = INVALID_SOCKET; | ||
323 | } | ||
324 | |||
325 | if (s4 != INVALID_SOCKET) | ||
326 | { | ||
327 | result = EnumNICs_IPv4_get_ifs (s4, &interfaces4, &ifs4len) || result; | ||
328 | closesocket (s4); | ||
329 | s4 = INVALID_SOCKET; | ||
330 | } | ||
331 | if (ifs6len + ifs4len == 0) | ||
332 | goto error; | ||
333 | |||
334 | if (!result) | ||
335 | { | ||
336 | *ifs4 = interfaces4; | ||
337 | *ifs4_len = ifs4len; | ||
338 | *ifs6 = interfaces6; | ||
339 | return GNUNET_OK; | ||
340 | } | ||
341 | error: | ||
342 | if (interfaces4 != NULL) | ||
343 | GNUNET_free (interfaces4); | ||
344 | if (interfaces6 != NULL) | ||
345 | GNUNET_free (interfaces6); | ||
346 | if (s4 != INVALID_SOCKET) | ||
347 | closesocket (s4); | ||
348 | if (s6 != INVALID_SOCKET) | ||
349 | closesocket (s6); | ||
350 | return GNUNET_SYSERR; | ||
88 | } | 351 | } |
89 | 352 | ||
90 | /** | 353 | /** |
91 | * Lists all network interfaces in a combo box | 354 | * Returns GNUNET_OK on OK, GNUNET_SYSERR on error |
92 | * Used by the basic GTK configurator | ||
93 | * | ||
94 | * @param callback function to call for each NIC | ||
95 | * @param callback_cls closure for callback | ||
96 | */ | 355 | */ |
97 | int ListNICs(void (*callback) (void *, const char *, int), void * callback_cls) | 356 | int |
357 | EnumNICs3 (struct EnumNICs3_results **results, int *results_count) | ||
98 | { | 358 | { |
99 | PMIB_IFTABLE pTable; | 359 | DWORD dwRetVal = 0; |
100 | PMIB_IPADDRTABLE pAddrTable; | 360 | int count = 0; |
101 | DWORD dwIfIdx, dwExternalNIC; | 361 | ULONG flags = /*GAA_FLAG_INCLUDE_PREFIX |*/ GAA_FLAG_SKIP_ANYCAST | |
102 | IPAddr theIP; | 362 | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER; |
103 | 363 | struct sockaddr_in6 examplecom6; | |
104 | /* Determine our external NIC */ | 364 | IPAddr examplecom; |
105 | theIP = inet_addr("192.0.34.166"); /* www.example.com */ | 365 | DWORD best_interface = 0; |
106 | if ((! GNGetBestInterface) || | 366 | DWORD best_interface6 = 0; |
107 | (GNGetBestInterface(theIP, &dwExternalNIC) != NO_ERROR)) | 367 | |
368 | int use_enum2 = 0; | ||
369 | INTERFACE_INFO *interfaces4 = NULL; | ||
370 | int interfaces4_len = 0; | ||
371 | SOCKET_ADDRESS_LIST *interfaces6 = NULL; | ||
372 | |||
373 | unsigned long outBufLen = sizeof (IP_ADAPTER_ADDRESSES); | ||
374 | IP_ADAPTER_ADDRESSES *pCurrentAddress = NULL; | ||
375 | IP_ADAPTER_ADDRESSES *pAddresses = (IP_ADAPTER_ADDRESSES *) GNUNET_malloc (outBufLen); | ||
376 | |||
377 | if (GetAdaptersAddresses (AF_UNSPEC, flags, NULL, pAddresses, &outBufLen) | ||
378 | == ERROR_BUFFER_OVERFLOW) | ||
379 | { | ||
380 | GNUNET_free (pAddresses); | ||
381 | pAddresses = (IP_ADAPTER_ADDRESSES *) GNUNET_malloc (outBufLen); | ||
382 | } | ||
383 | |||
384 | dwRetVal = GetAdaptersAddresses (AF_UNSPEC, flags, NULL, pAddresses, &outBufLen); | ||
385 | |||
386 | if (dwRetVal != NO_ERROR) | ||
387 | { | ||
388 | GNUNET_free (pAddresses); | ||
389 | return GNUNET_SYSERR; | ||
390 | } | ||
391 | |||
392 | if (pAddresses->Length < sizeof (IP_ADAPTER_ADDRESSES_VISTA)) | ||
393 | { | ||
394 | use_enum2 = 1; | ||
395 | |||
396 | /* Enumerate NICs using WSAIoctl() */ | ||
397 | if (GNUNET_OK != EnumNICs2 (&interfaces4, &interfaces4_len, &interfaces6)) | ||
398 | { | ||
399 | GNUNET_free (pAddresses); | ||
400 | return GNUNET_SYSERR; | ||
401 | } | ||
402 | } | ||
403 | |||
404 | examplecom = inet_addr("192.0.34.166"); /* www.example.com */ | ||
405 | if (GetBestInterface (examplecom, &best_interface) != NO_ERROR) | ||
406 | best_interface = 0; | ||
407 | |||
408 | if (GNGetBestInterfaceEx != NULL) | ||
108 | { | 409 | { |
109 | dwExternalNIC = 0; | 410 | examplecom6.sin6_family = AF_INET6; |
411 | examplecom6.sin6_port = 0; | ||
412 | examplecom6.sin6_flowinfo = 0; | ||
413 | examplecom6.sin6_scope_id = 0; | ||
414 | inet_pton (AF_INET6, "2001:500:88:200:0:0:0:10", | ||
415 | (struct sockaddr *) &examplecom6.sin6_addr); | ||
416 | dwRetVal = GNGetBestInterfaceEx ((struct sockaddr *) &examplecom6, | ||
417 | &best_interface6); | ||
418 | if (dwRetVal != NO_ERROR) | ||
419 | best_interface6 = 0; | ||
110 | } | 420 | } |
111 | 421 | ||
112 | /* Enumerate NICs */ | 422 | /* Give IPv6 a priority */ |
113 | EnumNICs(&pTable, &pAddrTable); | 423 | if (best_interface6 != 0) |
424 | best_interface = best_interface6; | ||
114 | 425 | ||
115 | if (pTable) | 426 | count = 0; |
427 | for (pCurrentAddress = pAddresses; | ||
428 | pCurrentAddress != NULL; pCurrentAddress = pCurrentAddress->Next) | ||
116 | { | 429 | { |
117 | for(dwIfIdx=0; dwIfIdx <= pTable->dwNumEntries; dwIfIdx++) | 430 | if (pCurrentAddress->OperStatus == IfOperStatusUp) |
118 | { | 431 | { |
119 | char szEntry[1001]; | 432 | IP_ADAPTER_UNICAST_ADDRESS *unicast = NULL; |
120 | DWORD dwIP = 0; | 433 | for (unicast = pCurrentAddress->FirstUnicastAddress; unicast != NULL; |
121 | int iItm; | 434 | unicast = unicast->Next) |
122 | PIP_ADAPTER_INFO pAdapterInfo; | ||
123 | PIP_ADAPTER_INFO pAdapter = NULL; | ||
124 | DWORD dwRetVal = 0; | ||
125 | |||
126 | /* Get IP-Address */ | ||
127 | int i; | ||
128 | for(i = 0; i < pAddrTable->dwNumEntries; i++) | ||
129 | { | 435 | { |
130 | if (pAddrTable->table[i].dwIndex == pTable->table[dwIfIdx].dwIndex) | 436 | if ((unicast->Address.lpSockaddr->sa_family == AF_INET || |
437 | unicast->Address.lpSockaddr->sa_family == AF_INET6) && | ||
438 | (unicast->DadState == IpDadStateDeprecated || | ||
439 | unicast->DadState == IpDadStatePreferred)) | ||
440 | count += 1; | ||
441 | } | ||
442 | } | ||
443 | } | ||
444 | |||
445 | if (count == 0) | ||
446 | { | ||
447 | *results = NULL; | ||
448 | *results_count = 0; | ||
449 | GNUNET_free (pAddresses); | ||
450 | GNUNET_free_non_null (interfaces4); | ||
451 | GNUNET_free_non_null (interfaces6); | ||
452 | return GNUNET_OK; | ||
453 | } | ||
454 | |||
455 | *results = (struct EnumNICs3_results *) GNUNET_malloc ( | ||
456 | sizeof (struct EnumNICs3_results) * count); | ||
457 | *results_count = count; | ||
458 | |||
459 | count = 0; | ||
460 | for (pCurrentAddress = pAddresses; | ||
461 | pCurrentAddress != NULL; pCurrentAddress = pCurrentAddress->Next) | ||
462 | { | ||
463 | struct EnumNICs3_results *r; | ||
464 | IP_ADAPTER_UNICAST_ADDRESS *unicast = NULL; | ||
465 | if (pCurrentAddress->OperStatus != IfOperStatusUp) | ||
466 | continue; | ||
467 | for (unicast = pCurrentAddress->FirstUnicastAddress; unicast != NULL; | ||
468 | unicast = unicast->Next) | ||
469 | { | ||
470 | int i, j; | ||
471 | int mask_length = -1; | ||
472 | char dst[INET6_ADDRSTRLEN + 1]; | ||
473 | |||
474 | if ((unicast->Address.lpSockaddr->sa_family != AF_INET && | ||
475 | unicast->Address.lpSockaddr->sa_family != AF_INET6) || | ||
476 | (unicast->DadState != IpDadStateDeprecated && | ||
477 | unicast->DadState != IpDadStatePreferred)) | ||
478 | continue; | ||
479 | |||
480 | r = &(*results)[count]; | ||
481 | r->flags = 0; | ||
482 | if (pCurrentAddress->IfIndex > 0 && | ||
483 | pCurrentAddress->IfIndex == best_interface && | ||
484 | unicast->Address.lpSockaddr->sa_family == AF_INET) | ||
485 | r->is_default = 1; | ||
486 | else if (pCurrentAddress->Ipv6IfIndex > 0 && | ||
487 | pCurrentAddress->Ipv6IfIndex == best_interface6 && | ||
488 | unicast->Address.lpSockaddr->sa_family == AF_INET6) | ||
489 | r->is_default = 1; | ||
490 | else | ||
491 | r->is_default = 0; | ||
492 | |||
493 | /* Don't choose default interface twice */ | ||
494 | if (r->is_default) | ||
495 | best_interface = best_interface6 = 0; | ||
496 | |||
497 | if (!use_enum2) | ||
498 | { | ||
499 | memcpy (&r->address, unicast->Address.lpSockaddr, | ||
500 | unicast->Address.iSockaddrLength); | ||
501 | memset (&r->mask, 0, sizeof (struct sockaddr)); | ||
502 | mask_length = ((IP_ADAPTER_UNICAST_ADDRESS_VISTA *) unicast)-> | ||
503 | OnLinkPrefixLength; | ||
504 | /* OnLinkPrefixLength is the number of leading 1s in the mask. | ||
505 | * OnLinkPrefixLength is available on Vista and later (hence use_enum2). | ||
506 | */ | ||
507 | if (unicast->Address.lpSockaddr->sa_family == AF_INET) | ||
131 | { | 508 | { |
132 | dwIP = pAddrTable->table[i].dwAddr; | 509 | struct sockaddr_in *m = (struct sockaddr_in *) &r->mask; |
133 | break; | 510 | for (i = 0; i < mask_length; i++) |
511 | ((unsigned char *) &m->sin_addr)[i / 8] |= 0x80 >> (i % 8); | ||
134 | } | 512 | } |
513 | else if (unicast->Address.lpSockaddr->sa_family == AF_INET6) | ||
514 | { | ||
515 | struct sockaddr_in6 *m = (struct sockaddr_in6 *) &r->mask; | ||
516 | struct sockaddr_in6 *b = (struct sockaddr_in6 *) &r->broadcast; | ||
517 | for (i = 0; i < mask_length; i++) | ||
518 | ((unsigned char *) &m->sin6_addr)[i / 8] |= 0x80 >> (i % 8); | ||
519 | memcpy (&r->broadcast, &r->address, unicast->Address.iSockaddrLength); | ||
520 | for (i = mask_length; i < 128; i++) | ||
521 | ((unsigned char *) &b->sin6_addr)[i / 8] |= 0x80 >> (i % 8); | ||
522 | } | ||
523 | r->flags |= ENUMNICS3_MASK_OK; | ||
135 | } | 524 | } |
136 | 525 | else | |
137 | if (dwIP) | ||
138 | { | 526 | { |
139 | BYTE bPhysAddr[MAXLEN_PHYSADDR]; | 527 | int found = 0; |
140 | char *pszIfName = NULL; | 528 | if (unicast->Address.lpSockaddr->sa_family == AF_INET) |
141 | char dst[INET_ADDRSTRLEN]; | 529 | { |
142 | 530 | for (i = 0; !found && i < interfaces4_len / sizeof (INTERFACE_INFO); i++) | |
143 | /* Get friendly interface name */ | 531 | { |
144 | pAdapterInfo = (IP_ADAPTER_INFO *) malloc(sizeof(IP_ADAPTER_INFO)); | 532 | struct sockaddr_in *m = (struct sockaddr_in *) &r->mask; |
145 | ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO); | 533 | if (memcpy (&interfaces4[i].iiAddress.Address, |
146 | 534 | unicast->Address.lpSockaddr, | |
147 | /* Make an initial call to GetAdaptersInfo to get | 535 | unicast->Address.iSockaddrLength) != 0) |
148 | the necessary size into the ulOutBufLen variable */ | 536 | continue; |
149 | if (GGetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) { | 537 | found = 1; |
150 | free(pAdapterInfo); | 538 | memcpy (&r->address, &interfaces4[i].iiAddress.Address, |
151 | pAdapterInfo = (IP_ADAPTER_INFO *) malloc (ulOutBufLen); | 539 | sizeof (struct sockaddr_in)); |
152 | } | 540 | memcpy (&r->mask, &interfaces4[i].iiNetmask.Address, |
153 | 541 | sizeof (struct sockaddr_in)); | |
154 | if ((dwRetVal = GGetAdaptersInfo( pAdapterInfo, &ulOutBufLen)) == NO_ERROR) { | 542 | for (mask_length = 0; |
155 | pAdapter = pAdapterInfo; | 543 | ((unsigned char *) &m->sin_addr)[mask_length / 8] & |
156 | while (pAdapter) { | 544 | 0x80 >> (mask_length % 8); mask_length++) |
157 | if (pTable->table[dwIfIdx].dwIndex == pAdapter->Index) | 545 | { |
158 | { | 546 | } |
159 | char szKey[251]; | 547 | r->flags |= ENUMNICS3_MASK_OK; |
160 | long lLen = 250; | 548 | } |
161 | 549 | } | |
162 | sprintf(szKey, "SYSTEM\\CurrentControlSet\\Control\\Network\\" | 550 | else if (unicast->Address.lpSockaddr->sa_family == AF_INET6) |
163 | "{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection", | 551 | { |
164 | pAdapter->AdapterName); | 552 | for (i = 0; |
165 | pszIfName = (char *) malloc(251); | 553 | interfaces6 != NULL && !found && i < interfaces6->iAddressCount; |
166 | if (QueryRegistry(HKEY_LOCAL_MACHINE, szKey, "Name", pszIfName, | 554 | i++) |
167 | &lLen) != ERROR_SUCCESS) | 555 | { |
168 | { | 556 | if (memcpy (interfaces6->Address[i].lpSockaddr, |
169 | free(pszIfName); | 557 | unicast->Address.lpSockaddr, |
170 | pszIfName = NULL; | 558 | unicast->Address.iSockaddrLength) != 0) |
171 | } | 559 | continue; |
172 | } | 560 | found = 1; |
173 | pAdapter = pAdapter->Next; | 561 | memcpy (&r->address, interfaces6->Address[i].lpSockaddr, |
174 | } | 562 | sizeof (struct sockaddr_in6)); |
175 | } | 563 | /* TODO: Find a way to reliably get network mask for IPv6 on XP */ |
176 | free(pAdapterInfo); | 564 | memset (&r->mask, 0, sizeof (struct sockaddr)); |
177 | 565 | r->flags &= ~ENUMNICS3_MASK_OK; | |
178 | /* Set entry */ | 566 | } |
179 | memset(bPhysAddr, 0, MAXLEN_PHYSADDR); | 567 | } |
180 | memcpy(bPhysAddr, | 568 | if (!found) |
181 | pTable->table[dwIfIdx].bPhysAddr, | 569 | { |
182 | pTable->table[dwIfIdx].dwPhysAddrLen); | 570 | DebugBreak (); |
183 | 571 | } | |
184 | snprintf(szEntry, 1000, "%s (%s - %I64u)", | 572 | } |
185 | pszIfName ? pszIfName : (char *) pTable->table[dwIfIdx].bDescr, | 573 | if (unicast->Address.lpSockaddr->sa_family == AF_INET) |
186 | inet_ntop (AF_INET, &dwIP, dst, INET_ADDRSTRLEN), | 574 | { |
187 | *((unsigned long long *) bPhysAddr)); | 575 | struct sockaddr_in *m = (struct sockaddr_in *) &r->mask; |
188 | szEntry[1000] = 0; | 576 | struct sockaddr_in *a = (struct sockaddr_in *) &r->address; |
189 | 577 | /* copy address to broadcast, then flip all the trailing bits not | |
190 | if (pszIfName) | 578 | * falling under netmask to 1, |
191 | free(pszIfName); | 579 | * so we get, 192.168.0.255 from, say, 192.168.0.43 with mask == 24. |
192 | 580 | */ | |
193 | callback(callback_cls, | 581 | memcpy (&r->broadcast, &r->address, unicast->Address.iSockaddrLength); |
194 | szEntry, | 582 | for (i = mask_length; i < 32; i++) |
195 | pAddrTable->table[dwIfIdx].dwIndex == dwExternalNIC); | 583 | ((unsigned char *) &m->sin_addr)[i / 8] |= 0x80 >> (i % 8); |
584 | r->flags |= ENUMNICS3_BCAST_OK; | ||
585 | r->addr_size = sizeof (struct sockaddr_in); | ||
586 | inet_ntop (AF_INET, &a->sin_addr, dst, INET_ADDRSTRLEN); | ||
587 | } | ||
588 | else if (unicast->Address.lpSockaddr->sa_family == AF_INET6) | ||
589 | { | ||
590 | struct sockaddr_in6 *a = (struct sockaddr_in6 *) &r->address; | ||
591 | /* for IPv6 broadcast is not defined, zero it down */ | ||
592 | memset (&r->broadcast, 0, sizeof (struct sockaddr)); | ||
593 | r->flags &= ~ENUMNICS3_BCAST_OK; | ||
594 | r->addr_size = sizeof (struct sockaddr_in6); | ||
595 | inet_ntop (AF_INET6, &a->sin6_addr, dst, INET6_ADDRSTRLEN); | ||
196 | } | 596 | } |
597 | |||
598 | i = 0; | ||
599 | i += snprintf (&r->pretty_name[i], 1000 - i > 0 ? 1000 - i : 0, | ||
600 | "%S (%s", pCurrentAddress->FriendlyName, dst); | ||
601 | for (j = 0; j < pCurrentAddress->PhysicalAddressLength; j++) | ||
602 | i += snprintf (&r->pretty_name[i], 1000 - i > 0 ? 1000 - i : 0, | ||
603 | "%s%02X",j > 0 ? ":" : " - ", pCurrentAddress->PhysicalAddress[j]); | ||
604 | i += snprintf (&r->pretty_name[i], 1000 - i > 0 ? 1000 - i : 0, ")"); | ||
605 | r->pretty_name[1000] = '\0'; | ||
606 | count += 1; | ||
197 | } | 607 | } |
198 | GlobalFree(pAddrTable); | ||
199 | GlobalFree(pTable); | ||
200 | } | 608 | } |
201 | 609 | ||
610 | if (use_enum2) | ||
611 | { | ||
612 | GNUNET_free_non_null (interfaces4); | ||
613 | GNUNET_free_non_null (interfaces6); | ||
614 | } | ||
615 | |||
616 | GNUNET_free (pAddresses); | ||
617 | return GNUNET_OK; | ||
618 | } | ||
619 | |||
620 | void | ||
621 | EnumNICs3_free (struct EnumNICs3_results *r) | ||
622 | { | ||
623 | GNUNET_free (r); | ||
624 | } | ||
625 | |||
626 | |||
627 | /** | ||
628 | * Lists all network interfaces in a combo box | ||
629 | * Used by the basic GTK configurator | ||
630 | * | ||
631 | * @param callback function to call for each NIC | ||
632 | * @param callback_cls closure for callback | ||
633 | */ | ||
634 | int | ||
635 | ListNICs (void (*callback) (void *, const char *, int), void * callback_cls) | ||
636 | { | ||
637 | int r; | ||
638 | int i; | ||
639 | struct EnumNICs3_results *results = NULL; | ||
640 | int results_count; | ||
641 | |||
642 | r = EnumNICs3 (&results, &results_count); | ||
643 | if (r != GNUNET_OK) | ||
644 | return GNUNET_NO; | ||
645 | |||
646 | for (i = 0; i < results_count; i++) | ||
647 | callback (callback_cls, results[i].pretty_name, results[i].is_default); | ||
648 | GNUNET_free_non_null (results); | ||
202 | return GNUNET_YES; | 649 | return GNUNET_YES; |
203 | } | 650 | } |
204 | 651 | ||
diff --git a/src/util/winproc.c b/src/util/winproc.c index 252cacbfb..b5245313a 100644 --- a/src/util/winproc.c +++ b/src/util/winproc.c | |||
@@ -46,8 +46,8 @@ TSetServiceStatus GNSetServiceStatus; | |||
46 | TStartServiceCtrlDispatcher GNStartServiceCtrlDispatcher; | 46 | TStartServiceCtrlDispatcher GNStartServiceCtrlDispatcher; |
47 | TControlService GNControlService; | 47 | TControlService GNControlService; |
48 | TOpenService GNOpenService; | 48 | TOpenService GNOpenService; |
49 | TGetBestInterface GNGetBestInterface; | 49 | TGetBestInterfaceEx GNGetBestInterfaceEx; |
50 | TGetAdaptersInfo GGetAdaptersInfo; | 50 | TGetAdaptersInfo GNGetAdaptersInfo; |
51 | TNetUserAdd GNNetUserAdd; | 51 | TNetUserAdd GNNetUserAdd; |
52 | TNetUserSetInfo GNNetUserSetInfo; | 52 | TNetUserSetInfo GNNetUserSetInfo; |
53 | TLsaOpenPolicy GNLsaOpenPolicy; | 53 | TLsaOpenPolicy GNLsaOpenPolicy; |
@@ -117,9 +117,9 @@ GNInitWinEnv () | |||
117 | GNGetIpAddrTable = | 117 | GNGetIpAddrTable = |
118 | (TGetIpAddrTable) GetProcAddress (hIphlpapi, "GetIpAddrTable"); | 118 | (TGetIpAddrTable) GetProcAddress (hIphlpapi, "GetIpAddrTable"); |
119 | GNGetIfTable = (TGetIfTable) GetProcAddress (hIphlpapi, "GetIfTable"); | 119 | GNGetIfTable = (TGetIfTable) GetProcAddress (hIphlpapi, "GetIfTable"); |
120 | GNGetBestInterface = | 120 | GNGetBestInterfaceEx = |
121 | (TGetBestInterface) GetProcAddress (hIphlpapi, "GetBestInterface"); | 121 | (TGetBestInterfaceEx) GetProcAddress (hIphlpapi, "GetBestInterfaceEx"); |
122 | GGetAdaptersInfo = | 122 | GNGetAdaptersInfo = |
123 | (TGetAdaptersInfo) GetProcAddress (hIphlpapi, "GetAdaptersInfo"); | 123 | (TGetAdaptersInfo) GetProcAddress (hIphlpapi, "GetAdaptersInfo"); |
124 | } | 124 | } |
125 | else | 125 | else |
@@ -127,8 +127,8 @@ GNInitWinEnv () | |||
127 | GNGetIfEntry = NULL; | 127 | GNGetIfEntry = NULL; |
128 | GNGetIpAddrTable = NULL; | 128 | GNGetIpAddrTable = NULL; |
129 | GNGetIfTable = NULL; | 129 | GNGetIfTable = NULL; |
130 | GNGetBestInterface = NULL; | 130 | GNGetBestInterfaceEx = NULL; |
131 | GGetAdaptersInfo = NULL; | 131 | GNGetAdaptersInfo = NULL; |
132 | } | 132 | } |
133 | 133 | ||
134 | /* Service & Account functions */ | 134 | /* Service & Account functions */ |