Skip to content

Instantly share code, notes, and snippets.

@mkht
Last active March 25, 2021 15:07
Show Gist options
  • Save mkht/73a3147c27dd4ba02e9dbcdaf33b15fb to your computer and use it in GitHub Desktop.
Save mkht/73a3147c27dd4ba02e9dbcdaf33b15fb to your computer and use it in GitHub Desktop.
Send-ARPRequest
# Original code is written by earthdiver1
# https://qiita.com/earthdiver1/items/0b9c85a5f2c90ba51f7e
# Modified by mkht
function Send-ARPRequest {
[CmdletBinding(PositionalBinding = $False)]
[Alias('arping')]
Param(
[Parameter(Position = 0)]
[String]$Target, # IP address of the target host
[Parameter()]
[String]$Source, # if you have multiple interfaces (optional, default value: 0 (all interfaces))
[Parameter()]
[Alias('n')]
[UInt32]$Count = 4, # the number of ARP requests to send (optional, default value: 4)
[Parameter()]
[UInt32]$Interval = 1 # the interval between ARP requests, in seconds (optional, default value: 1)
)
if (-not $Target) {
Write-Output 'Usage: arping <target IP address> [-Source <source IP address>]'
Write-Output ' [-Count/-n <number of ARP requests>] [-Interval <interval between ARP requests>]'
return
}
$code = '[DllImport("iphlpapi.dll")]public static extern int SendARP(UInt32 DestIP,UInt32 SrcIP,byte[] pMacAddr,ref UInt32 PhyAddrLen);'
$type = Add-Type -MemberDefinition $code -Name Win32SendARP -PassThru
$Target = $Target.Trim()
$Source = $Source.Trim()
try {
$DstIP = [UInt32][System.Net.IPAddress]::Parse($Target).Address
}
catch {
Write-Error "Target IP address $Target is invalid. Please check it and try again."
return
}
if ($Source) {
try {
$SrcIP = [UInt32][System.Net.IPAddress]::Parse($Source).Address
}
catch {
Write-Error "Source IP address $Source is invalid. Please check it and try again."
return
}
}
else {
$SrcIP = [UInt32]0
}
$MacAddr = New-Object Byte[] 6
$n_sent = 0
$n_received = 0
$maxT = 0.
$minT = 9999.
$sumT = 0.
Write-Output ''
Write-Output "ARPING ${Target}:"
for ($i = 1; $i -le $Count; $i++) {
$n_sent++
$MacAddr = New-Object Byte[] 6
$result = $null
$t = (Measure-Command { $result = $type::SendARP($DstIP, $SrcIP, $MacAddr, [ref][UInt32]$MacAddr.Length) }).TotalMilliseconds
if ($result -eq 0) {
# NO_ERROR
$n_received++
if ($t -gt $maxT) { $maxT = $t }
if ($t -lt $minT) { $minT = $t }
$sumT += $t
Write-Output "Reply from $(($MacAddr | %{ '{0:x2}' -F $_ }) -Join '-') (as $Target): index=$i, time=$(($t).ToString('0'))ms"
}
elseif ($result -eq 67) {
# ERROR_BAD_NET_NAME
Write-Output 'Request timed out.'
}
else {
Write-Output "SendARP failed with error: $result"
}
if ($i -lt $Count) { Start-Sleep -Milliseconds ([Math]::Max(($Interval * 1000 - [Int]$t), 0)) }
}
Write-Output ''
Write-Output "Ping statistics for $Target/arp:"
Write-Output " Packets: Sent=$n_sent, Received=$n_received, Lost=$($n_sent-$n_received) ($((($n_sent-$n_received)/$n_sent*100).ToString('0'))% loss)"
if ($n_received -gt 0) {
Write-Output 'Approximate round trip times in milli-seconds:'
Write-Output " Minimum = $(($minT).ToString('0'))ms, Maximum = $(($maxT).ToString('0'))ms, Average = $(($sumT/$n_received).ToString('0'))ms"
}
}
Export-ModuleMember -Function 'Send-ARPRequest' -Alias 'arping'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment