Last active
March 25, 2021 15:07
-
-
Save mkht/73a3147c27dd4ba02e9dbcdaf33b15fb to your computer and use it in GitHub Desktop.
Send-ARPRequest
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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