MrBeatnik Posted November 17, 2009 Share Posted November 17, 2009 (edited) ================================================================================Updated 21-10-10****************Previous version was not RFC compliant to bootp packet.This resulted in problems if bootp packet returned more options than expected in the original creation.Our DHCP setup has changed a little, and more options are coming down.The script has therefore been modified to be compliant to bootp RFC standards.This script can now read any DHCP option, not just option 12.However, the script is still focused on retreiving option 12 only.You can modify manually to read whatever option number you require.================================================================================Hi all,This script is to query DHCP server using BOOTP protocol and retrieve OPTION12 (Hostname).This script was made to create a 32-bit solution to a previously used 16-bit app (Created @ Sussex University by an IT member, webpage since gone).The 32-bit application was required to work in PE.This allows all our machines names to be centrally "managed" in DHCP:The script could modify SYSPREP.INF or UNATTEND.XML to set the correct computername at image time.I'm posting this at a request of another user who was following my quest on getting OPTION12!********************************************************************************This script may not work on all systems.Our DHCP server gives both DHCP and BOOTP requests.This application will require a firewall exception.********************************************************************************I haven't really had time to tidy this up a great deal so is perhaps a little sloppy.Would appreciate any comments/feedback, cleanup ideas or any other input etc.expandcollapse popup;================================ ; GetOpt12 2.1 ; MrBeatnik 04-11-09 ; UPDATED: 23-10-10 ; Get DHCP Option 12 from DHCP ;================================ ; Send BOOTP request to router ; Receive BOOTP packet ; Pick apart packet for OPTION 12 ; ; Must have BOOTP enabled on DHCP ; server (send both). ;================================ #include <GUIConstantsEx.au3> #include <string.au3> Global $errtit="Hostname Error " global $loopNum=0,$loopMax=500 global $socketA, $socketB global $myIP = @IPAddress1 $splitDrive = StringSplit(@WindowsDir,"\") $sysDrive = $splitDrive[1] global $hnFile = $sysDrive & "\hostname.txt" $AdapterList = GetAdaptersList( ) ;Set Adapter VARS global $macVar = $AdapterList[1][2] global $routerIP = $AdapterList[1][4] ;change to your router IP - Note this would be broadcast address (255.255.255.255) in next AutoIT release. global $mymac=StringReplace($macVar,":","") global $mypacket="0x"&"01010600ca1d0c4a0100000000000000000000000000000000000000" & $mymac & "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" ; stick together to a binary string ! ;Note this packet is a BOOTP request packet! ;Start App _startup() While 1 $status = UDPSend($socketA, $mypacket) $data = UDPRecv($socketB, 500,1) _readData($data) $loopNum+=1 If $loopNum == $loopMax Then msgbox(0,$errtit & "#1001","Did not receive BOOTP packet in expected time.",10) Exit 1001 EndIf WEnd Exit 0 ;============== ; Functions ;============== Func _startup() ;Function 1100 - Create UDP socket to send and receive data on. ;Init UDP UDPStartup() ;Open socket to send $socketA = UDPOpen($routerIP, 67) ;67 is the bootpS port on broadcast. If @error <> 0 Then msgbox(0,$errtit & "#1101","UDP Open Error: " & @error,10) Exit 1101 EndIf ;Open socket to receive $socketB = UDPBind($myIP, 68) ;68 is the bootpC port on local machine. If @error <> 0 Then msgbox(0,$errtit & "#1102","UDP Bind Error: " & @error,10) Exit 1102 EndIf EndFunc Func _readData($data) ;Function 1200 - Check read data. If $data <> "" Then ;Check this packet is not being broadcast but destined for correct MAC. $var = StringMid($data, 59, 12) ;Strip out where MAC would be (this may be different on your packet!) If $var <> $mymac then Return 1 ;Go back to reading data ;Correct MAC found - check for data inside. ;As per bootp RFC, data (Options) start at character 481 (First 480 Chars represent 240 Bytes of data). ;Drop the 482 Chars (480 + 2 for the 0x) $optData = StringMid($data, 483) ;msgbox(0,"",$optData) ;Now find Option 12: ;First two chars represent Option num. ;Second two chars represent Data Length. $charN=1 While 1 $optNum = Dec(StringMid($optData, $charN,2)) $optLen = Dec(StringMid($optData, $charN+2,2))*2 ;msgbox(0,"",$optNum & " " & $optLen) If $optNum = 12 Then $opt12=StringMid($optData, $charN+4,$optLen) $hnString = _HexToString($opt12) $hnString = StringStripCR($hnString) If $hnString="" Then $hnString="NOVALUE12" $hnString = StringUpper($hnString) ;msgbox(0,"Hostname is:",$opt12 & "--->" & $hnString & "<") ExitLoop ElseIf $optNum = 255 Then ;End of Options ;msgbox(0,"No Hostname Found:","Option 12 was not found within the packet.") $hnString = "NOOPTION12" ExitLoop EndIf $charN = $charN + 4 + $optLen WEnd _writeHostname($data,$String) Exit EndIf EndFunc Func _writeHostname($data,$String) ;Function 1300 - Write HOSTNAME data to text file. $file = FileOpen($hnFile, 2) If $file = -1 Then MsgBox(0, $errtit & "#1301", "Unable to open file for writing: " & $hnFile,10) Exit 1301 EndIf FileWriteLine($file, $String) FileClose($file) EndFunc Func GetAdaptersList( $ListAll = 0 ) ;Func 1400 - Get WMI adapter to setup UDP correctly. Local $Cols = 5 Local $Adapters[1][$Cols] $Adapters[0][0] = 0 If @OSTYPE = "WIN32_NT" Then ;Use WMI Local $o_WMIService = ObjGet( "winmgmts:\\" & @ComputerName & "\root\cimv2" ) Local $Query = "SELECT Index, Caption, MACAddress, IPAddress, DefaultIPGateway FROM Win32_NetworkAdapterConfiguration" If $ListAll = 0 Then $Query &= " Where IPEnabled = True" EndIf Local $o_Adapters = $o_WMIService.ExecQuery( $Query, "WQL", 0x30 ) If IsObj( $o_Adapters ) Then Local $o_Adapter For $o_Adapter In $o_Adapters If $o_Adapter.IPAddress(0) <> @IPAddress1 Then ExitLoop $Adapters[0][0] += 1 ReDim $Adapters[UBound($Adapters) + 1][$Cols] $Adapters[$Adapters[0][0]][0] = $o_Adapter.Index ;index $Adapters[$Adapters[0][0]][1] = $o_Adapter.Caption ;adapter name $Adapters[$Adapters[0][0]][2] = $o_Adapter.MACAddress ;adapter real mac address $Adapters[$Adapters[0][0]][3] = $o_Adapter.IPAddress(0) ;IP $Adapters[$Adapters[0][0]][4] = $o_Adapter.DefaultIPGateway(0) ;Default Gateway Next EndIf EndIf If $Adapters[0][0] == 0 Then ;No adapter found with our IP msgbox(0,$errtit & "#1401", "Could not get network adapter details.",10) Exit 1401 EndIf return $Adapters EndFunc Edited October 23, 2010 by MrBeatnik Please correct me if I am wrong in any of my posts. I like learning from my mistakes too. Link to comment Share on other sites More sharing options...
QuantumRiff Posted November 25, 2009 Share Posted November 25, 2009 Thanks, this is really helpful. I have been wanting to publish Timezone and Active Directory OU in DHCP for a while now, and rewrite the sysprep files. Then, no manual intervention would be necessary for imaging any of our computers in any office. Link to comment Share on other sites More sharing options...
CapnLars Posted November 26, 2009 Share Posted November 26, 2009 Mr Beatnik, Thanks for posting this. I cannot detect a reply, though, in WinPE. I can wireshark and see the server is replying to port 68, but the UDPRecv doesn't seem to see it. Larry Link to comment Share on other sites More sharing options...
MrBeatnik Posted December 3, 2009 Author Share Posted December 3, 2009 Mr Beatnik, Thanks for posting this. I cannot detect a reply, though, in WinPE. I can wireshark and see the server is replying to port 68, but the UDPRecv doesn't seem to see it. Larry You need to disable the firewall. Assuming you are using WinPE 3: wpeutil disablefirewall In practice, you would add an exception to the firewall (through registy). You would need to do this before the network has been initialised (so modify the WIM before loaded). To test this before cracking open the WIM (again, assuming WinPE 3): [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\services\SharedAccess\Parameters\FirewallPolicy\FirewallRules] "UDP Query User{89888F58-4822-411A-9173-E24C767A437D}X:\\hostnamerequest.exe"="v2.10|Action=Allow|Active=TRUE|Dir=In|Protocol=17|Profile=Domain|Profile=Private|Profile=Public|App=X:\\hostnamerequest.exe|Name=HostnameRequest|Desc=HostnameRequest|Defer=User|"You may need to modify the location/script name of course. Merge that file before the network has started, then to start the network (and allow the firewall exceptions to apply) type: wpeutil initializenetwork Note when I say WinPE 3, I was using a boot.wim taken from a Win7 RTM. Please correct me if I am wrong in any of my posts. I like learning from my mistakes too. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now