Jump to content

Get Hostname from DHCP


MrBeatnik
 Share

Recommended Posts

================================================================================

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.

;================================
; 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 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

  • 2 weeks later...

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

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...