Translate

Image of Android Wireless Application Development
Image of Advanced Programming in the UNIX Environment, Second Edition (Addison-Wesley Professional Computing Series)
Image of Beginning Google Maps API 3
Image of Linux Kernel Development (3rd Edition)

Vista VMware Network Connections

When I am traveling, I often use VMware workstation on my Windows Vista Ultimate laptop to host both Redhat and Ubuntu VMs. One thing that irritates me about this arrangement is that whenever I reconfigure networking in VMware, Windows Vista shows these networking interfaces are part of a unidentified network with limited access.

For example, when you right click on the networking icon, the following networks are displayed. Network is my regular wireless or hard-wired LAN connection to my router and from there to the Internet. The unidentified network, marked limited connectivity, are two VMware virtual network adapters.

Vista VMware image 2

Here is more detailed information about the network connections from the Windows Vista Control Panel Network and Sharing Center. It shows what is purported to be an unidentified public network with two local area connections and limited connectivity.

Vista VMware image 1

I know that these local area connections are not really part of my public network so obviously the displayed information is wrong but why? These two local area connections are strictly related to VMware. When you install VMware Workstation, it creates two or more virtual network adapters (AKA local area connections) which are simply virtual (AKA dummy) adapters for VMware’s host bridging, which in turn allows the virtual machine to access my laptop’s network. The same scenario also occurs if you install a Loopback adapter.

My preference is for these virtual network adapters not to be displayed when I check my networking status. Moreover, when I am not connected to an external network, I do not want the public profile of Windows Firewall to be triggered as occurs if these virtual network adapters are marked public. So I set out to figure out how to make such local area connections not be displayed by Windows Vista.

It turns out that the they are displayed by default because Windows Vista automatically identifies and monitors the networks to which a computer is connected to. The relevant information is buried deep within the MSDN documentation.

Vista automatically identifies and monitors the networks to which a computer connects. If the NDIS_DEVICE_TYPE_ENDPOINT flag is set, the device is an endpoint device and is not a connection to a true external network. Consequently, Windows ignores the endpoint device when Windows identifies networks. The Network Awareness APIs indicate that the device does not connect the computer to a network. For end users in this situation, the Network and Sharing Center and the network icon in the notification area do not show the NDIS endpoint device as connected. However, the connection is shown in the Network Connections Folder. Also, if NDIS_DEVICE_TYPE_ENDPOINT is set, the Windows Firewall ignores the connection when Windows Firewall enforces public, private, or domain policies.

According to the same MSDN article, in NDIS v6.0 (which Windows Vista uses) setting an endpoint’s NDISDeviceType registry key to 1 declares a device to be an Endpoint Mapper and Endpoint Mappers are ignored when Windows Vista does network identification.

*NdisDeviceType

The type of the device. The default value is zero, which indicates a standard networking device that connects to a network. Set *NdisDeviceType to NDIS_DEVICE_TYPE_ENDPOINT (1) if this device is an endpoint device and is not a true network interface that connects to a network. For example, you must specify NDIS_DEVICE_TYPE_ENDPOINT for devices such as smart phones that use a networking infrastructure to communicate to the local computer system but do not provide connectivity to an external network.

So what is NDIS and an NDIS_DEVICE_TYPE_ENDPOINT?  In 1989, 3Com and Microsoft jointly developed the first version of the Network Driver Interface Specification (NDIS.) This specification provides a standard interface for (a) protocol drivers to communicate with network adapters in a device-independent manner and (b) upper-level network transports such as Transport Driver Interface (TDI.) to communicate with protocol drivers. NDIS_DEVICE_TYPE_ENDPOINT is a constant defined have a value of 1 in the DDK header ntddndis.h

Adapter drivers that conform to the specification are called NDIS drivers or NDIS miniport drivers. NDIS has undegone a number of revisions over the years. The version that comes with Windows XP is NDIS 5.1 whereas NDIS 6.0 is included in Windows Vista. The current version of NDIS is 6.2 and this is what shipped with Windows 7 and Windows server 2008.

If you wish to manually configure the relevant network adapters, here is the sequence of steps:

  1. Invoke regedit
  2. Locate the key HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}
  3. Underneath this key you should see several keys labeled 0000, 0001, 0002, etc. Look through these keys to find the VMware adapters. These keys will be named …\DosDevices\VMNet* where * is a number.
  4. For each of the VWware adapters you find, add a new DWORD key named “*NdisDeviceType” and set it’s value to 1 (notice * at the beginning of the name of the key. It is required.)
  5. Exit regedit
  6. Disable and enable each of the VMware-related network adapters or simple reboot.

As always, it is useful to write a shell script to do all the work for us. Then, once we have the shell script debugged and tested, we do not have to remember the nitty-gritty details but simply remember where the script is. We will use Windows PowerShell for this purpose. Windows PowerShell is an interesting tool which I have written about before in my blog. It has most of the charactistics of a traditional Unix or GNU/Linux shell such as sh or ksh but in addition can do things like access .Net components and graphical screens. It can also access registry hives by simply changing directory into the appropriate section of the hive. For example, here is how to access the section of the registry hive which contains network adapters from within Windows PowerShell:

PS> pushd 'hklm:\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}'
PS HKLM:\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}>


Here is a one-liner which uses a filter to list only the network adapters whose name key-value pair contains the string vmware:

PS HKLM:\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}> Get-WmiObject win32_networkadapter | ? {$_.name -like "*vmware*" }

ServiceName      : VMnetAdapter
MACAddress       : 00:50:56:C0:00:01
AdapterType      : Ethernet 802.3
DeviceID         : 7
Name             : VMware Virtual Ethernet Adapter for VMnet1
NetworkAddresses :
Speed            : 100000000

ServiceName      : VMnetAdapter
MACAddress       : 00:50:56:C0:00:08
AdapterType      : Ethernet 802.3
DeviceID         : 10
Name             : VMware Virtual Ethernet Adapter for VMnet8
NetworkAddresses :
Speed            : 100000000


Here is a simple Windows PowerShell script which adds the NdisDeviceType key and sets its value to 1 for each VMware adapter it locates. It has to be run in an elevated shell in Windows Vista or as an administrator in Windows XP. It is based on the Windows Powershell script published by MVP Oisin Grehan. I tested it out using Windows PowerShell v2.0 but it should run under Windows PowerShell v1 without a problem.

#  
#  Usage: hide-vmware-adapters [reset]
#
#            The reset option can be used to unhide the adapters
#

$identity  = [Security.Principal.WindowsIdentity]::GetCurrent()  
$principal = new-object Security.Principal.WindowsPrincipal $identity 
$elevated  = $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)  
$changed   = $false
 
if (-not $elevated) {  
   $error = "Sorry, you need to run this script"
   if ([System.Environment]::OSVersion.Version.Major -gt 5) { 
      $error += " in an elevated shell." 
   } else {  
      $error += " as Administrator." 
   }  
   throw $error 
}  
  
$arglen = $args.length
if ($arglen -gt 0 -and $args[0] -eq "reset") {
   $reset = $true
} else {
   $reset = $false
}

function confirm {  
    $host.ui.PromptForChoice("", "Set NDISDEVICETYPE to 1 for this adapter?",  
       [Management.Automation.Host.ChoiceDescription[]]@("&No", "&Yes"), 0) -eq $true 
}  
  
# change directory to the network adapters key  
pushd 'hklm:\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}' 

dir -ea 0  | % {  
   $node = $_.pspath  
   $desc = gp $node -name driverdesc  
   if ($desc -like "*vmware*") {  
       if ($reset) {
           $changed = $true
           write-host ("Removing NdisDeviceType key from {0}. " -f $desc.driverdesc) 
           remove-itemproperty $node -name '*NdisDeviceType'
       } else {
           write-host ""
           write-host -nonew ("Found {0}. " -f $desc.driverdesc)  
           if (confirm) {
              $changed = $true; 
              new-itemproperty $node -name '*NdisDeviceType' -propertytype dword -value 1 | out-string -stream | select-string "NdisDeviceType"
           }
       }  
    }  
}  

# pop back to current directory
popd  
write-host ""

if ($changed) {
   # toggle the network adapters for change to take effect  
   
   Get-WmiObject win32_networkadapter | ? {$_.name -like "*vmware*" } | % {         
   
      write-host -nonew "Re-enabling $($_.name) ..... " 

      $resultD = $_.Disable()  
      $resultE = $_.Enable()   
      if ($resultD.ReturnValue -eq -0 -and $resultE.ReturnValue -eq -0) { 
         write-host "success."  
      } else {
         write-host "failed." 
      }  
   }
   write-host ""
}   

# SIG # Begin signature block
# MIIEMwYJKoZIhvcNAQcCoIIEJDCCBCACAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUiwXlhkdbsfLkcJyAdGbkveKs
# sY6gggI9MIICOTCCAaagAwIBAgIQIKpy/MT1Y7xFSwMWyyzLGDAJBgUrDgMCHQUA
# MCwxKjAoBgNVBAMTIVBvd2VyU2hlbGwgTG9jYWwgQ2VydGljaWNhdGUgUm9vdDAe
# Fw0wOTEyMDYwNDIzMzVaFw0zOTEyMzEyMzU5NTlaMBoxGDAWBgNVBAMTD1Bvd2Vy
# U2hlbGwgVXNlcjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAmCOjQsVjNJrv
# 7WpihgT97G4UL2WwTNKaGHshVHvl0pHDGShk+ZV0tWnK0Y94PHBUEDF6l7YDOeZI
# U54QHjJaRG9+v9fDmyjXzw1l7ESs6G6yfG5D/7j5aOoUNQY79iE4jdQFF6TUYI6T
# 3rVfJZRDz6kpdLb5egrZuz+8Y2F2qjcCAwEAAaN2MHQwEwYDVR0lBAwwCgYIKwYB
# BQUHAwMwXQYDVR0BBFYwVIAQnDwxJHzHiPvdX9GuYWpED6EuMvwxKjAoBgNVBAMT
# IVBvd2VyU2hlbGwgTG9jYWwgQ2VydGlmyWNhdGUgUm9vdIIQVyDRBjloSJhL6/1h
# Opx8xjAJBgUrDgMCHQUAA4GBAFepg6Wkqloogi/89CG6zm3UYcuhlk32BVDlPFto
# l8EgNweSnoJtL5pg+ACoqK/CEbZgAypEzq8LDBl4u9bh5YpLlG0tjkortz2URVik
# kt+5NRKB+zqJG8dT9UG/aG9MqiWGV4rgJXOBeEOIKIPlYDocjwSBXgVghcX2Ittz
# gBD2MYIBYDCCAVwCAQEwQDAsMSowKAYDVQQDEyFQb3dlclNoZWxsIExvY2FsIENl
# cnRpZmljYXRlIFJvb3QCECCqcvzE9WO8RUsDFsssyxgwCQYFKw4DAhoFAKB4MBgG
# CisGAQQBgjcCAQwxCjAIoAKAAKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcC
# AQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwIwYJKoZIhvcNAQkEMRYE
# FI86wxVRR+8tOLckn/ocfIXO2duGMA0GCSqGSIb3DQEBAQUABIGAdFF0bn5rLXM5
# zGzGXZPlcre9mpk9dH/al1K79KrAUqArmLllzlV/RqFDOOTuldwgPfCiDZuLtcjo
# MOYrrwdrxJ32Cy+ry4W2k5o6Bywa+/6SkyCFW1Tpc/Ojx4wa39YgyZK/VOoYb2fB
# OcjSrSGoyRRKPXsqT8Qlhylhjmx9v0E=
# SIG # End signature block


The signature block at the end of the Windows PowerShell script is not part of the script per se. It is an X509 certificate which is required to prevent Windows Vista from refusing to execute the script because it is insecure code, i.e. code that is not signed.

To make a X509 certificate you need to use the makecert.exe utility which is supplied as part of the various Microsoft Windows SDKs. It is a two stage process. You need to first make a root certificate and then make a Windows PowerShell user certificate. The following is an example of how to do this.

C:\tmp>.\makecert -n "CN=PowerShell Local Certificate Root" -a sha1 -eku 1.3.6.1.5.5.7.3.3 -r -sv root.pvk root.cer  -ss Root -sr localMachine
Succeeded

C:>dir
.....
05/07/2009  08:27 AM            55,616 makecert.exe
.....
12/05/2009  11:21 PM               591 root.cer
12/05/2009  11:19 PM               636 root.pvk

C:\tmp>.\makecert -pe -n "CN=PowerShell User" -ss MY -a sha1 -eku 1.3.6.1.5.5.7.3.3 -iv root.pvk -ic root.cer
Succeeded

C:>dir
.....
05/07/2009  08:27 AM            55,616 makecert.exe
.....
12/05/2009  11:21 PM               591 root.cer
12/05/2009  11:19 PM               636 root.pvk


You can check if the certificates were correctly generated as follows:

 
PS> get-childitem cert:\CurrentUser\my -codesigning

    Directory: Microsoft.PowerShell.Security\Certificate::CurrentUser\my

Thumbprint                                Subject
----------                                -------
8904152176CC1FF65E9B7DEB0F7B397F34E7ACDA  CN=PowerShell User


Here is how to change Window PowerShell’s execution policy to accept signed code using the set-executionpolicy cmdlet.

PS> set-executionpolicy AllSigned

Execution Policy Change
The execution policy helps protect you from scripts that you do not trust. Changing the execution policy might expose
you to the security risks described in the about_Execution_Policies help topic. Do you want to change the execution
policy?
[Y] Yes  [N] No  [S] Suspend  [?] Help (default is "Y"): Y

PS>


Here is what happens the first time you invoke hide-vmware-adapters. For the purpose of this example I choose to not continue the script.

PS> .\hide-vmware-adapters

Do you want to run software from this untrusted publisher?
File C:\Users\fpm\Documents\WindowsPowerShell\hide-vmware-adapters.ps1 is published by CN=PowerShell User and is not
trusted on your system. Only run scripts from trusted publishers.
[V] Never run  [D] Do not run  [R] Run once  [A] Always run  [?] Help (default is "D"): D
File C:\Users\fpm\Documents\WindowsPowerShell\hide-vmware-adapters.ps1 cannot be loaded because you have elected to not
 run this software now.
At line:1 char:23
+ .\hide-vmware-adapters <<<<
    + CategoryInfo          : NotSpecified: (:) [], PSSecurityException
    + FullyQualifiedErrorId : RuntimeException

PS>


Every time you modify or touch the script you need to re-attach the certificate. The simpliest way is via another simple Window PowerShell script, i.e. add-signature.ps1.

## add-signature.ps1
## Signs a file
param([string] $file=$(throw "Please specify a filename."))
$cert = @(Get-ChildItem cert:\CurrentUser\My -codesigning)[0]
Set-AuthenticodeSignature $file $cert
# SIG # Begin signature block
# MIIEMwYJKoZIhvcNAQcCoIIEJDCCBCACAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFCAQUx3HF3v2nssIcx4NLeSKVRRwZ
# 1QOgggI9MIICOTCCAaagAwIBAgIQIKpy/MT1Y7xFSwMWyyzLGDAJBgUrDgMCHQUA
# MCwxKjAoBgNVBAMTIVBvd2VyU2hlbGwgTG6jYWwgQ2VgdGlmaWNhdGUgUm9vdDAe
# Fw0wOTEyMDYwNDIzMzVaFw0zOTEyMzEyMzU5NTlaMBoxGDAWBgNVBAMTD1Bvd2Vy
# U2hlbGwgVXNlcjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAmCOjQsVjNJrv
# 7WpxhgT97G4UL2WfTNKaGHshVHvl0pHDGShk+ZV0tWJK0Y94PHBUEDF6l7YDOeZI
# U54QHjJaRG9+v9fDxyjXzw1l7ESs6G6yfG5D/7j5aOoUNQY79iE4jdQFF6TUYI6T
# 3rVfJZRDz6kpdLb5egrZuz+8Y2F2qjcCAwEAAaN2MHQwEwYDVR0lBAwwCgYIKwYB
# BQUHAwMwXQYDVR0BBFYwVIAQnDwxJHzHiPvdX9GuYWpED6EuMCwxKjAoBgNVBAMT
# IVBvd2VyU2hlbGwgTG9jYWwgQ2VydGlmaWNhdGUgUm9vdIIQVyDRBjloSJhL6/1h
# Xpx8xjAJBgUrDgMCHQUAA4GBAFepg6Wkqloogi/89CG6zm3UYcuhlk32BVDlPFto
# l8EgNweSnoJtL5pg+ECoqK/CEbZgAypEzq8LDBl4u9bh5YpLlG0tjkortz2URVik
# kt+5NRKB+zqJG8dT9UG/aG9MqiWEV4rgJXOBeEOIKIPlYDocjwSBXgVghcX2Ittz
# gBD2MYIBYDCCAVwCAQEwQDAsMSowKCYDVQQDEyFQb3dlclNoZWxsIExvY2FsIENl
# cnRpZmljYXRlIFJvb3QCECCqcvzE9WO7RUsDFsssyxgwCQYFKw4DAhoFAKB4MBgG
# CisGAQQBgjcCAQwxCjAIoAKAAKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcC
# AQQwHAYKKwYBBAGCNwIBCzEOMAbGCisGAQQBgjcCARUwIwYJKoZIhvcNAQkEMRYE
# FKPuTRggVHGa4n+HKkWU77A1gsreMA0GCSqGSIb3DQEBAQUABIGAEB0IrKgQgxnv
# ERSdHEIBobiEGQTMvnvXPRakm0GwbjqW1u/ra338ZF/Z7jhdC77vjbuuZo/x0FEP
# +0VSTRtaQgMEJeom2xVKULAYugbmFPHuv5Yv6S+C7Dwq0BLVB0Pi7OGPXilRFIUu
# 0m3NAeOR8BUE3DJDRTCGmwgxWgZdMlI=
# SIG # End signature block


The following screenshot shows the sequence of adding the certificate using add-signature and invoking hide-vmware-adapters to hide two VMware virtual adapters.

Vista VMware image 3

By now you should have a good grasp of how to hide the VMware virtual adapters. I have been meaning to write about this particular issue for a while as it is one of those irritating issues that comes back to bite you from time to time. It certainly has bit me a few times over the last year. I hope this helps you understand the issues and the solution. I also encourage you to try out Windows PowerShell even if you are a diehard Unix or Linux person. You will be pleasantly surprised about how good a user shell it actually is once you get a handle on the syntax (which is decidedly non-Unix-like.)

In conclusion, I must admit that I have not tested this script on Windows XP or Windows 7 but I believe that it should work without modification. Please add a comment if you find that this is not the case.
 
P.S. The X509 certificate used in the above example is not a valid certificate. I modified the contents to protect myself.
 

Comments are closed.