You're seeing these because option 249 must be specified as as BINARY value, not as an IPADDRESS value. If you can't set this with the GUI then you'll have to convert your desired route into a hexadecimal string yourself. An example would be as follows: 10.1.1.0/24 accessible via 10.1.1.1 converts into "180a01010a010101". The first octet, "18", is the number of bits of subnet mask (0x18 = 24 decimal). The next octets are the network ID (0a = 10, 01 = 1, 01 = 1, for "10.1.1"), padded by zeros on the right if the subnet mask doesn't end on an even octet boundary. The last four octets are the IP address of the gateway. Set the value in the GUI and you'll be happier.Well I had too many to do, so I couldn't do it with the GUI really and it was too prone to error with fat fingers.. so I knocked up a quick script to accomplish this.. a word of warning is that I have only done /20 /23 and /24 networks with this.. so test it and verify in the GUI!!
Here's the powershell script with an example at the end of how its run for multiple routes...
function ConvertTo-MaskLength { <# .Synopsis Returns the length of a subnet mask. .Description ConvertTo-MaskLength accepts any IPv4 address as input, however the output value only makes sense when using a subnet mask. .Parameter SubnetMask A subnet mask to convert into length Function pinched from http://www.indented.co.uk/2010/01/23/powershell-subnet-math/ #> [CmdLetBinding()] param( [Parameter(Mandatory = $True, Position = 0, ValueFromPipeline = $True)] [Alias("Mask")] [Net.IPAddress]$SubnetMask ) process { $Bits = "$( $SubnetMask.GetAddressBytes() | ForEach-Object { [Convert]::ToString($_, 2) } )" -replace '[\s0]' return $Bits.Length } } function GenerateHex { <# .Synopsis Returns the hex value for creating a static route (DHCP option 121 / 249) - RFC3442 .Description GenerateHex creates the hex value for creating a static route.. untested with anything other than /23 /24 .Parameter SubnetMask EG 255.255.255.0 or /24 .Parameter NetworkAddress The Network address IE 192.168.1.0 .Parameter Gateway Address The IP Address of the gateway to send the traffic to IE 192.168.1.254 #> [CmdLetBinding()] param( [Parameter(Mandatory = $True, Position = 0, ValueFromPipeline = $True)] [String]$NetworkAddress, [Parameter(Mandatory = $True, Position = 1, ValueFromPipeline = $True)] [String]$SubnetMask, [Parameter(Mandatory = $True, Position = 2, ValueFromPipeline = $True)] [String]$GatewayAddress ) # Convert subnet mask to correct format if ($SubnetMask -like "/*") { $SubnetMask = $SubnetMask.Replace("/","") }elseif ($SubnetMask -like "*.*") { $SubnetMask = ConvertTo-MaskLength -SubnetMask $SubnetMask } # Split network into an object by octet $NetAddress = $NetworkAddress.split('.') # Step through the correct number of significant octets (mask / 8 then rounded up) and convert to hex foreach($i in 1..([math]::Ceiling($SubnetMask / 8))){ $Network += "{0:X2}" -f [convert]::ToInt32($NetAddress[$i-1]) } # Convert Gateway Address to Hex Foreach ($octet in $GatewayAddress.split('.')) { $Gateway += "{0:X2}" -f [convert]::ToInt32($octet) } # Convert Mask to Hex $maskHex = "{0:X2}" -f [convert]::ToInt32($SubnetMask) # return calculated output $value = $maskHex + $Network + $Gateway return $value } $String = "" $String += GenerateHex -NetworkAddress 192.168.1.0 -SubnetMask 255.255.255.0 -GatewayAddress 10.111.111.1 $String += GenerateHex -NetworkAddress 10.1.2.0 -SubnetMask 255.255.254.0 -GatewayAddress 10.111.111.1 # Display command rather than execute it Write-Output "netsh dhcp server 192.168.1.1 scope 10.111.111.0 set optionvalue 121 binary $($string)"I then needed to convert some existing boxes from having lots of local persistent routes and was planning on using something like this as the basis of starting a script..
Get-WmiObject Win32_IP4PersistedRouteTable | Select-Object Destination, Mask, Nexthophowever I quickly discovered the machine I was looking at doesn't have powershell installed.. Given I'm in a rush I resorted to VBS as it was my scripting language of choice prior to powershell.. so the following script was used to export the routes and generate the netsh command.. Crude I know, but not as crude as multiple static routes on a server, rather than using a Router!
' Export Routes.vbs On Error Resume Next Set objWMIService = GetObject("winmgmts:\\.\root\cimv2") Set colItems = objWMIService.ExecQuery("Select * from Win32_IP4PersistedRouteTable",,48) For Each objItem in colItems wscript.echo "$String += GenerateHex -NetworkAddress " & objItem.Destination & " -SubnetMask " & objItem.Mask & " -GatewayAddress " & objItem.NextHop Next
This is excellent. I did find one issue. Your comment on line 63 says the right thing (always round up) but the code on line 64 doesn't do that... it does a simple round. Changing [math]::Round to [math]::Ceiling fixed it up for me.
ReplyDeleteThanks, I will update this to reflect that :)
Delete