PwSh.Fw.Network.DHCPv4.psm1

<#
.SYNOPSIS
Module to handle DHCP requests
 
.DESCRIPTION
Module to handle DHCP packets
 
.NOTES
 
#>


# DHCP Packet Format (RFC 2131 - http://www.ietf.org/rfc/rfc2131.txt):
# 0 1 2 3
# 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# | op (1) | htype (1) | hlen (1) | hops (1) |
# +---------------+---------------+---------------+---------------+
# | xid (4) |
# +-------------------------------+-------------------------------+
# | secs (2) | flags (2) |
# +-------------------------------+-------------------------------+
# | ciaddr (4) |
# +---------------------------------------------------------------+
# | yiaddr (4) |
# +---------------------------------------------------------------+
# | siaddr (4) |
# +---------------------------------------------------------------+
# | giaddr (4) |
# +---------------------------------------------------------------+
# | |
# | chaddr (16) |
# | |
# | |
# +---------------------------------------------------------------+
# | |
# | sname (64) |
# +---------------------------------------------------------------+
# | |
# | file (128) |
# +---------------------------------------------------------------+
# | |
# | options (variable) |
# +---------------------------------------------------------------+

$Script:socketIn = $null
$Script:socketOut = $null

function Convert-BytesToString {
    [CmdletBinding()]
    [OutputType([String])]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipeLine = $true)][byte[]]$bytes
    )
    Begin {
        Write-EnterFunction
        $char = @()
    }

    Process {
        $char += -join ($bytes | ForEach-Object { [char]$_ })
    }

    End {
        return -join $char
        Write-LeaveFunction
    }
}

Function Convert-BytesToHex {
    [CmdletBinding()]
    [OutputType([String])]
    param(
        [parameter(Mandatory = $true, ValueFromPipeLine = $true)][Byte[]]$Bytes
    )
    Begin {
        Write-EnterFunction
        $char = @()
    }

    Process {
        $HexString = [System.Text.StringBuilder]::new($Bytes.Length * 2)
        ForEach($byte in $Bytes){
            $HexString.AppendFormat("{0:x2}", $byte) | Out-Null
        }
        $char += $HexString.ToString()
    }

    End {
        return -join $char
        Write-LeaveFunction
    }
}

function Convert-BytesToInt {
    [CmdletBinding()]
    [OutputType([int])]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipeLine = $true)][byte[]]$bytes
    )
    Begin {
        Write-EnterFunction
        $b = @()
    }

    Process {
        $b += $bytes
    }

    End {
        return [int]"0x$(Convert-BytesToHex -Bytes $b)"
        Write-LeaveFunction
    }
}


<#
.SYNOPSIS
Short description
 
.DESCRIPTION
Long description
 
.PARAMETER string
Parameter description
 
.EXAMPLE
An example
 
.NOTES
General notes
#>


function Send-DHCPv4Packet {
    [CmdletBinding()]Param (
        [Parameter(Mandatory = $true, ValueFromPipeLine = $true)][DHCPv4Packet]$Packet,
        [Alias('Destination')]
        [Parameter(Mandatory = $false, ValueFromPipeLine = $false)][ipAddress]$ipaddress =[net.ipaddress]::Broadcast
    )
    Begin {
        Write-EnterFunction
    }

    Process {
        $Packet.Send($ipaddress)
    }

    End {
        Write-LeaveFunction
    }
}

function Receive-DHCPv4Packet {
    [CmdletBinding()]
    [OutputType([DHCPv4Packet])]
    Param (
        [Parameter(Mandatory = $false, ValueFromPipeLine = $false)][string]$xid,
        [Parameter(Mandatory = $false, ValueFromPipeLine = $false)][ipAddress]$ipaddress = [net.ipaddress]::any,
        [Parameter(Mandatory = $false, ValueFromPipeLine = $false)][uint16]$port = 0,
        [uint16]$timeout = 10000
    )
    Begin {
        Write-EnterFunction
    }

    Process {
        # $packet = [DHCPv4Packet]::New()
        # $packet.Receive($ipaddress, $xid)
        $client = new-object net.sockets.udpclient($ipaddress, $port)
        # $client.Connect(68)
        $client.Client.ReceiveTimeout = $timeout
        $ipep = new-object net.ipendpoint([net.ipaddress]::any, 0)
        $receive = $client.receive([ref]$ipep)
        $client.close()

        return $receive
    }

    End {
        Write-LeaveFunction
    }
}