minor update to sync my tree.
[reactos.git] / rosapps / net / ipconfig / ipconfig.c
1 /*
2 * ipconfig - display IP stack parameters.
3 *
4 * This source code is in the PUBLIC DOMAIN and has NO WARRANTY.
5 *
6 * Robert Dickenson <robd@reactos.org>, August 15, 2002.
7 */
8 #include <stdio.h>
9 #include <windows.h>
10 #include <tchar.h>
11 #include <time.h>
12
13 #ifdef __GNUC__
14 #undef WINAPI
15 #define WINAPI
16 #endif
17
18 #include <iptypes.h>
19 #include <ipexport.h>
20 #include <iphlpapi.h>
21
22 #ifdef _DEBUG
23 #include "trace.h"
24 #endif
25
26 ////////////////////////////////////////////////////////////////////////////////
27
28 /* imported from iphlpapi.dll
29
30 GetAdapterOrderMap
31 GetInterfaceInfo
32 GetIpStatsFromStack
33 NhGetInterfaceNameFromGuid
34 NhpAllocateAndGetInterfaceInfoFromStack
35
36 */
37
38 static TCHAR* GetNodeTypeName(int nNodeType)
39 {
40 switch (nNodeType) {
41 case 0: return _T("zero");
42 case 1: return _T("one");
43 case 2: return _T("two");
44 case 3: return _T("three");
45 case 4: return _T("mixed");
46 default: return _T("unknown");
47 }
48 }
49
50 static void ShowNetworkFixedInfo()
51 {
52 FIXED_INFO* pFixedInfo = NULL;
53 ULONG OutBufLen = 0;
54 DWORD result;
55
56 result = GetNetworkParams(NULL, &OutBufLen);
57 if (result == ERROR_BUFFER_OVERFLOW) {
58 pFixedInfo = (FIXED_INFO*)malloc(OutBufLen);
59 if (!pFixedInfo) {
60 _tprintf(_T("ERROR: failed to allocate 0x%08X bytes of memory\n"), OutBufLen);
61 return;
62 }
63 } else {
64 _tprintf(_T("ERROR: GetNetworkParams() failed to report required buffer size.\n"));
65 return;
66 }
67
68 result = GetNetworkParams(pFixedInfo, &OutBufLen);
69 if (result == ERROR_SUCCESS) {
70 IP_ADDR_STRING* pIPAddr;
71
72 printf("\tHostName. . . . . . . . . . . : %s\n", pFixedInfo->HostName);
73 printf("\tDomainName. . . . . . . . . . : %s\n", pFixedInfo->DomainName);
74 //
75 printf("\tDNS Servers . . . . . . . . . : %s\n", pFixedInfo->DnsServerList.IpAddress.String);
76 pIPAddr = pFixedInfo->DnsServerList.Next;
77 while (pIPAddr) {
78 printf("\t\t\t\t : %s\n", pIPAddr->IpAddress.String);
79 pIPAddr = pIPAddr->Next;
80 }
81 //
82 _tprintf(_T("\tNodeType. . . . . . . . . . . : %d (%s)\n"), pFixedInfo->NodeType, GetNodeTypeName(pFixedInfo->NodeType));
83 printf("\tScopeId . . . . . . . . . . . : %s\n", pFixedInfo->ScopeId);
84 _tprintf(_T("\tEnableRouting . . . . . . . . : %s\n"), pFixedInfo->EnableRouting ? _T("yes") : _T("no"));
85 _tprintf(_T("\tEnableProxy . . . . . . . . . : %s\n"), pFixedInfo->EnableProxy ? _T("yes") : _T("no"));
86 _tprintf(_T("\tEnableDns . . . . . . . . . . : %s\n"), pFixedInfo->EnableDns ? _T("yes") : _T("no"));
87 _tprintf(_T("\n"));
88 //_tprintf(_T("\n"),);
89 //_tprintf(_T("GetNetworkParams() returned with %d\n"), pIfTable->NumAdapters);
90
91 // _tprintf(_T("\tConnection specific DNS suffix: %s\n"), pFixedInfo->EnableDns ? _T("yes") : _T("no"));
92
93 } else {
94 switch (result) {
95 case ERROR_BUFFER_OVERFLOW:
96 _tprintf(_T("The buffer size indicated by the pOutBufLen parameter is too small to hold the adapter information. The pOutBufLen parameter points to the required size\n"));
97 break;
98 case ERROR_INVALID_PARAMETER:
99 _tprintf(_T("The pOutBufLen parameter is NULL, or the calling process does not have read/write access to the memory pointed to by pOutBufLen, or the calling process does not have write access to the memory pointed to by the pAdapterInfo parameter\n"));
100 break;
101 case ERROR_NO_DATA:
102 _tprintf(_T("No adapter information exists for the local computer\n"));
103 break;
104 case ERROR_NOT_SUPPORTED:
105 _tprintf(_T("This function is not supported on the operating system in use on the local system\n"));
106 break;
107 default:
108 _tprintf(_T("0x%08X - Use FormatMessage to obtain the message string for the returned error\n"), result);
109 break;
110 }
111 }
112 }
113
114 static void ShowNetworkInterfaces()
115 {
116 IP_INTERFACE_INFO* pIfTable = NULL;
117 DWORD result;
118 DWORD dwNumIf;
119 DWORD dwOutBufLen = 0;
120
121 if ((result = GetNumberOfInterfaces(&dwNumIf)) != NO_ERROR) {
122 _tprintf(_T("GetNumberOfInterfaces() failed with code 0x%08X - Use FormatMessage to obtain the message string for the returned error\n"), result);
123 return;
124 } else {
125 _tprintf(_T("GetNumberOfInterfaces() returned %d\n"), dwNumIf);
126 }
127
128 result = GetInterfaceInfo(pIfTable, &dwOutBufLen);
129 // dwOutBufLen = sizeof(IP_INTERFACE_INFO) + dwNumIf * sizeof(IP_ADAPTER_INDEX_MAP);
130 // _tprintf(_T("GetNumberOfInterfaces() returned %d, dwOutBufLen %d\n"), dwNumIf, dwOutBufLen);
131 // _tprintf(_T("sizeof(IP_INTERFACE_INFO) %d, sizeof(IP_ADAPTER_INDEX_MAP) %d\n"), sizeof(IP_INTERFACE_INFO), sizeof(IP_ADAPTER_INDEX_MAP));
132
133 pIfTable = (IP_INTERFACE_INFO*)malloc(dwOutBufLen);
134 if (!pIfTable) {
135 _tprintf(_T("ERROR: failed to allocate 0x%08X bytes of memory\n"), dwOutBufLen);
136 return;
137 }
138 /*
139 typedef struct _IP_ADAPTER_INDEX_MAP {
140 ULONG Index; // adapter index
141 WCHAR Name[MAX_ADAPTER_NAME]; // name of the adapter
142 } IP_ADAPTER_INDEX_MAP, * PIP_ADAPTER_INDEX_MAP;
143
144 typedef struct _IP_INTERFACE_INFO {
145 LONG NumAdapters; // number of adapters in array
146 IP_ADAPTER_INDEX_MAP Adapter[1]; // adapter indices and names
147 } IP_INTERFACE_INFO,*PIP_INTERFACE_INFO;
148 */
149 result = GetInterfaceInfo(pIfTable, &dwOutBufLen);
150 if (result == NO_ERROR) {
151 int i;
152 _tprintf(_T("GetInterfaceInfo() returned with %d adaptor entries\n"), pIfTable->NumAdapters);
153 for (i = 0; i < pIfTable->NumAdapters; i++) {
154 wprintf(L"[%d] %s\n", i + 1, pIfTable->Adapter[i].Name);
155 //wprintf(L"[%d] %s\n", pIfTable->Adapter[i].Index, pIfTable->Adapter[i].Name);
156
157 // \DEVICE\TCPIP_{DB0E61C1-3498-4C5F-B599-59CDE8A1E357}
158 // \DEVICE\TCPIP_{BD445697-0945-4591-AE7F-2AB0F383CA87}
159 // \DEVICE\TCPIP_{6D87DC08-6BC5-4E78-AB5F-18CAB785CFFE}
160
161 //HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NetBT\Parameters\Interfaces\Tcpip_{DB0E61C1-3498-4C5F-B599-59CDE8A1E357}
162 }
163 } else {
164 switch (result) {
165 case ERROR_INVALID_PARAMETER:
166 _tprintf(_T("The dwOutBufLen parameter is NULL, or GetInterfaceInterface is unable to write to the memory pointed to by the dwOutBufLen parameter\n"));
167 break;
168 case ERROR_INSUFFICIENT_BUFFER:
169 _tprintf(_T("The buffer pointed to by the pIfTable parameter is not large enough. The required size is returned in the DWORD variable pointed to by the dwOutBufLen parameter\n"));
170 _tprintf(_T("\tdwOutBufLen: %d\n"), dwOutBufLen);
171 break;
172 case ERROR_NOT_SUPPORTED:
173 _tprintf(_T("This function is not supported on the operating system in use on the local system\n"));
174 break;
175 default:
176 _tprintf(_T("0x%08X - Use FormatMessage to obtain the message string for the returned error\n"), result);
177 break;
178 }
179 }
180 free(pIfTable);
181 }
182
183 /*
184 typedef struct _IP_ADAPTER_INFO {
185 struct _IP_ADAPTER_INFO* Next;
186 DWORD ComboIndex;
187 char AdapterName[MAX_ADAPTER_NAME_LENGTH + 4];
188 1 char Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4];
189 UINT AddressLength;
190 2 BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH];
191 DWORD Index;
192 UINT Type;
193 3 UINT DhcpEnabled;
194 5 PIP_ADDR_STRING CurrentIpAddress;
195 IP_ADDR_STRING IpAddressList;
196 7 IP_ADDR_STRING GatewayList;
197 8 IP_ADDR_STRING DhcpServer;
198 BOOL HaveWins;
199 IP_ADDR_STRING PrimaryWinsServer;
200 IP_ADDR_STRING SecondaryWinsServer;
201 a time_t LeaseObtained;
202 b time_t LeaseExpires;
203 } IP_ADAPTER_INFO, *PIP_ADAPTER_INFO;
204 */
205 /*
206 Ethernet adapter VMware Virtual Ethernet Adapter (Network Address Translation (NAT) for VMnet8):
207
208 Connection-specific DNS Suffix . :
209 1 Description . . . . . . . . . . . : VMware Virtual Ethernet Adapter (Network Address Translation (NAT) for VMnet8)
210 2 Physical Address. . . . . . . . . : 00-50-56-C0-00-08
211 3 DHCP Enabled. . . . . . . . . . . : Yes
212 Autoconfiguration Enabled . . . . : Yes
213 5 IP Address. . . . . . . . . . . . : 192.168.136.1
214 Subnet Mask . . . . . . . . . . . : 255.255.255.0
215 7 Default Gateway . . . . . . . . . :
216 8 DHCP Server . . . . . . . . . . . : 192.168.136.254
217 DNS Servers . . . . . . . . . . . :
218 a Lease Obtained. . . . . . . . . . : Monday, 30 December 2002 5:56:53 PM
219 b Lease Expires . . . . . . . . . . : Monday, 30 December 2002 6:26:53 PM
220 */
221 static void ShowAdapterInfo()
222 {
223 IP_ADAPTER_INFO* pAdaptorInfo;
224 ULONG ulOutBufLen;
225 DWORD dwRetVal;
226
227 _tprintf(_T("\nAdaptor Information\t\n"));
228 pAdaptorInfo = (IP_ADAPTER_INFO*)GlobalAlloc(GPTR, sizeof(IP_ADAPTER_INFO));
229 ulOutBufLen = sizeof(IP_ADAPTER_INFO);
230
231 if (ERROR_BUFFER_OVERFLOW == GetAdaptersInfo(pAdaptorInfo, &ulOutBufLen)) {
232 GlobalFree(pAdaptorInfo);
233 pAdaptorInfo = (IP_ADAPTER_INFO*)GlobalAlloc(GPTR, ulOutBufLen);
234 }
235 if (dwRetVal = GetAdaptersInfo(pAdaptorInfo, &ulOutBufLen)) {
236 _tprintf(_T("Call to GetAdaptersInfo failed. Return Value: %08x\n"), dwRetVal);
237 } else {
238 while (pAdaptorInfo) {
239 printf(" AdapterName: %s\n", pAdaptorInfo->AdapterName);
240 printf(" Description: %s\n", pAdaptorInfo->Description);
241 pAdaptorInfo = pAdaptorInfo->Next;
242 }
243 }
244 }
245
246 const char szUsage[] = { "USAGE:\n" \
247 " ipconfig [/? | /all | /release [adapter] | /renew [adapter]\n" \
248 " | /flushdns | /registerdns\n" \
249 " | /showclassid adapter\n" \
250 " | /showclassid adapter\n" \
251 " | /setclassid adapter [classidtoset] ]\n" \
252 "\n" \
253 "adapter Full name or pattern with '*' and '?' to 'match',\n" \
254 " * matches any character, ? matches one character.\n" \
255 " Options\n" \
256 " /? Display this help message.\n" \
257 " /all Display full configuration information.\n" \
258 " /release Release the IP address for the specified adapter.\n" \
259 " /renew Renew the IP address for the specified adapter.\n" \
260 " /flushdns Purges the DNS Resolver cache.\n" \
261 " /registerdns Refreshes all DHCP leases and re-registers DNS names\n" \
262 " /displaydns Display the contents of the DNS Resolver Cache.\n" \
263 " /showclassid Displays all the dhcp class IDs allowed for adapter.\n" \
264 " /setclassid Modifies the dhcp class id.\n" \
265 "\n" \
266 "The default is to display only the IP address, subnet mask and\n" \
267 "default gateway for each adapter bound to TCP/IP.\n"
268 };
269 /*
270 "\n" \
271 "For Release and Renew, if no adapter name is specified, then the IP address\n" \
272 "leases for all adapters bound to TCP/IP will be released or renewed.\n" \
273 "\n" \
274 "For SetClassID, if no class id is specified, then the classid is removed.\n" \
275 "\n" \
276 "Examples:\n" \
277 " > ipconfig ... Show information.\n" \
278 " > ipconfig /all ... Show detailed information\n" \
279 " > ipconfig /renew ... renew all adapaters\n" \
280 " > ipconfig /renew EL* ... renew adapters named EL....\n" \
281 " > ipconfig /release *ELINK?21* ... release all matching adapters,\n" \
282 eg. ELINK-21, myELELINKi21adapter.\n"
283 */
284
285 static void usage(void)
286 {
287 fputs(szUsage, stderr);
288 }
289
290
291 int main(int argc, char *argv[])
292 {
293 // 10.0.0.100 // As of build 0.0.20 this is hardcoded in the ip stack
294
295 if (argc > 1) {
296 usage();
297 return 1;
298 }
299 _tprintf(_T("ReactOS IP Configuration\n"));
300 ShowNetworkFixedInfo();
301 ShowNetworkInterfaces();
302 ShowAdapterInfo();
303 return 0;
304 }