2 * ReactOS Win32 Applications
3 * Copyright (C) 2005 ReactOS Team
5 * COPYRIGHT: See COPYING in the top level directory
6 * PROJECT: ReactOS arp utility
7 * FILE: apps/utils/net/ipconfig/ipconfig.c
9 * PROGRAMMERS: Ged Murphy (gedmurphy@gmail.com)
17 * implement flushdns, registerdns, displaydns, showclassid, setclassid
18 * allow globbing on adapter names
20 #define WIN32_LEAN_AND_MEAN
35 PTCHAR
GetNodeTypeName(UINT NodeType
)
38 case 1: return _T("Broadcast");
39 case 2: return _T("Peer To Peer");
40 case 4: return _T("Mixed");
41 case 8: return _T("Hybrid");
42 default : return _T("unknown");
46 PTCHAR
GetInterfaceTypeName(UINT InterfaceType
)
48 switch (InterfaceType
) {
49 case MIB_IF_TYPE_OTHER
: return _T("Other Type Of Adapter");
50 case MIB_IF_TYPE_ETHERNET
: return _T("Ethernet Adapter");
51 case MIB_IF_TYPE_TOKENRING
: return _T("Token Ring Adapter");
52 case MIB_IF_TYPE_FDDI
: return _T("FDDI Adapter");
53 case MIB_IF_TYPE_PPP
: return _T("PPP Adapter");
54 case MIB_IF_TYPE_LOOPBACK
: return _T("Loopback Adapter");
55 case MIB_IF_TYPE_SLIP
: return _T("SLIP Adapter");
56 default: return _T("unknown");
60 /* print MAC address */
61 PTCHAR
PrintMacAddr(PBYTE Mac
)
63 static TCHAR MacAddr
[20];
65 _stprintf(MacAddr
, _T("%02x-%02x-%02x-%02x-%02x-%02x"),
66 Mac
[0], Mac
[1], Mac
[2], Mac
[3], Mac
[4], Mac
[5]);
71 DWORD
DoFormatMessage(DWORD ErrorCode
)
76 if ((RetVal
= FormatMessage(
77 FORMAT_MESSAGE_ALLOCATE_BUFFER
|
78 FORMAT_MESSAGE_FROM_SYSTEM
|
79 FORMAT_MESSAGE_IGNORE_INSERTS
,
82 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
), /* Default language */
86 _tprintf(_T("%s"), (LPTSTR
)lpMsgBuf
);
89 /* return number of TCHAR's stored in output buffer
90 * excluding '\0' - as FormatMessage does*/
97 INT
ShowInfo(BOOL bAll
)
99 PIP_ADAPTER_INFO pAdapterInfo
= NULL
;
100 PIP_ADAPTER_INFO pAdapter
= NULL
;
101 ULONG adaptOutBufLen
;
103 PFIXED_INFO pFixedInfo
;
105 PIP_ADDR_STRING pIPAddr
= NULL
;
107 /* assign memory for call to GetNetworkParams */
108 pFixedInfo
= (FIXED_INFO
*) GlobalAlloc( GPTR
, sizeof( FIXED_INFO
) );
109 netOutBufLen
= sizeof(FIXED_INFO
);
111 /* assign memory for call to GetAdapterInfo */
112 pAdapterInfo
= (IP_ADAPTER_INFO
*) malloc( sizeof(IP_ADAPTER_INFO
) );
113 adaptOutBufLen
= sizeof(IP_ADAPTER_INFO
);
115 /* set required buffer size */
116 if(GetNetworkParams(pFixedInfo
, &netOutBufLen
) == ERROR_BUFFER_OVERFLOW
)
118 GlobalFree(pFixedInfo
);
119 pFixedInfo
= (FIXED_INFO
*) GlobalAlloc(GPTR
, netOutBufLen
);
122 /* set required buffer size */
123 if (GetAdaptersInfo( pAdapterInfo
, &adaptOutBufLen
) == ERROR_BUFFER_OVERFLOW
)
126 pAdapterInfo
= (IP_ADAPTER_INFO
*) malloc (adaptOutBufLen
);
129 if (! GetAdaptersInfo(pAdapterInfo
, &adaptOutBufLen
) == NO_ERROR
)
131 _tprintf(_T("GetAdaptersInfo failed %lu\n"), GetLastError());
135 if (! GetNetworkParams(pFixedInfo
, &netOutBufLen
) == NO_ERROR
)
137 _tprintf(_T("GetNetworkParams failed %lu\n"), GetLastError());
141 pAdapter
= pAdapterInfo
;
143 //LPCTSTR lpSubKey = _T("SYSTEM\\ControlSet\\Control\\Network");
145 _tprintf(_T("\nReactOS IP Configuration\n\n"));
151 _tprintf(_T("\tHost Name . . . . . . . . . . . . : %s\n"), pFixedInfo
->HostName
);
152 _tprintf(_T("\tPrimary DNS Suffix. . . . . . . . : \n"));
153 _tprintf(_T("\tNode Type . . . . . . . . . . . . : %s\n"), GetNodeTypeName(pFixedInfo
->NodeType
));
154 if (pFixedInfo
->EnableRouting
)
155 _tprintf(_T("\tIP Routing Enabled. . . . . . . . : Yes\n"));
157 _tprintf(_T("\tIP Routing Enabled. . . . . . . . : No\n"));
158 if (pAdapter
->HaveWins
)
159 _tprintf(_T("\tWINS Proxy enabled. . . . . . . . : Yes\n"));
161 _tprintf(_T("\tWINS Proxy enabled. . . . . . . . : No\n"));
162 _tprintf(_T("\tDNS Suffix Search List. . . . . . : %s\n"), pFixedInfo
->DomainName
);
165 _tprintf(_T("\n%s ...... : \n\n"), GetInterfaceTypeName(pAdapter
->Type
));
167 /* check if the adapter is connected to the media */
168 if (_tcscmp(pAdapter
->IpAddressList
.IpAddress
.String
, "0.0.0.0") == 0)
170 _tprintf(_T("\tMedia State . . . . . . . . . . . : Media disconnected\n"));
171 pAdapter
= pAdapter
->Next
;
175 _tprintf(_T("\tConnection-specific DNS Suffix. . : %s\n"), pFixedInfo
->DomainName
);
179 _tprintf(_T("\tDescription . . . . . . . . . . . : %s\n"), pAdapter
->Description
);
180 _tprintf(_T("\tPhysical Address. . . . . . . . . : %s\n"), PrintMacAddr(pAdapter
->Address
));
181 if (pAdapter
->DhcpEnabled
)
182 _tprintf(_T("\tDHCP Enabled. . . . . . . . . . . : Yes\n"));
184 _tprintf(_T("\tDHCP Enabled. . . . . . . . . . . : No\n"));
185 _tprintf(_T("\tAutoconfiguration Enabled . . . . : \n"));
188 _tprintf(_T("\tIP Address. . . . . . . . . . . . : %s\n"), pAdapter
->IpAddressList
.IpAddress
.String
);
189 _tprintf(_T("\tSubnet Mask . . . . . . . . . . . : %s\n"), pAdapter
->IpAddressList
.IpMask
.String
);
190 _tprintf(_T("\tDefault Gateway . . . . . . . . . : %s\n"), pAdapter
->GatewayList
.IpAddress
.String
);
194 if (pAdapter
->DhcpEnabled
)
195 _tprintf(_T("\tDHCP Server . . . . . . . . . . . : %s\n"), pAdapter
->DhcpServer
.IpAddress
.String
);
197 _tprintf(_T("\tDNS Servers . . . . . . . . . . . : "));
198 _tprintf(_T("%s\n"), pFixedInfo
->DnsServerList
.IpAddress
.String
);
199 pIPAddr
= pFixedInfo
-> DnsServerList
.Next
;
202 _tprintf(_T("\t\t\t\t\t %s\n"), pIPAddr
->IpAddress
.String
);
203 pIPAddr
= pIPAddr
->Next
;
205 if (pAdapter
->HaveWins
)
207 _tprintf(_T("\tPrimary WINS Server . . . . . . . : %s\n"), pAdapter
->PrimaryWinsServer
.IpAddress
.String
);
208 _tprintf(_T("\tSecondard WINS Server . . . . . . : %s\n"), pAdapter
->SecondaryWinsServer
.IpAddress
.String
);
210 if (pAdapter
->DhcpEnabled
)
212 _tprintf(_T("\tLease Obtained. . . . . . . . . . : %s"), _tasctime(localtime(&pAdapter
->LeaseObtained
)));
213 _tprintf(_T("\tLease Expires . . . . . . . . . . : %s"), _tasctime(localtime(&pAdapter
->LeaseExpires
)));
218 pAdapter
= pAdapter
->Next
;
225 INT
Release(TCHAR Index
)
227 IP_ADAPTER_INDEX_MAP AdapterInfo
;
230 /* if interface is not given, query GetInterfaceInfo */
231 if (Index
== (TCHAR
)NULL
)
233 PIP_INTERFACE_INFO pInfo
;
234 pInfo
= (IP_INTERFACE_INFO
*) malloc(sizeof(IP_INTERFACE_INFO
));
235 ULONG ulOutBufLen
= 0;
237 /* Make an initial call to GetInterfaceInfo to get
238 * the necessary size into the ulOutBufLen variable */
239 if ( GetInterfaceInfo(pInfo
, &ulOutBufLen
) == ERROR_INSUFFICIENT_BUFFER
)
242 pInfo
= (IP_INTERFACE_INFO
*) malloc (ulOutBufLen
);
245 /* Make a second call to GetInterfaceInfo to get the actual data we want */
246 if ((dwRetVal
= GetInterfaceInfo(pInfo
, &ulOutBufLen
)) == NO_ERROR
)
248 AdapterInfo
= pInfo
->Adapter
[0];
249 _tprintf(_T("name - %S\n"), pInfo
->Adapter
[0].Name
);
253 _tprintf(_T("\nGetInterfaceInfo failed : "));
254 DoFormatMessage(dwRetVal
);
260 /* we need to be able to release connections by name with support for globbing
261 * i.e. ipconfig /release Eth* will release all cards starting with Eth...
262 * ipconfig /release *con* will release all cards with 'con' in their name
267 /* Call IpReleaseAddress to release the IP address on the specified adapter. */
268 if ((dwRetVal
= IpReleaseAddress(&AdapterInfo
)) != NO_ERROR
)
270 _tprintf(_T("\nAn error occured while releasing interface %s : "), _T("*name*"));
271 DoFormatMessage(dwRetVal
);
279 INT
Renew(TCHAR Index
)
281 IP_ADAPTER_INDEX_MAP AdapterInfo
;
284 /* if interface is not given, query GetInterfaceInfo */
285 if (Index
== (TCHAR
)NULL
)
287 PIP_INTERFACE_INFO pInfo
;
288 pInfo
= (IP_INTERFACE_INFO
*) malloc(sizeof(IP_INTERFACE_INFO
));
289 ULONG ulOutBufLen
= 0;
291 /* Make an initial call to GetInterfaceInfo to get
292 * the necessary size into the ulOutBufLen variable */
293 if ( GetInterfaceInfo(pInfo
, &ulOutBufLen
) == ERROR_INSUFFICIENT_BUFFER
)
296 pInfo
= (IP_INTERFACE_INFO
*) malloc (ulOutBufLen
);
299 /* Make a second call to GetInterfaceInfo to get the actual data we want */
300 if ((dwRetVal
= GetInterfaceInfo(pInfo
, &ulOutBufLen
)) == NO_ERROR
)
302 AdapterInfo
= pInfo
->Adapter
[0];
303 _tprintf(_T("name - %S\n"), pInfo
->Adapter
[0].Name
);
305 _tprintf(_T("\nGetInterfaceInfo failed : "));
306 DoFormatMessage(dwRetVal
);
312 /* we need to be able to renew connections by name with support for globbing
313 * i.e. ipconfig /renew Eth* will renew all cards starting with Eth...
314 * ipconfig /renew *con* will renew all cards with 'con' in their name
319 /* Call IpRenewAddress to renew the IP address on the specified adapter. */
320 if ((dwRetVal
= IpRenewAddress(&AdapterInfo
)) != NO_ERROR
)
322 _tprintf(_T("\nAn error occured while renew interface %s : "), _T("*name*"));
323 DoFormatMessage(dwRetVal
);
328 /* temp func for testing purposes */
331 // Declare and initialize variables
332 PIP_INTERFACE_INFO pInfo
;
333 pInfo
= (IP_INTERFACE_INFO
*) malloc( sizeof(IP_INTERFACE_INFO
) );
334 ULONG ulOutBufLen
= sizeof(IP_INTERFACE_INFO
);
338 // Make an initial call to GetInterfaceInfo to get
339 // the necessary size in the ulOutBufLen variable
340 if ( GetInterfaceInfo(pInfo
, &ulOutBufLen
) == ERROR_INSUFFICIENT_BUFFER
)
343 pInfo
= (IP_INTERFACE_INFO
*) malloc (ulOutBufLen
);
346 // Make a second call to GetInterfaceInfo to get
347 // the actual data we need
348 if ((dwRetVal
= GetInterfaceInfo(pInfo
, &ulOutBufLen
)) == NO_ERROR
)
351 for (i
=0; i
<pInfo
->NumAdapters
; i
++)
353 printf("\tAdapter Name: %S\n", pInfo
->Adapter
[i
].Name
);
354 printf("\tAdapter Index: %ld\n", pInfo
->Adapter
[i
].Index
);
355 printf("\tNum Adapters: %ld\n", pInfo
->NumAdapters
);
360 printf("GetInterfaceInfo failed.\n");
361 DoFormatMessage(dwRetVal
);
368 _tprintf(_T("\nUSAGE:\n"
369 " ipconfig [/? | /all | /renew [adapter] | /release [adapter] |\n"
370 " /flushdns | /displaydns | /registerdns |\n"
371 " /showclassid adapter |\n"
372 " /setclassid adapter [classid] ]\n"
375 " adapter Connection name\n"
376 " (wildcard characters * and ? allowed, see examples)\n"
379 " /? Display this help message\n"
380 " /all Display full configuration information.\n"
381 " /release Release the IP address for the specified adapter.\n"
382 " /renew Renew the IP address for the specified adapter.\n"
383 " /flushdns Purges the DNS Resolver cache.\n"
384 " /registerdns Refreshes all DHCP leases and re-registers DNS names.\n"
385 " /displaydns Display the contents of the DNS Resolver Cache.\n"
386 " /showclassid Displays all the dhcp class IDs allowed for adapter.\n"
387 " /setclassid Modifies the dhcp class id.\n"
389 "The default is to display only the IP address, subnet mask and\n"
390 "default gateway for each adapter bound to TCP/IP.\n"
392 "For Release and Renew, if no adapter name is specified, then the IP address\n"
393 "leases for all adapters bound to TCP/IP will be released or renewed.\n"
395 "For Setclassid, if no ClassId is specified, then the ClassId is removed.\n"
398 " > ipconfig ... Show information.\n"
399 " > ipconfig /all ... Show detailed information\n"
400 " > ipconfig /renew ... renew all adapters\n"
401 " > ipconfig /renew EL* ... renew any connection that has its\n"
402 " name starting with EL\n"
403 " > ipconfig /release *Con* ... release all matching connections,\n"
404 " eg. \"Local Area Connection 1\" or\n"
405 " \"Local Area Connection 2\"\n"));
408 int main(int argc
, char *argv
[])
412 BOOL DoRelease
=FALSE
;
414 BOOL DoFlushdns
=FALSE
;
415 BOOL DoRegisterdns
=FALSE
;
416 BOOL DoDisplaydns
=FALSE
;
417 BOOL DoShowclassid
=FALSE
;
418 BOOL DoSetclassid
=FALSE
;
420 /* Parse command line for options we have been given. */
421 if ( (argc
> 1)&&(argv
[1][0]=='/') )
423 if( !_tcsicmp( &argv
[1][1], _T("?") ))
427 else if( !_tcsnicmp( &argv
[1][1], _T("ALL"), _tcslen(&argv
[1][1]) ))
431 else if( !_tcsnicmp( &argv
[1][1], _T("RELEASE"), _tcslen(&argv
[1][1]) ))
435 else if( ! _tcsnicmp( &argv
[1][1], _T("RENEW"), _tcslen(&argv
[1][1]) ))
439 else if( ! _tcsnicmp( &argv
[1][1], _T("FLUSHDNS"), _tcslen(&argv
[1][1]) ))
443 else if( ! _tcsnicmp( &argv
[1][1], _T("FLUSHREGISTERDNS"), _tcslen(&argv
[1][1]) ))
445 DoRegisterdns
= TRUE
;
447 else if( ! _tcsnicmp( &argv
[1][1], _T("DISPLAYDNS"), _tcslen(&argv
[1][1]) ))
451 else if( ! _tcsnicmp( &argv
[1][1], _T("SHOWCLASSID"), _tcslen(&argv
[1][1]) ))
453 DoShowclassid
= TRUE
;
455 else if( ! _tcsnicmp( &argv
[1][1], _T("SETCLASSID"), _tcslen(&argv
[1][1]) ))
463 case 1: /* Default behaviour if no options are given*/
466 case 2: /* Process all the options that take no paramiters */
472 Release((TCHAR
)NULL
);
476 _tprintf(_T("\nSorry /flushdns is not implemented yet\n"));
477 else if (DoRegisterdns
)
478 _tprintf(_T("\nSorry /registerdns is not implemented yet\n"));
479 else if (DoDisplaydns
)
480 _tprintf(_T("\nSorry /displaydns is not implemented yet\n"));
484 case 3: /* Process all the options that can have 1 paramiters */
486 _tprintf(_T("\nSorry /release [adapter] is not implemented yet\n"));
489 _tprintf(_T("\nSorry /renew [adapter] is not implemented yet\n"));
490 else if (DoShowclassid
)
491 _tprintf(_T("\nSorry /showclassid adapter is not implemented yet\n"));
492 else if (DoSetclassid
)
493 _tprintf(_T("\nSorry /setclassid adapter is not implemented yet\n"));
497 case 4: /* Process all the options that can have 2 paramiters */
499 _tprintf(_T("\nSorry /setclassid adapter [classid]is not implemented yet\n"));