qshinoの日記

Powershell関係と徒然なこと

高速 ping

IPアドレス調査高速化

DHCPで割り当てられた他装置のIPアドレスを高速に調べたい。

非サーバ管理者を前提とする。

方法

  1. シーケンシャルにping
  2. ping多重実行

シーケンシャルping

for文でping -c 1 - w 0.5 などを繰り返す。

多重ping

pingを多重実行し、結果を刈り取る。

前半でpingを非同期実行し、pidとipアドレスを配列に保管する。

後半で配列からpidとipアドレスを取り出し、pid毎にping結果を受け取る。

下記ではpingを254多重で実行する。

#!/bin/sh

base=192.168.0
from=1
to=254

list=`seq $from $to`

function oneping(){
  ad=$1
  ping -c 1 -w 0.5 $ad 2>&1 >/dev/null
}

pids=()
ipas=()

for ix in $list ; do
  ipa="${base}.$ix"
  oneping ${ipa} &
  pids+=($!)
  ipas+=($ipa)
done

cnt=0

for ix in $list ; do
  pid=$(pids[$cnt])
  ipa=$(ipas[$cnt])
  wait $pid
  if [ $? -eq 0 ]; then
     # ping success
     echo $ipa
  fi
  cnt=$(( $cnt + 1 ))
done

ポイント

  • sh関数をbg実行できる。
  • pids, ipas配列を使う。
  • waitの戻り値 $? を使う。
  • 最後に実行したプロセスのpid が$!
  • pingの待ち時間を -w 秒 で指定。
  • pingが成功したip addressのみを表示する。
  • 関数 oneping の戻り値はreturnを省略しているため、最後に実行したpingの終了ステータスになる。
  • 関数の戻り値は、0-255 であり、returnで指定するか、指定しない場合は最後のコマンドの終了ステータスとなる。
  • 関数内のローカル変数は、localで指定する。(bashの場合)

今後

今後の発展としては、実行結果をDBに登録し、前回の結果と比較し、差分を抽出する。

選択肢は、

  1. DBへの登録間隔。
  2. 履歴を保管する方法。保管する世代数。保管方法、保管単位(アドレス単位、調査実施単位、差分のみ等)
  3. 差分の表示方法

差分の保管方法1

調査データは下記項目。

調査時刻、(アドレス、ping結果) x N

Table 1: 調査ID, 時刻 Table 2: 結果ID, 調査ID,アドレス,ping結果

差分: 調査id-a,bの比較

アドレス毎に、ping結果が異なる物を抽出する。

差分の保管方法2

Table 1 案1と同じ

Table 2 結果id,調査id,アドレス

Table 2に登録されるのは、pingが成功したもののみ。

差分: 前回調査で存在しなかったものが追加されたアドレス。前回調査に存在したが、今回存在しないものが消えたもの。

テーブルを2回引くか、joinして抽出する。

案2だと、ping失敗レコードが不要な為、DBサイズが案1より小さい。

dhcpで新規登録されたアドレスを探す目的であり、案2で増えたアドレスを表示するのが、簡単。

差分の保管方法3

アドレスをキーにする案。

アドレス, 前回結果

新規調査時、前回と結果が異なればテーブルを更新し、差分を表示。

履歴が一世代しか取れないが単純。

履歴が必要なら、同じ形式のテーブルを世代数分持つ方法もある。

その他

簡素化のため、出力ファイルをgit登録。 git dif により差分確認。

参考

https://bash.cyberciti.biz/guide/Putting_functions_in_background