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 //LPCTSTR lpSubKey = _T("SYSTEM\\ControlSet\\Control\\Network");
150 _tprintf(_T("\nReactOS IP Configuration\n\n"));
156 _tprintf(_T("\tHost Name . . . . . . . . . . . . : %s\n"), pFixedInfo
->HostName
);
157 _tprintf(_T("\tPrimary DNS Suffix. . . . . . . . : \n"));
158 _tprintf(_T("\tNode Type . . . . . . . . . . . . : %s\n"), GetNodeTypeName(pFixedInfo
->NodeType
));
159 if (pFixedInfo
->EnableRouting
)
160 _tprintf(_T("\tIP Routing Enabled. . . . . . . . : Yes\n"));
162 _tprintf(_T("\tIP Routing Enabled. . . . . . . . : No\n"));
163 if (pAdapter
->HaveWins
)
164 _tprintf(_T("\tWINS Proxy enabled. . . . . . . . : Yes\n"));
166 _tprintf(_T("\tWINS Proxy enabled. . . . . . . . : No\n"));
167 _tprintf(_T("\tDNS Suffix Search List. . . . . . : %s\n"), pFixedInfo
->DomainName
);
170 _tprintf(_T("\n%s ...... : \n\n"), GetInterfaceTypeName(pAdapter
->Type
));
172 /* check if the adapter is connected to the media */
173 if (_tcscmp(pAdapter
->IpAddressList
.IpAddress
.String
, "0.0.0.0") == 0)
175 _tprintf(_T("\tMedia State . . . . . . . . . . . : Media disconnected\n"));
176 pAdapter
= pAdapter
->Next
;
180 _tprintf(_T("\tConnection-specific DNS Suffix. . : %s\n"), pFixedInfo
->DomainName
);
184 _tprintf(_T("\tDescription . . . . . . . . . . . : %s\n"), pAdapter
->Description
);
185 _tprintf(_T("\tPhysical Address. . . . . . . . . : %s\n"), PrintMacAddr(pAdapter
->Address
));
186 if (pAdapter
->DhcpEnabled
)
187 _tprintf(_T("\tDHCP Enabled. . . . . . . . . . . : Yes\n"));
189 _tprintf(_T("\tDHCP Enabled. . . . . . . . . . . : No\n"));
190 _tprintf(_T("\tAutoconfiguration Enabled . . . . : \n"));
193 _tprintf(_T("\tIP Address. . . . . . . . . . . . : %s\n"), pAdapter
->IpAddressList
.IpAddress
.String
);
194 _tprintf(_T("\tSubnet Mask . . . . . . . . . . . : %s\n"), pAdapter
->IpAddressList
.IpMask
.String
);
195 _tprintf(_T("\tDefault Gateway . . . . . . . . . : %s\n"), pAdapter
->GatewayList
.IpAddress
.String
);
199 if (pAdapter
->DhcpEnabled
)
200 _tprintf(_T("\tDHCP Server . . . . . . . . . . . : %s\n"), pAdapter
->DhcpServer
.IpAddress
.String
);
202 _tprintf(_T("\tDNS Servers . . . . . . . . . . . : "));
203 _tprintf(_T("%s\n"), pFixedInfo
->DnsServerList
.IpAddress
.String
);
204 pIPAddr
= pFixedInfo
-> DnsServerList
.Next
;
207 _tprintf(_T("\t\t\t\t\t %s\n"), pIPAddr
->IpAddress
.String
);
208 pIPAddr
= pIPAddr
->Next
;
210 if (pAdapter
->HaveWins
)
212 _tprintf(_T("\tPrimary WINS Server . . . . . . . : %s\n"), pAdapter
->PrimaryWinsServer
.IpAddress
.String
);
213 _tprintf(_T("\tSecondard WINS Server . . . . . . : %s\n"), pAdapter
->SecondaryWinsServer
.IpAddress
.String
);
215 if (pAdapter
->DhcpEnabled
)
217 _tprintf(_T("\tLease Obtained. . . . . . . . . . : %s"), _tasctime(localtime(&pAdapter
->LeaseObtained
)));
218 _tprintf(_T("\tLease Expires . . . . . . . . . . : %s"), _tasctime(localtime(&pAdapter
->LeaseExpires
)));
223 pAdapter
= pAdapter
->Next
;
230 INT
Release(TCHAR Index
)
232 IP_ADAPTER_INDEX_MAP AdapterInfo
;
235 /* if interface is not given, query GetInterfaceInfo */
236 if (Index
== (TCHAR
)NULL
)
238 PIP_INTERFACE_INFO pInfo
;
239 pInfo
= (IP_INTERFACE_INFO
*) malloc(sizeof(IP_INTERFACE_INFO
));
240 ULONG ulOutBufLen
= 0;
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
;
293 pInfo
= (IP_INTERFACE_INFO
*) malloc(sizeof(IP_INTERFACE_INFO
));
294 ULONG ulOutBufLen
= 0;
296 /* Make an initial call to GetInterfaceInfo to get
297 * the necessary size into the ulOutBufLen variable */
298 if ( GetInterfaceInfo(pInfo
, &ulOutBufLen
) == ERROR_INSUFFICIENT_BUFFER
)
301 pInfo
= (IP_INTERFACE_INFO
*) malloc (ulOutBufLen
);
304 /* Make a second call to GetInterfaceInfo to get the actual data we want */
305 if ((dwRetVal
= GetInterfaceInfo(pInfo
, &ulOutBufLen
)) == NO_ERROR
)
307 AdapterInfo
= pInfo
->Adapter
[0];
308 _tprintf(_T("name - %S\n"), pInfo
->Adapter
[0].Name
);
310 _tprintf(_T("\nGetInterfaceInfo failed : "));
311 DoFormatMessage(dwRetVal
);
317 /* we need to be able to renew connections by name with support for globbing
318 * i.e. ipconfig /renew Eth* will renew all cards starting with Eth...
319 * ipconfig /renew *con* will renew all cards with 'con' in their name
324 /* Call IpRenewAddress to renew the IP address on the specified adapter. */
325 if ((dwRetVal
= IpRenewAddress(&AdapterInfo
)) != NO_ERROR
)
327 _tprintf(_T("\nAn error occured while renew interface %s : "), _T("*name*"));
328 DoFormatMessage(dwRetVal
);
333 /* temp func for testing purposes */
336 // Declare and initialize variables
337 PIP_INTERFACE_INFO pInfo
;
338 pInfo
= (IP_INTERFACE_INFO
*) malloc( sizeof(IP_INTERFACE_INFO
) );
339 ULONG ulOutBufLen
= sizeof(IP_INTERFACE_INFO
);
343 // Make an initial call to GetInterfaceInfo to get
344 // the necessary size in the ulOutBufLen variable
345 if ( GetInterfaceInfo(pInfo
, &ulOutBufLen
) == ERROR_INSUFFICIENT_BUFFER
)
348 pInfo
= (IP_INTERFACE_INFO
*) malloc (ulOutBufLen
);
351 // Make a second call to GetInterfaceInfo to get
352 // the actual data we need
353 if ((dwRetVal
= GetInterfaceInfo(pInfo
, &ulOutBufLen
)) == NO_ERROR
)
356 for (i
=0; i
<pInfo
->NumAdapters
; i
++)
358 printf("\tAdapter Name: %S\n", pInfo
->Adapter
[i
].Name
);
359 printf("\tAdapter Index: %ld\n", pInfo
->Adapter
[i
].Index
);
360 printf("\tNum Adapters: %ld\n", pInfo
->NumAdapters
);
365 printf("GetInterfaceInfo failed.\n");
366 DoFormatMessage(dwRetVal
);
373 _tprintf(_T("\nUSAGE:\n"
374 " ipconfig [/? | /all | /renew [adapter] | /release [adapter] |\n"
375 " /flushdns | /displaydns | /registerdns |\n"
376 " /showclassid adapter |\n"
377 " /setclassid adapter [classid] ]\n"
380 " adapter Connection name\n"
381 " (wildcard characters * and ? allowed, see examples)\n"
384 " /? Display this help message\n"
385 " /all Display full configuration information.\n"
386 " /release Release the IP address for the specified adapter.\n"
387 " /renew Renew the IP address for the specified adapter.\n"
388 " /flushdns Purges the DNS Resolver cache.\n"
389 " /registerdns Refreshes all DHCP leases and re-registers DNS names.\n"
390 " /displaydns Display the contents of the DNS Resolver Cache.\n"
391 " /showclassid Displays all the dhcp class IDs allowed for adapter.\n"
392 " /setclassid Modifies the dhcp class id.\n"
394 "The default is to display only the IP address, subnet mask and\n"
395 "default gateway for each adapter bound to TCP/IP.\n"
397 "For Release and Renew, if no adapter name is specified, then the IP address\n"
398 "leases for all adapters bound to TCP/IP will be released or renewed.\n"
400 "For Setclassid, if no ClassId is specified, then the ClassId is removed.\n"
403 " > ipconfig ... Show information.\n"
404 " > ipconfig /all ... Show detailed information\n"
405 " > ipconfig /renew ... renew all adapters\n"
406 " > ipconfig /renew EL* ... renew any connection that has its\n"
407 " name starting with EL\n"
408 " > ipconfig /release *Con* ... release all matching connections,\n"
409 " eg. \"Local Area Connection 1\" or\n"
410 " \"Local Area Connection 2\"\n"));
413 int main(int argc
, char *argv
[])
417 BOOL DoRelease
=FALSE
;
419 BOOL DoFlushdns
=FALSE
;
420 BOOL DoRegisterdns
=FALSE
;
421 BOOL DoDisplaydns
=FALSE
;
422 BOOL DoShowclassid
=FALSE
;
423 BOOL DoSetclassid
=FALSE
;
425 /* Parse command line for options we have been given. */
426 if ( (argc
> 1)&&(argv
[1][0]=='/') )
428 if( !_tcsicmp( &argv
[1][1], _T("?") ))
432 else if( !_tcsnicmp( &argv
[1][1], _T("ALL"), _tcslen(&argv
[1][1]) ))
436 else if( !_tcsnicmp( &argv
[1][1], _T("RELEASE"), _tcslen(&argv
[1][1]) ))
440 else if( ! _tcsnicmp( &argv
[1][1], _T("RENEW"), _tcslen(&argv
[1][1]) ))
444 else if( ! _tcsnicmp( &argv
[1][1], _T("FLUSHDNS"), _tcslen(&argv
[1][1]) ))
448 else if( ! _tcsnicmp( &argv
[1][1], _T("FLUSHREGISTERDNS"), _tcslen(&argv
[1][1]) ))
450 DoRegisterdns
= TRUE
;
452 else if( ! _tcsnicmp( &argv
[1][1], _T("DISPLAYDNS"), _tcslen(&argv
[1][1]) ))
456 else if( ! _tcsnicmp( &argv
[1][1], _T("SHOWCLASSID"), _tcslen(&argv
[1][1]) ))
458 DoShowclassid
= TRUE
;
460 else if( ! _tcsnicmp( &argv
[1][1], _T("SETCLASSID"), _tcslen(&argv
[1][1]) ))
468 case 1: /* Default behaviour if no options are given*/
471 case 2: /* Process all the options that take no paramiters */
477 Release((TCHAR
)NULL
);
481 _tprintf(_T("\nSorry /flushdns is not implemented yet\n"));
482 else if (DoRegisterdns
)
483 _tprintf(_T("\nSorry /registerdns is not implemented yet\n"));
484 else if (DoDisplaydns
)
485 _tprintf(_T("\nSorry /displaydns is not implemented yet\n"));
489 case 3: /* Process all the options that can have 1 paramiters */
491 _tprintf(_T("\nSorry /release [adapter] is not implemented yet\n"));
494 _tprintf(_T("\nSorry /renew [adapter] is not implemented yet\n"));
495 else if (DoShowclassid
)
496 _tprintf(_T("\nSorry /showclassid adapter is not implemented yet\n"));
497 else if (DoSetclassid
)
498 _tprintf(_T("\nSorry /setclassid adapter is not implemented yet\n"));
502 case 4: /* Process all the options that can have 2 paramiters */
504 _tprintf(_T("\nSorry /setclassid adapter [classid]is not implemented yet\n"));