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
36 LPCTSTR
GetNodeTypeName(UINT NodeType
)
39 case 1: return _T("Broadcast");
40 case 2: return _T("Peer To Peer");
41 case 4: return _T("Mixed");
42 case 8: return _T("Hybrid");
43 default : return _T("unknown");
47 LPCTSTR
GetInterfaceTypeName(UINT InterfaceType
)
49 switch (InterfaceType
) {
50 case MIB_IF_TYPE_OTHER
: return _T("Other Type Of Adapter");
51 case MIB_IF_TYPE_ETHERNET
: return _T("Ethernet Adapter");
52 case MIB_IF_TYPE_TOKENRING
: return _T("Token Ring Adapter");
53 case MIB_IF_TYPE_FDDI
: return _T("FDDI Adapter");
54 case MIB_IF_TYPE_PPP
: return _T("PPP Adapter");
55 case MIB_IF_TYPE_LOOPBACK
: return _T("Loopback Adapter");
56 case MIB_IF_TYPE_SLIP
: return _T("SLIP Adapter");
57 default: return _T("unknown");
61 /* print MAC address */
62 PTCHAR
PrintMacAddr(PBYTE Mac
)
64 static TCHAR MacAddr
[20];
66 _stprintf(MacAddr
, _T("%02x-%02x-%02x-%02x-%02x-%02x"),
67 Mac
[0], Mac
[1], Mac
[2], Mac
[3], Mac
[4], Mac
[5]);
72 DWORD
DoFormatMessage(DWORD ErrorCode
)
77 if ((RetVal
= FormatMessage(
78 FORMAT_MESSAGE_ALLOCATE_BUFFER
|
79 FORMAT_MESSAGE_FROM_SYSTEM
|
80 FORMAT_MESSAGE_IGNORE_INSERTS
,
83 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
), /* Default language */
87 _tprintf(_T("%s"), (LPTSTR
)lpMsgBuf
);
90 /* return number of TCHAR's stored in output buffer
91 * excluding '\0' - as FormatMessage does*/
98 INT
ShowInfo(BOOL bAll
)
100 PIP_ADAPTER_INFO pAdapterInfo
= NULL
;
101 PIP_ADAPTER_INFO pAdapter
= NULL
;
102 ULONG adaptOutBufLen
;
104 PFIXED_INFO pFixedInfo
;
106 PIP_ADDR_STRING pIPAddr
= NULL
;
110 /* assign memory for call to GetNetworkParams */
111 pFixedInfo
= (FIXED_INFO
*) GlobalAlloc( GPTR
, sizeof( FIXED_INFO
) );
112 netOutBufLen
= sizeof(FIXED_INFO
);
114 /* assign memory for call to GetAdapterInfo */
115 pAdapterInfo
= (IP_ADAPTER_INFO
*) malloc( sizeof(IP_ADAPTER_INFO
) );
116 adaptOutBufLen
= sizeof(IP_ADAPTER_INFO
);
118 /* set required buffer size */
119 if(GetNetworkParams(pFixedInfo
, &netOutBufLen
) == ERROR_BUFFER_OVERFLOW
)
121 GlobalFree(pFixedInfo
);
122 pFixedInfo
= (FIXED_INFO
*) GlobalAlloc(GPTR
, netOutBufLen
);
125 /* set required buffer size */
126 if (GetAdaptersInfo( pAdapterInfo
, &adaptOutBufLen
) == ERROR_BUFFER_OVERFLOW
)
129 pAdapterInfo
= (IP_ADAPTER_INFO
*) malloc (adaptOutBufLen
);
132 if ((ErrRet
= GetAdaptersInfo(pAdapterInfo
, &adaptOutBufLen
)) != NO_ERROR
)
134 _tprintf(_T("GetAdaptersInfo failed : "));
135 DoFormatMessage(ErrRet
);
139 if ((ErrRet
= GetNetworkParams(pFixedInfo
, &netOutBufLen
)) != NO_ERROR
)
141 _tprintf(_T("GetNetworkParams failed : "));
142 DoFormatMessage(ErrRet
);
146 pAdapter
= pAdapterInfo
;
148 _tprintf(_T("\nReactOS IP Configuration\n\n"));
152 _tprintf(_T("\tHost Name . . . . . . . . . . . . : %s\n"), pFixedInfo
->HostName
);
153 _tprintf(_T("\tPrimary DNS Suffix. . . . . . . . : \n"));
154 _tprintf(_T("\tNode Type . . . . . . . . . . . . : %s\n"), GetNodeTypeName(pFixedInfo
->NodeType
));
155 if (pFixedInfo
->EnableRouting
)
156 _tprintf(_T("\tIP Routing Enabled. . . . . . . . : Yes\n"));
158 _tprintf(_T("\tIP Routing Enabled. . . . . . . . : No\n"));
159 if (pAdapter
->HaveWins
)
160 _tprintf(_T("\tWINS Proxy enabled. . . . . . . . : Yes\n"));
162 _tprintf(_T("\tWINS Proxy enabled. . . . . . . . : No\n"));
163 _tprintf(_T("\tDNS Suffix Search List. . . . . . : %s\n"), pFixedInfo
->DomainName
);
169 _tprintf(_T("\n%s ...... : \n\n"), GetInterfaceTypeName(pAdapter
->Type
));
171 /* check if the adapter is connected to the media */
172 if (_tcscmp(pAdapter
->IpAddressList
.IpAddress
.String
, "0.0.0.0") == 0)
174 _tprintf(_T("\tMedia State . . . . . . . . . . . : Media disconnected\n"));
175 pAdapter
= pAdapter
->Next
;
179 _tprintf(_T("\tConnection-specific DNS Suffix. . : %s\n"), pFixedInfo
->DomainName
);
183 _tprintf(_T("\tDescription . . . . . . . . . . . : %s\n"), pAdapter
->Description
);
184 _tprintf(_T("\tPhysical Address. . . . . . . . . : %s\n"), PrintMacAddr(pAdapter
->Address
));
185 if (pAdapter
->DhcpEnabled
)
186 _tprintf(_T("\tDHCP Enabled. . . . . . . . . . . : Yes\n"));
188 _tprintf(_T("\tDHCP Enabled. . . . . . . . . . . : No\n"));
189 _tprintf(_T("\tAutoconfiguration Enabled . . . . : \n"));
192 _tprintf(_T("\tIP Address. . . . . . . . . . . . : %s\n"), pAdapter
->IpAddressList
.IpAddress
.String
);
193 _tprintf(_T("\tSubnet Mask . . . . . . . . . . . : %s\n"), pAdapter
->IpAddressList
.IpMask
.String
);
194 _tprintf(_T("\tDefault Gateway . . . . . . . . . : %s\n"), pAdapter
->GatewayList
.IpAddress
.String
);
198 if (pAdapter
->DhcpEnabled
)
199 _tprintf(_T("\tDHCP Server . . . . . . . . . . . : %s\n"), pAdapter
->DhcpServer
.IpAddress
.String
);
201 _tprintf(_T("\tDNS Servers . . . . . . . . . . . : "));
202 _tprintf(_T("%s\n"), pFixedInfo
->DnsServerList
.IpAddress
.String
);
203 pIPAddr
= pFixedInfo
-> DnsServerList
.Next
;
206 _tprintf(_T("\t\t\t\t\t %s\n"), pIPAddr
->IpAddress
.String
);
207 pIPAddr
= pIPAddr
->Next
;
209 if (pAdapter
->HaveWins
)
211 _tprintf(_T("\tPrimary WINS Server . . . . . . . : %s\n"), pAdapter
->PrimaryWinsServer
.IpAddress
.String
);
212 _tprintf(_T("\tSecondard WINS Server . . . . . . : %s\n"), pAdapter
->SecondaryWinsServer
.IpAddress
.String
);
214 if (pAdapter
->DhcpEnabled
)
216 _tprintf(_T("\tLease Obtained. . . . . . . . . . : %s"), _tasctime(localtime(&pAdapter
->LeaseObtained
)));
217 _tprintf(_T("\tLease Expires . . . . . . . . . . : %s"), _tasctime(localtime(&pAdapter
->LeaseExpires
)));
222 pAdapter
= pAdapter
->Next
;
229 INT
Release(TCHAR Index
)
231 IP_ADAPTER_INDEX_MAP AdapterInfo
;
234 /* if interface is not given, query GetInterfaceInfo */
235 if (Index
== (TCHAR
)NULL
)
237 PIP_INTERFACE_INFO pInfo
;
239 pInfo
= (IP_INTERFACE_INFO
*) malloc(sizeof(IP_INTERFACE_INFO
));
242 /* Make an initial call to GetInterfaceInfo to get
243 * the necessary size into the ulOutBufLen variable */
244 if ( GetInterfaceInfo(pInfo
, &ulOutBufLen
) == ERROR_INSUFFICIENT_BUFFER
)
247 pInfo
= (IP_INTERFACE_INFO
*) malloc (ulOutBufLen
);
250 /* Make a second call to GetInterfaceInfo to get the actual data we want */
251 if ((dwRetVal
= GetInterfaceInfo(pInfo
, &ulOutBufLen
)) == NO_ERROR
)
253 AdapterInfo
= pInfo
->Adapter
[0];
254 _tprintf(_T("name - %S\n"), pInfo
->Adapter
[0].Name
);
258 _tprintf(_T("\nGetInterfaceInfo failed : "));
259 DoFormatMessage(dwRetVal
);
265 /* we need to be able to release connections by name with support for globbing
266 * i.e. ipconfig /release Eth* will release all cards starting with Eth...
267 * ipconfig /release *con* will release all cards with 'con' in their name
272 /* Call IpReleaseAddress to release the IP address on the specified adapter. */
273 if ((dwRetVal
= IpReleaseAddress(&AdapterInfo
)) != NO_ERROR
)
275 _tprintf(_T("\nAn error occured while releasing interface %s : "), _T("*name*"));
276 DoFormatMessage(dwRetVal
);
284 INT
Renew(TCHAR Index
)
286 IP_ADAPTER_INDEX_MAP AdapterInfo
;
289 /* if interface is not given, query GetInterfaceInfo */
290 if (Index
== (TCHAR
)NULL
)
292 PIP_INTERFACE_INFO pInfo
;
294 pInfo
= (IP_INTERFACE_INFO
*) malloc(sizeof(IP_INTERFACE_INFO
));
297 /* Make an initial call to GetInterfaceInfo to get
298 * the necessary size into the ulOutBufLen variable */
299 if ( GetInterfaceInfo(pInfo
, &ulOutBufLen
) == ERROR_INSUFFICIENT_BUFFER
)
302 pInfo
= (IP_INTERFACE_INFO
*) malloc (ulOutBufLen
);
305 /* Make a second call to GetInterfaceInfo to get the actual data we want */
306 if ((dwRetVal
= GetInterfaceInfo(pInfo
, &ulOutBufLen
)) == NO_ERROR
)
308 AdapterInfo
= pInfo
->Adapter
[0];
309 _tprintf(_T("name - %S\n"), pInfo
->Adapter
[0].Name
);
311 _tprintf(_T("\nGetInterfaceInfo failed : "));
312 DoFormatMessage(dwRetVal
);
318 /* we need to be able to renew connections by name with support for globbing
319 * i.e. ipconfig /renew Eth* will renew all cards starting with Eth...
320 * ipconfig /renew *con* will renew all cards with 'con' in their name
325 /* Call IpRenewAddress to renew the IP address on the specified adapter. */
326 if ((dwRetVal
= IpRenewAddress(&AdapterInfo
)) != NO_ERROR
)
328 _tprintf(_T("\nAn error occured while renew interface %s : "), _T("*name*"));
329 DoFormatMessage(dwRetVal
);
334 /* temp func for testing purposes */
337 // Declare and initialize variables
338 PIP_INTERFACE_INFO pInfo
;
342 pInfo
= (IP_INTERFACE_INFO
*) malloc( sizeof(IP_INTERFACE_INFO
) );
343 ulOutBufLen
= sizeof(IP_INTERFACE_INFO
);
347 // Make an initial call to GetInterfaceInfo to get
348 // the necessary size in the ulOutBufLen variable
349 if ( GetInterfaceInfo(pInfo
, &ulOutBufLen
) == ERROR_INSUFFICIENT_BUFFER
)
352 pInfo
= (IP_INTERFACE_INFO
*) malloc (ulOutBufLen
);
355 // Make a second call to GetInterfaceInfo to get
356 // the actual data we need
357 if ((dwRetVal
= GetInterfaceInfo(pInfo
, &ulOutBufLen
)) == NO_ERROR
)
360 for (i
=0; i
<pInfo
->NumAdapters
; i
++)
362 printf("\tAdapter Name: %S\n", pInfo
->Adapter
[i
].Name
);
363 printf("\tAdapter Index: %ld\n", pInfo
->Adapter
[i
].Index
);
364 printf("\tNum Adapters: %ld\n", pInfo
->NumAdapters
);
369 printf("GetInterfaceInfo failed.\n");
370 DoFormatMessage(dwRetVal
);
377 _tprintf(_T("\nUSAGE:\n"
378 " ipconfig [/? | /all | /renew [adapter] | /release [adapter] |\n"
379 " /flushdns | /displaydns | /registerdns |\n"
380 " /showclassid adapter |\n"
381 " /setclassid adapter [classid] ]\n"
384 " adapter Connection name\n"
385 " (wildcard characters * and ? allowed, see examples)\n"
388 " /? Display this help message\n"
389 " /all Display full configuration information.\n"
390 " /release Release the IP address for the specified adapter.\n"
391 " /renew Renew the IP address for the specified adapter.\n"
392 " /flushdns Purges the DNS Resolver cache.\n"
393 " /registerdns Refreshes all DHCP leases and re-registers DNS names.\n"
394 " /displaydns Display the contents of the DNS Resolver Cache.\n"
395 " /showclassid Displays all the dhcp class IDs allowed for adapter.\n"
396 " /setclassid Modifies the dhcp class id.\n"
398 "The default is to display only the IP address, subnet mask and\n"
399 "default gateway for each adapter bound to TCP/IP.\n"
401 "For Release and Renew, if no adapter name is specified, then the IP address\n"
402 "leases for all adapters bound to TCP/IP will be released or renewed.\n"
404 "For Setclassid, if no ClassId is specified, then the ClassId is removed.\n"
407 " > ipconfig ... Show information.\n"
408 " > ipconfig /all ... Show detailed information\n"
409 " > ipconfig /renew ... renew all adapters\n"
410 " > ipconfig /renew EL* ... renew any connection that has its\n"
411 " name starting with EL\n"
412 " > ipconfig /release *Con* ... release all matching connections,\n"
413 " eg. \"Local Area Connection 1\" or\n"
414 " \"Local Area Connection 2\"\n"));
417 int main(int argc
, char *argv
[])
421 BOOL DoRelease
=FALSE
;
423 BOOL DoFlushdns
=FALSE
;
424 BOOL DoRegisterdns
=FALSE
;
425 BOOL DoDisplaydns
=FALSE
;
426 BOOL DoShowclassid
=FALSE
;
427 BOOL DoSetclassid
=FALSE
;
429 /* Parse command line for options we have been given. */
430 if ( (argc
> 1)&&(argv
[1][0]=='/') )
432 if( !_tcsicmp( &argv
[1][1], _T("?") ))
436 else if( !_tcsnicmp( &argv
[1][1], _T("ALL"), _tcslen(&argv
[1][1]) ))
440 else if( !_tcsnicmp( &argv
[1][1], _T("RELEASE"), _tcslen(&argv
[1][1]) ))
444 else if( ! _tcsnicmp( &argv
[1][1], _T("RENEW"), _tcslen(&argv
[1][1]) ))
448 else if( ! _tcsnicmp( &argv
[1][1], _T("FLUSHDNS"), _tcslen(&argv
[1][1]) ))
452 else if( ! _tcsnicmp( &argv
[1][1], _T("FLUSHREGISTERDNS"), _tcslen(&argv
[1][1]) ))
454 DoRegisterdns
= TRUE
;
456 else if( ! _tcsnicmp( &argv
[1][1], _T("DISPLAYDNS"), _tcslen(&argv
[1][1]) ))
460 else if( ! _tcsnicmp( &argv
[1][1], _T("SHOWCLASSID"), _tcslen(&argv
[1][1]) ))
462 DoShowclassid
= TRUE
;
464 else if( ! _tcsnicmp( &argv
[1][1], _T("SETCLASSID"), _tcslen(&argv
[1][1]) ))
472 case 1: /* Default behaviour if no options are given*/
475 case 2: /* Process all the options that take no paramiters */
481 Release((TCHAR
)NULL
);
485 _tprintf(_T("\nSorry /flushdns is not implemented yet\n"));
486 else if (DoRegisterdns
)
487 _tprintf(_T("\nSorry /registerdns is not implemented yet\n"));
488 else if (DoDisplaydns
)
489 _tprintf(_T("\nSorry /displaydns is not implemented yet\n"));
493 case 3: /* Process all the options that can have 1 paramiters */
495 _tprintf(_T("\nSorry /release [adapter] is not implemented yet\n"));
498 _tprintf(_T("\nSorry /renew [adapter] is not implemented yet\n"));
499 else if (DoShowclassid
)
500 _tprintf(_T("\nSorry /showclassid adapter is not implemented yet\n"));
501 else if (DoSetclassid
)
502 _tprintf(_T("\nSorry /setclassid adapter is not implemented yet\n"));
506 case 4: /* Process all the options that can have 2 paramiters */
508 _tprintf(_T("\nSorry /setclassid adapter [classid]is not implemented yet\n"));