はじめに
- 「このIPアドレスが所属するセグメントはどれだ!」というのを一発で分かるようにしたかった。
- そこで、sqlite3に全てのIPを登録して参照するようにした。
- ものすごい力技なので、良い方法があればご教授ください。
要件
- sqlite3
- perl-Net-IP → ipcountコマンドに必要
テーブル作成
$ echo 'create table segment(IP varchar(255) primary key, Seg varchar(255) );' | sqlite3 segment.db
$ echo '.schema' | sqlite3 segment.db
CREATE TABLE segment(IP varchar(255) primary key, Seg varchar(255) );
データ用意
segments.txt
192.168.0.0/24 セグメントA
192.168.0.1/24 セグメントB
スクリプト用意
import.sh
#!/bin/bash
# IPアドレス表記 -> 32bit値 に変換
function ip2decimal(){
local IFS=.
local c=($1)
printf "%s\n" $(( (${c[0]} << 24) | (${c[1]} << 16) | (${c[2]} << 8) | ${c[3]} ))
}
# 32bit値 -> IPアドレス表記 に変換
function decimal2ip(){
local n=$1
printf "%d.%d.%d.%d\n" $(($n >> 24)) $(( ($n >> 16) & 0xFF)) $(( ($n >> 8) & 0xFF)) $(($n & 0xFF))
}
# IFS を改行文字にする
IFS='
'
for i in $(cat segments.txt)
do
# リストを分解
network=$( awk '{print $1}' <<<$i )
segment=$( awk '{print $2}' <<<$i )
# 最初と最後のIPを32bit値 に変換
start=$(ip2decimal $(/usr/bin/ipcount $network | awk '{print $2}'))
end=$(ip2decimal $(/usr/bin/ipcount $network | awk '{print $4}'))
# IPアドレスとセグメント名の組合わせを登録
for ip in $(seq $start $end)
do
addr=$(decimal2ip $ip)
echo "INSERT INTO \"segment\" VALUES('$addr', '$segment');" | sqlite3 segment.db
done
done
スクリプト実行
$ bash import.sh
IP多いと時間かかります…
テスト
console
$ echo "select * from segment WHERE IP='192.168.0.1';" | sqlite3 ./segment.db
192.168.0.1|セグメントA
謝辞
ip2decimal
及び decimal2ip
は、harasouさんの投稿 を参考にさせていただきました。この場を借りてお礼申し上げます。