PowerShellでarpingもどき
目的
PowerShell で Linux ライクな arping コマンドを実現する。
背景
Windows でも ARP エントリ(ARP キャッシュ)を調べるコマンド(ARP -a
や Get-NetNeighbor
)は存在するが、実際に ARP を送出してレスポンスを調べるためのコマンドがない。
コード
IP Helper API(iphlpapi.dll)の SendARP 関数を実行しているだけです。
中身はほぼ PowerShellスクリプトですが、Windows バッチファイルとして実行できます(先頭行をコメントアウトまたは削除して拡張子を .ps1 に変更すると PowerShell スクリプトになります)。PowerShellのコンソール上で使用する場合は、arping 関数を直接使用してください。
arping.bat
@Powershell -NoP -C "&([ScriptBlock]::Create((gc '%~f0'|?{$_.ReadCount -gt 1}|Out-String)))" %* & exit/b
# by earthdiver1
[CmdletBinding(PositionalBinding=$False)]
Param(
[parameter(Position=0)][String]$Target, # IP address of the target host
[String]$Source, # if you have multiple interfaces (optional, default value: 0 (all interfaces))
[Alias("n")][Int]$Count=4, # the number of ARP requests to send (optional, default value: 4)
[Int]$Interval=1 # the interval between ARP requests, in seconds (optional, default value: 1)
)
Function arping {
[CmdletBinding(PositionalBinding=$False)]
Param(
[parameter(Position=0)][String]$Target, # IP address of the target host
[String]$Source, # if you have multiple interfaces (optional, default value: 0 (all interfaces))
[Alias("n")][Int]$Count=4, # the number of ARP requests to send (optional, default value: 4)
[Int]$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>]"
exit
}
if ($Count -lt 1) { exit }
$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
try {
$DstIP = [UInt32][System.Net.IPAddress]::Parse($Target).Address
} catch {
Write-Output "Target IP address $Target is invalid. Please check it and try again."
exit
}
if ($Source) {
try {
$SrcIP = [UInt32][System.Net.IPAddress]::Parse($Source).Address
} catch {
Write-Output "Source IP address $Source is invalid. Please check it and try again."
exit
}
} 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++
$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"
}
}
# update $PSBoundParameters with default parameter values
foreach ($p in $MyInvocation.MyCommand.ScriptBlock.Ast.ParamBlock.Parameters) {
$key = $p.Name.VariablePath.UserPath
if ($PSBoundParameters.ContainsKey($key)) { Continue }
$value = (Get-Variable $key).Value
if ($value) { $PSBoundParameters.Add($key, $value) }
}
arping @PSBoundParameters
実行例
C:\Users\earthdiver1\Desktop> arping 192.168.0.1
ARPing 192.168.0.1:
Reply from 00-3a-9d-80-ed-0c (as 192.168.0.1): index=1, time=26ms
Reply from 00-3a-9d-80-ed-0c (as 192.168.0.1): index=2, time=2ms
Reply from 00-3a-9d-80-ed-0c (as 192.168.0.1): index=3, time=1ms
Reply from 00-3a-9d-80-ed-0c (as 192.168.0.1): index=4, time=2ms
Ping statistics for 192.168.0.1/arp:
Packets: Sent=4, Received=4, Lost=0 (0% loss)
Approximate round trip times in milli-seconds:
Minimum = 1ms, Maximum = 26ms, Average = 8ms
C:\Users\earthdiver1\Desktop> arping 192.168.0.1
ARPing 192.168.0.1:
Reply from 00-3a-9d-80-ed-0c (as 192.168.0.1): index=1, time=26ms
Reply from 00-3a-9d-80-ed-0c (as 192.168.0.1): index=2, time=2ms
Reply from 00-3a-9d-80-ed-0c (as 192.168.0.1): index=3, time=1ms
Reply from 00-3a-9d-80-ed-0c (as 192.168.0.1): index=4, time=2ms
Ping statistics for 192.168.0.1/arp:
Packets: Sent=4, Received=4, Lost=0 (0% loss)
Approximate round trip times in milli-seconds:
Minimum = 1ms, Maximum = 26ms, Average = 8ms
クリエイティブ・コモンズ 表示 - 継承 4.0 国際
Author And Source
この問題について(PowerShellでarpingもどき), 我々は、より多くの情報をここで見つけました https://qiita.com/earthdiver1/items/0b9c85a5f2c90ba51f7e著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .