2 * PROJECT: ReactOS ipconfig utility
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/applications/network/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
32 int LoadStringAndOem(HINSTANCE hInst
,
41 szTmp
= (LPTSTR
)HeapAlloc(ProcessHeap
, 0, byteSize
);
46 res
= LoadString(hInst
, uID
, szTmp
, byteSize
);
47 CharToOem(szTmp
, szNode
);
48 HeapFree(ProcessHeap
, 0, szTmp
);
52 LPTSTR
GetNodeTypeName(UINT NodeType
)
54 static TCHAR szNode
[14];
59 if (!LoadStringAndOem(hInstance
, IDS_BCAST
, szNode
, sizeof(szNode
)))
64 if (!LoadStringAndOem(hInstance
, IDS_P2P
, szNode
, sizeof(szNode
)))
69 if (!LoadStringAndOem(hInstance
, IDS_MIXED
, szNode
, sizeof(szNode
)))
74 if (!LoadStringAndOem(hInstance
, IDS_HYBRID
, szNode
, sizeof(szNode
)))
79 if (!LoadStringAndOem(hInstance
, IDS_UNKNOWN
, szNode
, sizeof(szNode
)))
88 LPTSTR
GetInterfaceTypeName(UINT InterfaceType
)
90 static TCHAR szIntType
[25];
92 switch (InterfaceType
)
94 case MIB_IF_TYPE_OTHER
:
95 if (!LoadStringAndOem(hInstance
, IDS_OTHER
, szIntType
, sizeof(szIntType
)))
99 case MIB_IF_TYPE_ETHERNET
:
100 if (!LoadStringAndOem(hInstance
, IDS_ETH
, szIntType
, sizeof(szIntType
)))
104 case MIB_IF_TYPE_TOKENRING
:
105 if (!LoadStringAndOem(hInstance
, IDS_TOKEN
, szIntType
, sizeof(szIntType
)))
109 case MIB_IF_TYPE_FDDI
:
110 if (!LoadStringAndOem(hInstance
, IDS_FDDI
, szIntType
, sizeof(szIntType
)))
114 case MIB_IF_TYPE_PPP
:
115 if (!LoadStringAndOem(hInstance
, IDS_PPP
, szIntType
, sizeof(szIntType
)))
119 case MIB_IF_TYPE_LOOPBACK
:
120 if (!LoadStringAndOem(hInstance
, IDS_LOOP
, szIntType
, sizeof(szIntType
)))
124 case MIB_IF_TYPE_SLIP
:
125 if (!LoadStringAndOem(hInstance
, IDS_SLIP
, szIntType
, sizeof(szIntType
)))
130 if (!LoadStringAndOem(hInstance
, IDS_UNKNOWN
, szIntType
, sizeof(szIntType
)))
139 /* print MAC address */
140 PTCHAR
PrintMacAddr(PBYTE Mac
)
142 static TCHAR MacAddr
[20];
144 _stprintf(MacAddr
, _T("%02x-%02x-%02x-%02x-%02x-%02x"),
145 Mac
[0], Mac
[1], Mac
[2], Mac
[3], Mac
[4], Mac
[5]);
151 VOID
DoFormatMessage(LONG ErrorCode
)
157 ErrorCode
= GetLastError();
159 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
|
160 FORMAT_MESSAGE_FROM_SYSTEM
|
161 FORMAT_MESSAGE_IGNORE_INSERTS
,
164 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
), /* Default language */
169 _tprintf(_T("%s"), (LPTSTR
)lpMsgBuf
);
175 LPTSTR
GetConnectionType(LPTSTR lpClass
)
178 LPTSTR ConType
= NULL
;
179 LPTSTR ConTypeTmp
= NULL
;
181 LPTSTR PrePath
= _T("SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\");
182 LPTSTR PostPath
= _T("\\Connection");
187 /* don't overflow the buffer */
188 PathSize
= lstrlen(PrePath
) + lstrlen(lpClass
) + lstrlen(PostPath
) + 1;
192 wsprintf(Path
, _T("%s%s%s"), PrePath
, lpClass
, PostPath
);
194 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
198 &hKey
) == ERROR_SUCCESS
)
200 if(RegQueryValueEx(hKey
,
205 &dwDataSize
) == ERROR_SUCCESS
)
207 ConTypeTmp
= (LPTSTR
)HeapAlloc(ProcessHeap
,
211 if (ConTypeTmp
== NULL
)
214 ConType
= (LPTSTR
)HeapAlloc(ProcessHeap
,
220 HeapFree(ProcessHeap
, 0, ConTypeTmp
);
224 if(RegQueryValueEx(hKey
,
229 &dwDataSize
) != ERROR_SUCCESS
)
231 HeapFree(ProcessHeap
,
238 if (ConType
) CharToOem(ConTypeTmp
, ConType
);
239 HeapFree(ProcessHeap
, 0, ConTypeTmp
);
250 LPTSTR
GetConnectionDescription(LPTSTR lpClass
)
252 HKEY hBaseKey
= NULL
;
253 HKEY hClassKey
= NULL
;
254 LPTSTR lpKeyClass
= NULL
;
255 LPTSTR lpConDesc
= NULL
;
256 LPTSTR lpPath
= NULL
;
257 TCHAR szPrePath
[] = _T("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\");
262 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
266 &hBaseKey
) != ERROR_SUCCESS
)
278 if ((Status
= RegEnumKeyEx(hBaseKey
,
285 NULL
)) != ERROR_SUCCESS
)
287 if (Status
== ERROR_NO_MORE_ITEMS
)
289 DoFormatMessage(Status
);
297 PathSize
= lstrlen(szPrePath
) + lstrlen(szName
) + 1;
298 lpPath
= (LPTSTR
)HeapAlloc(ProcessHeap
,
300 PathSize
* sizeof(TCHAR
));
304 wsprintf(lpPath
, _T("%s%s"), szPrePath
, szName
);
306 //MessageBox(NULL, lpPath, NULL, 0);
308 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
312 &hClassKey
) != ERROR_SUCCESS
)
317 HeapFree(ProcessHeap
, 0, lpPath
);
320 if(RegQueryValueEx(hClassKey
,
321 _T("NetCfgInstanceId"),
325 &dwDataSize
) == ERROR_SUCCESS
)
327 lpKeyClass
= (LPTSTR
)HeapAlloc(ProcessHeap
,
330 if (lpKeyClass
== NULL
)
333 if(RegQueryValueEx(hClassKey
,
334 _T("NetCfgInstanceId"),
338 &dwDataSize
) != ERROR_SUCCESS
)
340 HeapFree(ProcessHeap
, 0, lpKeyClass
);
348 if (!lstrcmp(lpClass
, lpKeyClass
))
350 HeapFree(ProcessHeap
, 0, lpKeyClass
);
353 if(RegQueryValueEx(hClassKey
,
358 &dwDataSize
) == ERROR_SUCCESS
)
360 lpConDesc
= (LPTSTR
)HeapAlloc(ProcessHeap
,
363 if (lpConDesc
== NULL
)
366 if(RegQueryValueEx(hClassKey
,
371 &dwDataSize
) != ERROR_SUCCESS
)
373 HeapFree(ProcessHeap
, 0, lpConDesc
);
386 if (hBaseKey
!= NULL
)
387 RegCloseKey(hBaseKey
);
388 if (hClassKey
!= NULL
)
389 RegCloseKey(hClassKey
);
391 HeapFree(ProcessHeap
, 0, lpPath
);
392 if (lpKeyClass
!= NULL
)
393 HeapFree(ProcessHeap
, 0, lpKeyClass
);
399 VOID
ShowInfo(BOOL bAll
)
402 PIP_ADAPTER_INFO pAdapterInfo
= NULL
;
403 PIP_ADAPTER_INFO pAdapter
= NULL
;
404 ULONG adaptOutBufLen
= 0;
405 PFIXED_INFO pFixedInfo
= NULL
;
406 ULONG netOutBufLen
= 0;
409 /* call GetAdaptersInfo to obtain the adapter info */
410 ret
= GetAdaptersInfo(pAdapterInfo
, &adaptOutBufLen
);
411 if (ret
== ERROR_BUFFER_OVERFLOW
)
413 pAdapterInfo
= (IP_ADAPTER_INFO
*)HeapAlloc(ProcessHeap
, 0, adaptOutBufLen
);
414 if (pAdapterInfo
== NULL
)
417 ret
= GetAdaptersInfo(pAdapterInfo
, &adaptOutBufLen
);
421 HeapFree(ProcessHeap
, 0, pAdapterInfo
);
427 if( ERROR_NO_DATA
!= ret
)
434 /* call GetNetworkParams to obtain the network info */
435 if(GetNetworkParams(pFixedInfo
, &netOutBufLen
) == ERROR_BUFFER_OVERFLOW
)
437 pFixedInfo
= (FIXED_INFO
*)HeapAlloc(ProcessHeap
, 0, netOutBufLen
);
438 if (pFixedInfo
== NULL
)
441 HeapFree(ProcessHeap
, 0, pAdapterInfo
);
444 if (GetNetworkParams(pFixedInfo
, &netOutBufLen
) != NO_ERROR
)
448 HeapFree(ProcessHeap
, 0, pAdapterInfo
);
449 HeapFree(ProcessHeap
, 0, pFixedInfo
);
456 HeapFree(ProcessHeap
, 0, pAdapterInfo
);
461 pAdapter
= pAdapterInfo
;
463 _tprintf(_T("\nReactOS IP Configuration\n\n"));
466 _tprintf(_T("\tHost Name . . . . . . . . . . . . : %s\n"), pFixedInfo
->HostName
);
467 _tprintf(_T("\tPrimary DNS Suffix. . . . . . . . : \n"));
468 _tprintf(_T("\tNode Type . . . . . . . . . . . . : %s\n"), GetNodeTypeName(pFixedInfo
->NodeType
));
469 if (pFixedInfo
->EnableRouting
)
470 _tprintf(_T("\tIP Routing Enabled. . . . . . . . : Yes\n"));
472 _tprintf(_T("\tIP Routing Enabled. . . . . . . . : No\n"));
473 if (pAdapter
&& pAdapter
->HaveWins
)
474 _tprintf(_T("\tWINS Proxy enabled. . . . . . . . : Yes\n"));
476 _tprintf(_T("\tWINS Proxy enabled. . . . . . . . : No\n"));
477 _tprintf(_T("\tDNS Suffix Search List. . . . . . : %s\n"), pFixedInfo
->DomainName
);
482 LPTSTR IntType
, myConType
;
484 mibEntry
.dwIndex
= pAdapter
->Index
;
485 GetIfEntry(&mibEntry
);
487 IntType
= GetInterfaceTypeName(pAdapter
->Type
);
488 myConType
= GetConnectionType(pAdapter
->AdapterName
);
490 _tprintf(_T("\n%s %s: \n\n"), IntType
, myConType
);
492 if (myConType
!= NULL
) HeapFree(ProcessHeap
, 0, myConType
);
494 /* check if the adapter is connected to the media */
495 if (mibEntry
.dwOperStatus
!= MIB_IF_OPER_STATUS_CONNECTED
&& mibEntry
.dwOperStatus
!= MIB_IF_OPER_STATUS_OPERATIONAL
)
497 _tprintf(_T("\tMedia State . . . . . . . . . . . : Media disconnected\n"));
498 pAdapter
= pAdapter
->Next
;
502 _tprintf(_T("\tConnection-specific DNS Suffix. . : %s\n"), pFixedInfo
->DomainName
);
506 LPTSTR lpDesc
= GetConnectionDescription(pAdapter
->AdapterName
);
507 _tprintf(_T("\tDescription . . . . . . . . . . . : %s\n"), lpDesc
);
508 HeapFree(ProcessHeap
, 0, lpDesc
);
509 _tprintf(_T("\tPhysical Address. . . . . . . . . : %s\n"), PrintMacAddr(pAdapter
->Address
));
510 if (pAdapter
->DhcpEnabled
)
511 _tprintf(_T("\tDHCP Enabled. . . . . . . . . . . : Yes\n"));
513 _tprintf(_T("\tDHCP Enabled. . . . . . . . . . . : No\n"));
514 _tprintf(_T("\tAutoconfiguration Enabled . . . . : \n"));
517 _tprintf(_T("\tIP Address. . . . . . . . . . . . : %s\n"), pAdapter
->IpAddressList
.IpAddress
.String
);
518 _tprintf(_T("\tSubnet Mask . . . . . . . . . . . : %s\n"), pAdapter
->IpAddressList
.IpMask
.String
);
519 if (pAdapter
->GatewayList
.IpAddress
.String
[0] != '0')
520 _tprintf(_T("\tDefault Gateway . . . . . . . . . : %s\n"), pAdapter
->GatewayList
.IpAddress
.String
);
522 _tprintf(_T("\tDefault Gateway . . . . . . . . . :\n"));
526 PIP_ADDR_STRING pIPAddr
;
528 if (pAdapter
->DhcpEnabled
)
529 _tprintf(_T("\tDHCP Server . . . . . . . . . . . : %s\n"), pAdapter
->DhcpServer
.IpAddress
.String
);
531 _tprintf(_T("\tDNS Servers . . . . . . . . . . . : "));
532 _tprintf(_T("%s\n"), pFixedInfo
->DnsServerList
.IpAddress
.String
);
533 pIPAddr
= pFixedInfo
->DnsServerList
.Next
;
536 _tprintf(_T("\t\t\t\t\t %s\n"), pIPAddr
->IpAddress
.String
);
537 pIPAddr
= pIPAddr
->Next
;
540 if (pAdapter
->HaveWins
)
542 _tprintf(_T("\tPrimary WINS Server . . . . . . . : %s\n"), pAdapter
->PrimaryWinsServer
.IpAddress
.String
);
543 _tprintf(_T("\tSecondary WINS Server . . . . . . : %s\n"), pAdapter
->SecondaryWinsServer
.IpAddress
.String
);
546 if (pAdapter
->DhcpEnabled
)
548 _tprintf(_T("\tLease Obtained. . . . . . . . . . : %s"), _tasctime(localtime(&pAdapter
->LeaseObtained
)));
549 _tprintf(_T("\tLease Expires . . . . . . . . . . : %s"), _tasctime(localtime(&pAdapter
->LeaseExpires
)));
554 pAdapter
= pAdapter
->Next
;
558 HeapFree(ProcessHeap
, 0, pFixedInfo
);
560 HeapFree(ProcessHeap
, 0, pAdapterInfo
);
563 VOID
Release(LPTSTR Index
)
565 IP_ADAPTER_INDEX_MAP AdapterInfo
;
569 /* if interface is not given, query GetInterfaceInfo */
572 PIP_INTERFACE_INFO pInfo
= NULL
;
573 ULONG ulOutBufLen
= 0;
575 if (GetInterfaceInfo(pInfo
, &ulOutBufLen
) == ERROR_INSUFFICIENT_BUFFER
)
577 pInfo
= (IP_INTERFACE_INFO
*)HeapAlloc(ProcessHeap
, 0, ulOutBufLen
);
581 if (GetInterfaceInfo(pInfo
, &ulOutBufLen
) == NO_ERROR
)
583 for (i
= 0; i
< pInfo
->NumAdapters
; i
++)
585 CopyMemory(&AdapterInfo
, &pInfo
->Adapter
[i
], sizeof(IP_ADAPTER_INDEX_MAP
));
586 _tprintf(_T("name - %ls\n"), pInfo
->Adapter
[i
].Name
);
588 /* Call IpReleaseAddress to release the IP address on the specified adapter. */
589 if ((ret
= IpReleaseAddress(&AdapterInfo
)) != NO_ERROR
)
591 _tprintf(_T("\nAn error occured while releasing interface %ls : \n"), AdapterInfo
.Name
);
592 DoFormatMessage(ret
);
596 HeapFree(ProcessHeap
, 0, pInfo
);
601 HeapFree(ProcessHeap
, 0, pInfo
);
615 * we need to be able to release connections by name with support for globbing
616 * i.e. ipconfig /release Eth* will release all cards starting with Eth...
617 * ipconfig /release *con* will release all cards with 'con' in their name
625 VOID
Renew(LPTSTR Index
)
627 IP_ADAPTER_INDEX_MAP AdapterInfo
;
630 /* if interface is not given, query GetInterfaceInfo */
633 PIP_INTERFACE_INFO pInfo
;
634 ULONG ulOutBufLen
= 0;
636 pInfo
= (IP_INTERFACE_INFO
*)HeapAlloc(ProcessHeap
, 0, sizeof(IP_INTERFACE_INFO
));
639 _tprintf(_T("memory allocation error"));
643 /* Make an initial call to GetInterfaceInfo to get
644 * the necessary size into the ulOutBufLen variable */
645 if ( GetInterfaceInfo(pInfo
, &ulOutBufLen
) == ERROR_INSUFFICIENT_BUFFER
)
647 HeapFree(ProcessHeap
, 0, pInfo
);
648 pInfo
= (IP_INTERFACE_INFO
*)HeapAlloc(ProcessHeap
, 0, ulOutBufLen
);
651 _tprintf(_T("memory allocation error"));
656 /* Make a second call to GetInterfaceInfo to get the actual data we want */
657 if (GetInterfaceInfo(pInfo
, &ulOutBufLen
) == NO_ERROR
)
659 for (i
= 0; i
< pInfo
->NumAdapters
; i
++)
661 CopyMemory(&AdapterInfo
, &pInfo
->Adapter
[i
], sizeof(IP_ADAPTER_INDEX_MAP
));
662 _tprintf(_T("name - %ls\n"), pInfo
->Adapter
[i
].Name
);
665 /* Call IpRenewAddress to renew the IP address on the specified adapter. */
666 if (IpRenewAddress(&AdapterInfo
) != NO_ERROR
)
668 _tprintf(_T("\nAn error occured while renew interface %s : "), _T("*name*"));
675 _tprintf(_T("\nGetInterfaceInfo failed : "));
679 HeapFree(ProcessHeap
, 0, pInfo
);
685 * we need to be able to renew connections by name with support for globbing
686 * i.e. ipconfig /renew Eth* will renew all cards starting with Eth...
687 * ipconfig /renew *con* will renew all cards with 'con' in their name
700 LPTSTR lpName
= (LPTSTR
)MAKEINTRESOURCE((IDS_USAGE
>> 4) + 1);
702 hRes
= FindResource(hInstance
,
707 if ((Size
= SizeofResource(hInstance
,
710 lpUsage
= (LPTSTR
)HeapAlloc(ProcessHeap
,
716 if (LoadStringAndOem(hInstance
,
721 _tprintf(_T("%s"), lpUsage
);
724 HeapFree(ProcessHeap
, 0, lpUsage
);
731 int main(int argc
, char *argv
[])
735 BOOL DoRelease
=FALSE
;
737 BOOL DoFlushdns
=FALSE
;
738 BOOL DoRegisterdns
=FALSE
;
739 BOOL DoDisplaydns
=FALSE
;
740 BOOL DoShowclassid
=FALSE
;
741 BOOL DoSetclassid
=FALSE
;
743 hInstance
= GetModuleHandle(NULL
);
744 ProcessHeap
= GetProcessHeap();
746 /* Parse command line for options we have been given. */
747 if ( (argc
> 1)&&(argv
[1][0]=='/' || argv
[1][0]=='-') )
749 if( !_tcsicmp( &argv
[1][1], _T("?") ))
753 else if( !_tcsnicmp( &argv
[1][1], _T("ALL"), _tcslen(&argv
[1][1]) ))
757 else if( !_tcsnicmp( &argv
[1][1], _T("RELEASE"), _tcslen(&argv
[1][1]) ))
761 else if( ! _tcsnicmp( &argv
[1][1], _T("RENEW"), _tcslen(&argv
[1][1]) ))
765 else if( ! _tcsnicmp( &argv
[1][1], _T("FLUSHDNS"), _tcslen(&argv
[1][1]) ))
769 else if( ! _tcsnicmp( &argv
[1][1], _T("FLUSHREGISTERDNS"), _tcslen(&argv
[1][1]) ))
771 DoRegisterdns
= TRUE
;
773 else if( ! _tcsnicmp( &argv
[1][1], _T("DISPLAYDNS"), _tcslen(&argv
[1][1]) ))
777 else if( ! _tcsnicmp( &argv
[1][1], _T("SHOWCLASSID"), _tcslen(&argv
[1][1]) ))
779 DoShowclassid
= TRUE
;
781 else if( ! _tcsnicmp( &argv
[1][1], _T("SETCLASSID"), _tcslen(&argv
[1][1]) ))
789 case 1: /* Default behaviour if no options are given*/
792 case 2: /* Process all the options that take no parameters */
802 _tprintf(_T("\nSorry /flushdns is not implemented yet\n"));
803 else if (DoRegisterdns
)
804 _tprintf(_T("\nSorry /registerdns is not implemented yet\n"));
805 else if (DoDisplaydns
)
806 _tprintf(_T("\nSorry /displaydns is not implemented yet\n"));
810 case 3: /* Process all the options that can have 1 parameter */
812 _tprintf(_T("\nSorry /release [adapter] is not implemented yet\n"));
815 _tprintf(_T("\nSorry /renew [adapter] is not implemented yet\n"));
816 else if (DoShowclassid
)
817 _tprintf(_T("\nSorry /showclassid adapter is not implemented yet\n"));
818 else if (DoSetclassid
)
819 _tprintf(_T("\nSorry /setclassid adapter is not implemented yet\n"));
823 case 4: /* Process all the options that can have 2 parameters */
825 _tprintf(_T("\nSorry /setclassid adapter [classid]is not implemented yet\n"));