はじめに
tcpdumpの結果からユニークなIPアドレスだけ取り出したいと思い調べたところ、Stack Overflowに素敵な答えがあったのでメモしておきます。
参考
こちらのスレッドを参考にしています。
コマンド
提案されているコマンドは以下のとおりです。
sudo tcpdump -n ip | cut -d ' ' -f 3 | cut -d '.' -f 1-4 | awk '!x[$0]++'
解説
パイプ区切りで解説します。
sudo tcpdump -n ip:
- tcpdump でパケットを取得します。
- -n オプションは、ホスト名の解決を防ぎ、IPアドレスで表示してくれます。
- ip はIPトラフィックのみをキャプチャすることを指示しています。
- tcpdumpは通常、root権限が必要なので、sudoで権限昇格しています。
cut -d ' ' -f 3:
- cut コマンドはテキストをフィールドに分割するために使用されます。
- -d ' ' オプションはデリミタの指定で、ここではスペースをフィールドの区切り文字として設定します。
- -f 3 は、3番目のフィールド(今回だと送信元または宛先のIPアドレス)を抽出します。
cut -d '.' -f 1-4:
- 再び cut コマンドを使用し、ドット . を区切り文字とすることでIPアドレスの抽出を試みています。
- -f 1-4 は、ドット区切りの最初の4つの部分(完全なIPアドレス)を抽出するという意味です。
awk '!x[$0]++':
ここが一番のミソになっています。
- awk コマンドをつかって、すでに出力された各行(この場合はIPアドレス)を追跡し、ユニークな行のみを表示するようにしています。
- !x[$0]++ は、配列 x を使用して、各行($0)が以前に出現したかどうかを追跡します。その行が初めて出現する場合、コマンドは true と評価され、その行が出力されます。同じ行が再び出現する場合、false と評価され、その行はスキップされます。
- 配列 x による追跡は、コマンド実行ごとにリセットされます。このコマンドは、実行されるたびに新しい awk プロセスが開始され、プロセスが終了するとそのプロセスのすべてのデータ(この場合は配列 x の内容も含む)が消去されます。
おわりに
awkで重複の処理をできちゃうという発想がなかったので勉強になりました。awkは軽量なので負荷も少なそうです。
追記: 最初は、tcpdumpの結果をファイルに吐き出して、cat file | sort | uniq としようとしていました。しかし、今回紹介した awk を使うことで、リアルタイム性を得られる点とファイルに吐き出すなどする手間がかからないので、素敵だなぁと思った次第です。
役に立ったと思った方はび確認1杯奢ってください!
この続きはcodocで購入