2 * IP configuration utility
4 * Copyright 2008 Andrew Riedi
5 * Copyright 2010 Andrew Nguyen
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include <wine/unicode.h>
28 static int ipconfig_vprintfW(const WCHAR *msg, va_list va_args)
32 WCHAR msg_buffer[8192];
34 wlen = vsprintfW(msg_buffer, msg, va_args);
36 ret = WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), msg_buffer, wlen, &count, NULL);
42 len = WideCharToMultiByte(GetConsoleOutputCP(), 0, msg_buffer, wlen,
44 msgA = HeapAlloc(GetProcessHeap(), 0, len);
48 WideCharToMultiByte(GetConsoleOutputCP(), 0, msg_buffer, wlen, msgA, len,
50 WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), msgA, len, &count, FALSE);
51 HeapFree(GetProcessHeap(), 0, msgA);
57 static int ipconfig_printfW(const WCHAR *msg, ...)
62 va_start(va_args, msg);
63 len = ipconfig_vprintfW(msg, va_args);
69 static int ipconfig_message_printfW(int msg, ...)
72 WCHAR msg_buffer[8192];
75 LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer,
76 sizeof(msg_buffer)/sizeof(WCHAR));
78 va_start(va_args, msg);
79 len = ipconfig_vprintfW(msg_buffer, va_args);
85 static int ipconfig_message(int msg)
87 static const WCHAR formatW[] = {'%','s',0};
88 WCHAR msg_buffer[8192];
90 LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer,
91 sizeof(msg_buffer)/sizeof(WCHAR));
93 return ipconfig_printfW(formatW, msg_buffer);
96 static const WCHAR *iftype_to_string(DWORD type)
98 static WCHAR msg_buffer[50];
104 case IF_TYPE_ETHERNET_CSMACD:
105 /* The loopback adapter appears as an Ethernet device. */
106 case IF_TYPE_SOFTWARE_LOOPBACK:
107 msg = STRING_ETHERNET;
110 msg = STRING_UNKNOWN;
113 LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer,
114 sizeof(msg_buffer)/sizeof(WCHAR));
119 static void print_field(int msg, const WCHAR *value)
121 static const WCHAR formatW[] = {' ',' ',' ',' ','%','s',':',' ','%','s','\n',0};
123 WCHAR field[] = {'.',' ','.',' ','.',' ','.',' ','.',' ','.',' ','.',' ','.',' ','.',
124 ' ','.',' ','.',' ','.',' ','.',' ','.',' ','.',' ','.',' ','.',' ',0};
125 WCHAR name_buffer[sizeof(field)/sizeof(WCHAR)];
127 LoadStringW(GetModuleHandleW(NULL), msg, name_buffer, sizeof(name_buffer)/sizeof(WCHAR));
128 memcpy(field, name_buffer, sizeof(WCHAR) * min(strlenW(name_buffer), sizeof(field)/sizeof(WCHAR) - 1));
130 ipconfig_printfW(formatW, field, value);
133 static void print_value(const WCHAR *value)
135 static const WCHAR formatW[] = {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
136 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
137 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
138 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
141 ipconfig_printfW(formatW, value);
144 static BOOL socket_address_to_string(WCHAR *buf, DWORD len, SOCKET_ADDRESS *addr)
146 return WSAAddressToStringW(addr->lpSockaddr,
147 addr->iSockaddrLength, NULL,
151 static void print_basic_information(void)
153 IP_ADAPTER_ADDRESSES *adapters;
156 if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS,
157 NULL, NULL, &out) == ERROR_BUFFER_OVERFLOW)
159 adapters = HeapAlloc(GetProcessHeap(), 0, out);
163 if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS,
164 NULL, adapters, &out) == ERROR_SUCCESS)
166 IP_ADAPTER_ADDRESSES *p;
168 for (p = adapters; p; p = p->Next)
170 static const WCHAR newlineW[] = {'\n',0};
171 static const WCHAR emptyW[] = {0};
173 IP_ADAPTER_UNICAST_ADDRESS *addr;
174 IP_ADAPTER_GATEWAY_ADDRESS_LH *gateway;
177 ipconfig_message_printfW(STRING_ADAPTER_FRIENDLY, iftype_to_string(p->IfType), p->FriendlyName);
178 ipconfig_printfW(newlineW);
179 print_field(STRING_CONN_DNS_SUFFIX, p->DnsSuffix);
181 for (addr = p->FirstUnicastAddress; addr; addr = addr->Next)
183 if (socket_address_to_string(addr_buf, sizeof(addr_buf)/sizeof(WCHAR), &addr->Address))
184 print_field(STRING_IP_ADDRESS, addr_buf);
185 /* FIXME: Output corresponding subnet mask. */
188 if (p->FirstGatewayAddress)
190 if (socket_address_to_string(addr_buf, sizeof(addr_buf)/sizeof(WCHAR), &p->FirstGatewayAddress->Address))
191 print_field(STRING_DEFAULT_GATEWAY, addr_buf);
193 for (gateway = p->FirstGatewayAddress->Next; gateway; gateway = gateway->Next)
195 if (socket_address_to_string(addr_buf, sizeof(addr_buf)/sizeof(WCHAR), &gateway->Address))
196 print_value(addr_buf);
200 print_field(STRING_DEFAULT_GATEWAY, emptyW);
202 ipconfig_printfW(newlineW);
206 HeapFree(GetProcessHeap(), 0, adapters);
210 static const WCHAR *nodetype_to_string(DWORD type)
212 static WCHAR msg_buffer[50];
218 case BROADCAST_NODETYPE:
219 msg = STRING_BROADCAST;
221 case PEER_TO_PEER_NODETYPE:
222 msg = STRING_PEER_TO_PEER;
227 case HYBRID_NODETYPE:
231 msg = STRING_UNKNOWN;
234 LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer,
235 sizeof(msg_buffer)/sizeof(WCHAR));
240 static WCHAR *physaddr_to_string(WCHAR *buf, BYTE *addr, DWORD len)
242 static const WCHAR fmtW[] = {'%','0','2','X','-',0};
243 static const WCHAR fmt2W[] = {'%','0','2','X',0};
252 for (i = 0; i < len - 1; i++)
254 sprintfW(p, fmtW, addr[i]);
257 sprintfW(p, fmt2W, addr[i]);
263 static const WCHAR *boolean_to_string(int value)
265 static WCHAR msg_buffer[15];
267 LoadStringW(GetModuleHandleW(NULL), value ? STRING_YES : STRING_NO,
268 msg_buffer, sizeof(msg_buffer)/sizeof(WCHAR));
273 static void print_full_information(void)
275 static const WCHAR newlineW[] = {'\n',0};
276 static const WCHAR emptyW[] = {0};
279 IP_ADAPTER_ADDRESSES *adapters;
282 if (GetNetworkParams(NULL, &out) == ERROR_BUFFER_OVERFLOW)
284 info = HeapAlloc(GetProcessHeap(), 0, out);
288 if (GetNetworkParams(info, &out) == ERROR_SUCCESS)
290 WCHAR hostnameW[MAX_HOSTNAME_LEN + 4];
292 MultiByteToWideChar(CP_ACP, 0, info->HostName, -1, hostnameW, sizeof(hostnameW)/sizeof(hostnameW[0]));
293 print_field(STRING_HOSTNAME, hostnameW);
295 /* FIXME: Output primary DNS suffix. */
297 print_field(STRING_NODE_TYPE, nodetype_to_string(info->NodeType));
298 print_field(STRING_IP_ROUTING, boolean_to_string(info->EnableRouting));
300 /* FIXME: Output WINS proxy status and DNS suffix search list. */
302 ipconfig_printfW(newlineW);
305 HeapFree(GetProcessHeap(), 0, info);
308 if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS,
309 NULL, NULL, &out) == ERROR_BUFFER_OVERFLOW)
311 adapters = HeapAlloc(GetProcessHeap(), 0, out);
315 if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS,
316 NULL, adapters, &out) == ERROR_SUCCESS)
318 IP_ADAPTER_ADDRESSES *p;
320 for (p = adapters; p; p = p->Next)
322 IP_ADAPTER_UNICAST_ADDRESS *addr;
323 WCHAR physaddr_buf[3 * MAX_ADAPTER_ADDRESS_LENGTH];
324 IP_ADAPTER_GATEWAY_ADDRESS_LH *gateway;
327 ipconfig_message_printfW(STRING_ADAPTER_FRIENDLY, iftype_to_string(p->IfType), p->FriendlyName);
328 ipconfig_printfW(newlineW);
329 print_field(STRING_CONN_DNS_SUFFIX, p->DnsSuffix);
330 print_field(STRING_DESCRIPTION, p->Description);
331 print_field(STRING_PHYS_ADDR, physaddr_to_string(physaddr_buf, p->PhysicalAddress, p->PhysicalAddressLength));
332 print_field(STRING_DHCP_ENABLED, boolean_to_string(p->Flags & IP_ADAPTER_DHCP_ENABLED));
334 /* FIXME: Output autoconfiguration status. */
336 for (addr = p->FirstUnicastAddress; addr; addr = addr->Next)
338 if (socket_address_to_string(addr_buf, sizeof(addr_buf)/sizeof(WCHAR), &addr->Address))
339 print_field(STRING_IP_ADDRESS, addr_buf);
340 /* FIXME: Output corresponding subnet mask. */
343 if (p->FirstGatewayAddress)
345 if (socket_address_to_string(addr_buf, sizeof(addr_buf)/sizeof(WCHAR), &p->FirstGatewayAddress->Address))
346 print_field(STRING_DEFAULT_GATEWAY, addr_buf);
348 for (gateway = p->FirstGatewayAddress->Next; gateway; gateway = gateway->Next)
350 if (socket_address_to_string(addr_buf, sizeof(addr_buf)/sizeof(WCHAR), &gateway->Address))
351 print_value(addr_buf);
355 print_field(STRING_DEFAULT_GATEWAY, emptyW);
357 ipconfig_printfW(newlineW);
361 HeapFree(GetProcessHeap(), 0, adapters);
365 int wmain(int argc, WCHAR *argv[])
367 static const WCHAR slashHelp[] = {'/','?',0};
368 static const WCHAR slashAll[] = {'/','a','l','l',0};
372 if (WSAStartup(MAKEWORD(2, 2), &data))
377 if (!strcmpW(slashHelp, argv[1]))
379 ipconfig_message(STRING_USAGE);
383 else if (!strcmpiW(slashAll, argv[1]))
387 ipconfig_message(STRING_INVALID_CMDLINE);
388 ipconfig_message(STRING_USAGE);
393 print_full_information();
397 ipconfig_message(STRING_INVALID_CMDLINE);
398 ipconfig_message(STRING_USAGE);
404 print_basic_information();