2 * PROJECT: ReactOS ipconfig utility
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: apps/utils/net/ipconfig/ipconfig.c
5 * PURPOSE: Display IP info for net adapters
6 * PROGRAMMERS: Copyright 2005 - 2006 Ged Murphy (gedmurphy@gmail.com)
11 * implement flushdns, registerdns, displaydns, showclassid, setclassid
12 * allow globbing on adapter names
15 #define WIN32_LEAN_AND_MEAN
29 LPTSTR
GetNodeTypeName(UINT NodeType
)
31 static TCHAR szNode
[14];
36 if (!LoadString(hInstance
, IDS_BCAST
, szNode
, sizeof(szNode
)))
41 if (!LoadString(hInstance
, IDS_P2P
, szNode
, sizeof(szNode
)))
46 if (!LoadString(hInstance
, IDS_MIXED
, szNode
, sizeof(szNode
)))
51 if (!LoadString(hInstance
, IDS_HYBRID
, szNode
, sizeof(szNode
)))
56 if (!LoadString(hInstance
, IDS_UNKNOWN
, szNode
, sizeof(szNode
)))
65 LPTSTR
GetInterfaceTypeName(UINT InterfaceType
)
67 static TCHAR szIntType
[25];
69 switch (InterfaceType
)
71 case MIB_IF_TYPE_OTHER
:
72 if (!LoadString(hInstance
, IDS_OTHER
, szIntType
, sizeof(szIntType
)))
76 case MIB_IF_TYPE_ETHERNET
:
77 if (!LoadString(hInstance
, IDS_ETH
, szIntType
, sizeof(szIntType
)))
81 case MIB_IF_TYPE_TOKENRING
:
82 if (!LoadString(hInstance
, IDS_TOKEN
, szIntType
, sizeof(szIntType
)))
86 case MIB_IF_TYPE_FDDI
:
87 if (!LoadString(hInstance
, IDS_FDDI
, szIntType
, sizeof(szIntType
)))
92 if (!LoadString(hInstance
, IDS_PPP
, szIntType
, sizeof(szIntType
)))
96 case MIB_IF_TYPE_LOOPBACK
:
97 if (!LoadString(hInstance
, IDS_LOOP
, szIntType
, sizeof(szIntType
)))
101 case MIB_IF_TYPE_SLIP
:
102 if (!LoadString(hInstance
, IDS_SLIP
, szIntType
, sizeof(szIntType
)))
107 if (!LoadString(hInstance
, IDS_UNKNOWN
, szIntType
, sizeof(szIntType
)))
116 /* print MAC address */
117 PTCHAR
PrintMacAddr(PBYTE Mac
)
119 static TCHAR MacAddr
[20];
121 _stprintf(MacAddr
, _T("%02x-%02x-%02x-%02x-%02x-%02x"),
122 Mac
[0], Mac
[1], Mac
[2], Mac
[3], Mac
[4], Mac
[5]);
128 VOID
DoFormatMessage(LONG ErrorCode
)
134 ErrorCode
= GetLastError();
136 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
|
137 FORMAT_MESSAGE_FROM_SYSTEM
|
138 FORMAT_MESSAGE_IGNORE_INSERTS
,
141 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
), /* Default language */
146 _tprintf(_T("%s"), (LPTSTR
)lpMsgBuf
);
152 LPTSTR
GetConnectionType(LPTSTR lpClass
)
155 LPTSTR ConType
= NULL
;
157 LPTSTR PrePath
= _T("SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\");
158 LPTSTR PostPath
= _T("\\Connection");
163 /* don't overflow the buffer */
164 PathSize
= lstrlen(PrePath
) + lstrlen(lpClass
) + lstrlen(PostPath
) + 1;
168 wsprintf(Path
, _T("%s%s%s"), PrePath
, lpClass
, PostPath
);
170 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
174 &hKey
) == ERROR_SUCCESS
)
176 if(RegQueryValueEx(hKey
,
181 &dwDataSize
) == ERROR_SUCCESS
)
183 ConType
= (LPTSTR
)HeapAlloc(ProcessHeap
,
189 if(RegQueryValueEx(hKey
,
194 &dwDataSize
) != ERROR_SUCCESS
)
208 LPTSTR
GetConnectionDescription(LPTSTR lpClass
)
210 HKEY hBaseKey
= NULL
;
211 HKEY hClassKey
= NULL
;
212 LPTSTR lpKeyClass
= NULL
;
213 LPTSTR lpConDesc
= NULL
;
214 LPTSTR lpPath
= NULL
;
215 TCHAR szPrePath
[] = _T("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\");
220 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
224 &hBaseKey
) != ERROR_SUCCESS
)
236 if ((Status
= RegEnumKeyEx(hBaseKey
,
243 NULL
)) != ERROR_SUCCESS
)
245 if (Status
== ERROR_NO_MORE_ITEMS
)
247 DoFormatMessage(Status
);
255 PathSize
= lstrlen(szPrePath
) + lstrlen(szName
) + 1;
256 lpPath
= (LPTSTR
)HeapAlloc(ProcessHeap
,
258 PathSize
* sizeof(TCHAR
));
262 wsprintf(lpPath
, _T("%s%s"), szPrePath
, szName
);
264 //MessageBox(NULL, lpPath, NULL, 0);
266 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
270 &hClassKey
) != ERROR_SUCCESS
)
275 HeapFree(ProcessHeap
, 0, lpPath
);
278 if(RegQueryValueEx(hClassKey
,
279 _T("NetCfgInstanceId"),
283 &dwDataSize
) == ERROR_SUCCESS
)
285 lpKeyClass
= (LPTSTR
)HeapAlloc(ProcessHeap
,
288 if (lpKeyClass
== NULL
)
291 if(RegQueryValueEx(hClassKey
,
292 _T("NetCfgInstanceId"),
296 &dwDataSize
) != ERROR_SUCCESS
)
299 HeapFree(ProcessHeap
, 0, lpKeyClass
);
306 if (!lstrcmp(lpClass
, lpKeyClass
))
308 HeapFree(ProcessHeap
, 0, lpKeyClass
);
311 if(RegQueryValueEx(hClassKey
,
316 &dwDataSize
) == ERROR_SUCCESS
)
318 lpConDesc
= (LPTSTR
)HeapAlloc(ProcessHeap
,
321 if (lpConDesc
== NULL
)
324 if(RegQueryValueEx(hClassKey
,
329 &dwDataSize
) != ERROR_SUCCESS
)
343 if (hBaseKey
!= NULL
)
344 RegCloseKey(hBaseKey
);
345 if (hClassKey
!= NULL
)
346 RegCloseKey(hClassKey
);
347 if (lpConDesc
!= NULL
)
348 HeapFree(ProcessHeap
, 0, lpPath
);
349 if (lpConDesc
!= NULL
)
350 HeapFree(ProcessHeap
, 0, lpKeyClass
);
356 VOID
ShowInfo(BOOL bAll
)
358 PIP_ADAPTER_INFO pAdapterInfo
= NULL
;
359 PIP_ADAPTER_INFO pAdapter
= NULL
;
360 ULONG adaptOutBufLen
= 0;
361 PFIXED_INFO pFixedInfo
= NULL
;
362 ULONG netOutBufLen
= 0;
365 /* call GetAdaptersInfo to obtain the adapter info */
366 ret
= GetAdaptersInfo(pAdapterInfo
, &adaptOutBufLen
);
367 if (ret
== ERROR_BUFFER_OVERFLOW
)
369 pAdapterInfo
= (IP_ADAPTER_INFO
*)HeapAlloc(ProcessHeap
, 0, adaptOutBufLen
);
370 if (pAdapterInfo
== NULL
)
373 ret
= GetAdaptersInfo(pAdapterInfo
, &adaptOutBufLen
);
377 HeapFree(ProcessHeap
, 0, pAdapterInfo
);
383 if( ERROR_NO_DATA
!= ret
)
390 /* call GetNetworkParams to obtain the network info */
391 if(GetNetworkParams(pFixedInfo
, &netOutBufLen
) == ERROR_BUFFER_OVERFLOW
)
393 pFixedInfo
= (FIXED_INFO
*)HeapAlloc(ProcessHeap
, 0, netOutBufLen
);
394 if (pFixedInfo
== NULL
)
397 HeapFree(ProcessHeap
, 0, pAdapterInfo
);
400 if (GetNetworkParams(pFixedInfo
, &netOutBufLen
) != NO_ERROR
)
404 HeapFree(ProcessHeap
, 0, pAdapterInfo
);
405 HeapFree(ProcessHeap
, 0, pFixedInfo
);
412 HeapFree(ProcessHeap
, 0, pAdapterInfo
);
417 pAdapter
= pAdapterInfo
;
419 _tprintf(_T("\nReactOS IP Configuration\n\n"));
422 _tprintf(_T("\tHost Name . . . . . . . . . . . . : %s\n"), pFixedInfo
->HostName
);
423 _tprintf(_T("\tPrimary DNS Suffix. . . . . . . . : \n"));
424 _tprintf(_T("\tNode Type . . . . . . . . . . . . : %s\n"), GetNodeTypeName(pFixedInfo
->NodeType
));
425 if (pFixedInfo
->EnableRouting
)
426 _tprintf(_T("\tIP Routing Enabled. . . . . . . . : Yes\n"));
428 _tprintf(_T("\tIP Routing Enabled. . . . . . . . : No\n"));
429 if (pAdapter
&& pAdapter
->HaveWins
)
430 _tprintf(_T("\tWINS Proxy enabled. . . . . . . . : Yes\n"));
432 _tprintf(_T("\tWINS Proxy enabled. . . . . . . . : No\n"));
433 _tprintf(_T("\tDNS Suffix Search List. . . . . . : %s\n"), pFixedInfo
->DomainName
);
438 LPTSTR IntType
, myConType
;
440 IntType
= GetInterfaceTypeName(pAdapter
->Type
);
441 myConType
= GetConnectionType(pAdapter
->AdapterName
);
443 _tprintf(_T("\n%s %s: \n\n"), IntType
, myConType
);
445 if (myConType
!= NULL
) HeapFree(ProcessHeap
, 0, myConType
);
447 /* check if the adapter is connected to the media */
448 if (_tcscmp(pAdapter
->IpAddressList
.IpAddress
.String
, "0.0.0.0") == 0)
450 _tprintf(_T("\tMedia State . . . . . . . . . . . : Media disconnected\n"));
451 pAdapter
= pAdapter
->Next
;
455 _tprintf(_T("\tConnection-specific DNS Suffix. . : %s\n"), pFixedInfo
->DomainName
);
459 _tprintf(_T("\tDescription . . . . . . . . . . . : %s\n"), GetConnectionDescription(pAdapter
->AdapterName
));
460 _tprintf(_T("\tPhysical Address. . . . . . . . . : %s\n"), PrintMacAddr(pAdapter
->Address
));
461 if (pAdapter
->DhcpEnabled
)
462 _tprintf(_T("\tDHCP Enabled. . . . . . . . . . . : Yes\n"));
464 _tprintf(_T("\tDHCP Enabled. . . . . . . . . . . : No\n"));
465 _tprintf(_T("\tAutoconfiguration Enabled . . . . : \n"));
468 _tprintf(_T("\tIP Address. . . . . . . . . . . . : %s\n"), pAdapter
->IpAddressList
.IpAddress
.String
);
469 _tprintf(_T("\tSubnet Mask . . . . . . . . . . . : %s\n"), pAdapter
->IpAddressList
.IpMask
.String
);
470 if (pAdapter
->GatewayList
.IpAddress
.String
[0] != '0')
471 _tprintf(_T("\tDefault Gateway . . . . . . . . . : %s\n"), pAdapter
->GatewayList
.IpAddress
.String
);
473 _tprintf(_T("\tDefault Gateway . . . . . . . . . :\n"));
477 PIP_ADDR_STRING pIPAddr
;
479 if (pAdapter
->DhcpEnabled
)
480 _tprintf(_T("\tDHCP Server . . . . . . . . . . . : %s\n"), pAdapter
->DhcpServer
.IpAddress
.String
);
482 _tprintf(_T("\tDNS Servers . . . . . . . . . . . : "));
483 _tprintf(_T("%s\n"), pFixedInfo
->DnsServerList
.IpAddress
.String
);
484 pIPAddr
= pFixedInfo
->DnsServerList
.Next
;
487 _tprintf(_T("\t\t\t\t\t %s\n"), pIPAddr
->IpAddress
.String
);
488 pIPAddr
= pIPAddr
->Next
;
491 if (pAdapter
->HaveWins
)
493 _tprintf(_T("\tPrimary WINS Server . . . . . . . : %s\n"), pAdapter
->PrimaryWinsServer
.IpAddress
.String
);
494 _tprintf(_T("\tSecondard WINS Server . . . . . . : %s\n"), pAdapter
->SecondaryWinsServer
.IpAddress
.String
);
497 if (pAdapter
->DhcpEnabled
)
499 _tprintf(_T("\tLease Obtained. . . . . . . . . . : %s"), _tasctime(localtime(&pAdapter
->LeaseObtained
)));
500 _tprintf(_T("\tLease Expires . . . . . . . . . . : %s"), _tasctime(localtime(&pAdapter
->LeaseExpires
)));
505 pAdapter
= pAdapter
->Next
;
509 HeapFree(ProcessHeap
, 0, pFixedInfo
);
511 HeapFree(ProcessHeap
, 0, pAdapterInfo
);
514 VOID
Release(LPTSTR Index
)
516 IP_ADAPTER_INDEX_MAP AdapterInfo
;
520 /* if interface is not given, query GetInterfaceInfo */
523 PIP_INTERFACE_INFO pInfo
= NULL
;
524 ULONG ulOutBufLen
= 0;
526 if (GetInterfaceInfo(pInfo
, &ulOutBufLen
) == ERROR_INSUFFICIENT_BUFFER
)
528 pInfo
= (IP_INTERFACE_INFO
*)HeapAlloc(ProcessHeap
, 0, ulOutBufLen
);
532 if (GetInterfaceInfo(pInfo
, &ulOutBufLen
) == NO_ERROR
)
534 for (i
= 0; i
< pInfo
->NumAdapters
; i
++)
536 CopyMemory(&AdapterInfo
, &pInfo
->Adapter
[i
], sizeof(IP_ADAPTER_INDEX_MAP
));
537 _tprintf(_T("name - %S\n"), pInfo
->Adapter
[i
].Name
);
539 /* Call IpReleaseAddress to release the IP address on the specified adapter. */
540 if ((ret
= IpReleaseAddress(&AdapterInfo
)) != NO_ERROR
)
542 _tprintf(_T("\nAn error occured while releasing interface %S : \n"), AdapterInfo
.Name
);
543 DoFormatMessage(ret
);
547 HeapFree(ProcessHeap
, 0, pInfo
);
552 HeapFree(ProcessHeap
, 0, pInfo
);
566 * we need to be able to release connections by name with support for globbing
567 * i.e. ipconfig /release Eth* will release all cards starting with Eth...
568 * ipconfig /release *con* will release all cards with 'con' in their name
576 VOID
Renew(LPTSTR Index
)
578 IP_ADAPTER_INDEX_MAP AdapterInfo
;
581 /* if interface is not given, query GetInterfaceInfo */
584 PIP_INTERFACE_INFO pInfo
;
585 ULONG ulOutBufLen
= 0;
587 pInfo
= (IP_INTERFACE_INFO
*)HeapAlloc(ProcessHeap
, 0, sizeof(IP_INTERFACE_INFO
));
590 _tprintf(_T("memory allocation error"));
594 /* Make an initial call to GetInterfaceInfo to get
595 * the necessary size into the ulOutBufLen variable */
596 if ( GetInterfaceInfo(pInfo
, &ulOutBufLen
) == ERROR_INSUFFICIENT_BUFFER
)
598 HeapFree(ProcessHeap
, 0, pInfo
);
599 pInfo
= (IP_INTERFACE_INFO
*)HeapAlloc(ProcessHeap
, 0, ulOutBufLen
);
602 _tprintf(_T("memory allocation error"));
607 /* Make a second call to GetInterfaceInfo to get the actual data we want */
608 if (GetInterfaceInfo(pInfo
, &ulOutBufLen
) == NO_ERROR
)
610 for (i
= 0; i
< pInfo
->NumAdapters
; i
++)
612 CopyMemory(&AdapterInfo
, &pInfo
->Adapter
[i
], sizeof(IP_ADAPTER_INDEX_MAP
));
613 _tprintf(_T("name - %S\n"), pInfo
->Adapter
[i
].Name
);
616 /* Call IpRenewAddress to renew the IP address on the specified adapter. */
617 if (IpRenewAddress(&AdapterInfo
) != NO_ERROR
)
619 _tprintf(_T("\nAn error occured while renew interface %s : "), _T("*name*"));
626 _tprintf(_T("\nGetInterfaceInfo failed : "));
630 HeapFree(ProcessHeap
, 0, pInfo
);
636 * we need to be able to renew connections by name with support for globbing
637 * i.e. ipconfig /renew Eth* will renew all cards starting with Eth...
638 * ipconfig /renew *con* will renew all cards with 'con' in their name
651 LPTSTR lpName
= (LPTSTR
)MAKEINTRESOURCE((IDS_USAGE
>> 4) + 1);
653 hRes
= FindResource(hInstance
,
658 if ((Size
= SizeofResource(hInstance
,
661 lpUsage
= (LPTSTR
)HeapAlloc(ProcessHeap
,
667 if (LoadString(hInstance
,
672 _tprintf(_T("%s"), lpUsage
);
680 int main(int argc
, char *argv
[])
684 BOOL DoRelease
=FALSE
;
686 BOOL DoFlushdns
=FALSE
;
687 BOOL DoRegisterdns
=FALSE
;
688 BOOL DoDisplaydns
=FALSE
;
689 BOOL DoShowclassid
=FALSE
;
690 BOOL DoSetclassid
=FALSE
;
692 hInstance
= GetModuleHandle(NULL
);
693 ProcessHeap
= GetProcessHeap();
695 /* Parse command line for options we have been given. */
696 if ( (argc
> 1)&&(argv
[1][0]=='/' || argv
[1][0]=='-') )
698 if( !_tcsicmp( &argv
[1][1], _T("?") ))
702 else if( !_tcsnicmp( &argv
[1][1], _T("ALL"), _tcslen(&argv
[1][1]) ))
706 else if( !_tcsnicmp( &argv
[1][1], _T("RELEASE"), _tcslen(&argv
[1][1]) ))
710 else if( ! _tcsnicmp( &argv
[1][1], _T("RENEW"), _tcslen(&argv
[1][1]) ))
714 else if( ! _tcsnicmp( &argv
[1][1], _T("FLUSHDNS"), _tcslen(&argv
[1][1]) ))
718 else if( ! _tcsnicmp( &argv
[1][1], _T("FLUSHREGISTERDNS"), _tcslen(&argv
[1][1]) ))
720 DoRegisterdns
= TRUE
;
722 else if( ! _tcsnicmp( &argv
[1][1], _T("DISPLAYDNS"), _tcslen(&argv
[1][1]) ))
726 else if( ! _tcsnicmp( &argv
[1][1], _T("SHOWCLASSID"), _tcslen(&argv
[1][1]) ))
728 DoShowclassid
= TRUE
;
730 else if( ! _tcsnicmp( &argv
[1][1], _T("SETCLASSID"), _tcslen(&argv
[1][1]) ))
738 case 1: /* Default behaviour if no options are given*/
741 case 2: /* Process all the options that take no parameters */
751 _tprintf(_T("\nSorry /flushdns is not implemented yet\n"));
752 else if (DoRegisterdns
)
753 _tprintf(_T("\nSorry /registerdns is not implemented yet\n"));
754 else if (DoDisplaydns
)
755 _tprintf(_T("\nSorry /displaydns is not implemented yet\n"));
759 case 3: /* Process all the options that can have 1 parameter */
761 _tprintf(_T("\nSorry /release [adapter] is not implemented yet\n"));
764 _tprintf(_T("\nSorry /renew [adapter] is not implemented yet\n"));
765 else if (DoShowclassid
)
766 _tprintf(_T("\nSorry /showclassid adapter is not implemented yet\n"));
767 else if (DoSetclassid
)
768 _tprintf(_T("\nSorry /setclassid adapter is not implemented yet\n"));
772 case 4: /* Process all the options that can have 2 parameters */
774 _tprintf(_T("\nSorry /setclassid adapter [classid]is not implemented yet\n"));