pslaboが試したことの記録

はてなダイヤリーからはてなブログに引っ越してきました

この日記は現在実行中の減量記録を含む個人的なメモとして始めましたが、最近はコンピュータやガジェット、ハック、セキュリティネタのほうがメインになっております。

はてなダイヤリー時代はカテゴリ分けが適当だったのですが、これはそのうち直します。


IEEEのMACアドレス oui.txt を元にして MACアドレス→ベンダー名の変換を行う sed フィルタを作ってみる

先日、「MACアドレスからベンダーを検索して表示するコマンド」を作ってみる、なんてことをやったわけですが、あれはインターネット側のAPIを呼ぶ形式なのでインターネット接続が必要でした。

pslabo.hatenablog.com

しかしそれだと閉じたネットワークでは使いづらいので、IEEE の oui.txt を用いて MAC アドレスをベンダー名に変換するフィルタを sed で作ってみます。

oui.txt はこちらURLから入手できます。
http://standards-oui.ieee.org/oui.txt

さて、本件のポイントは「oui.txt → sed」の変換を行うスクリプトを書くことにあります。oui.txt は以下のようなフォーマットですが、これを変換してMACアドレスのベンダーコードとベンダー名の sed フィルタを生成すればよいわけです。この処理を手作業で行うのは無茶なので、これは是非ともスクリプトで対処したい。

E0-43-DB   (hex)        Shenzhen ViewAt Technology Co.,Ltd. 
E043DB     (base 16)        Shenzhen ViewAt Technology Co.,Ltd. 
                9A,Microprofit,6th Gaoxin South Road, High-Tech Industrial Park, Nanshan, Shenzhen, CHINA.
                shenzhen  guangdong  518057
                CN


で、oui.txt からこんな sed フィルタが得られるようにします。最終的な sed フィルタは2万行を超えるボリュームなので処理速度が遅い機材ではフィルタ処理が若干もたつくかもしれませんが、それでもインターネット接続無しで使えるメリットは大きいだろうと思っております。

# oui.txt から oui2vendor.sed を作ります。
$ cat oui.txt | ./generate_oui2vendor.awk 

# 出来上がったファイルを確認します。
$ ls -l oui2vendor.sed 
-rwxr-xr-x  1 pslabo  staff  2086558  3 31 00:07 oui2vendor.sed

# 中身を覗いてみます。
$ head -2 oui2vendor.sed 
#!/usr/bin/sed -f
s/[eE]0[-:]\{0,1\}43[-:]\{0,1\}[dD][bB]\([-:]\{0,1\}[0-9A-Fa-f]\{2\}\)\{3\}/Shenzhen ViewAt Technology Co.,Ltd./g

# で、件数はというと……。
$ wc -l oui2vendor.sed 
   21813 oui2vendor.sed

oui.txtをsedのフィルタに変換する処理の generate_oui2vendor.awk はこんなふうに書いてみました。正規表現はもうちょっとキレイに書けるかもしれませんね。

#!/usr/bin/awk -f 

# Generate oui matching sed script from oui.txt
# wget http://standards-oui.ieee.org/oui/oui.txt

BEGIN {
    output_file="oui2vendor.sed"

    print "#!/usr/bin/sed -f" > output_file
}

{
    # oui.txt is msdos formarted text. so it have to delete "\r" by sub()
    sub( /\r/, "" )
}

$2 == "(hex)" {
#    printf "%d\t%s\n", NF, $0
    oui=$1

    gsub( /-/, "[-:]\\{0,1\\}", oui )

    # ignore case
    gsub( /A/, "[aA]", oui )
    gsub( /B/, "[bB]", oui )
    gsub( /C/, "[cC]", oui )
    gsub( /D/, "[dD]", oui )
    gsub( /E/, "[eE]", oui )
    gsub( /F/, "[fF]", oui )

    oui = oui "\\([-:]\\{0,1\\}[0-9A-Fa-f]\\{2\\}\\)\\{3\\}"
    #oui = oui "\\([-:]\\{0,1\\}[0-9A-F]\\{2\\}\\)\\{3\\}"

    vendor = $3 

    for ( i = 3 ; i <= NF ; i++ ) {
        i == 3 ? vendor = $i : vendor = vendor " " $i
    }

    gsub( /\//, "\\/", vendor )


    printf "s/%s/%s/g\n", oui, vendor > output_file
}

このようにして作成した oui2vendor.sed を使うと、以下のようになります。

# 参考: oui2vendor.sed を通さない場合
$ /sbin/ifconfig en0
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	ether b8:e8:56:xx:xx:xx
	inet6 __________ prefixlen 64 scopeid 0x4 
	inet __________ netmask 0xffffe000 broadcast __________
	nd6 options=1<PERFORMNUD>
	media: autoselect
	status: active

# oui2vendor.sed を通す場合
$ /sbin/ifconfig en0 | ./oui2vendor.sed 
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	ether Apple, Inc. 
	inet6 __________ prefixlen 64 scopeid 0x4 
	inet __________ netmask 0xffffe000 broadcast __________
	nd6 options=1<PERFORMNUD>
	media: autoselect
	status: active


ただし使ってみて思ったのは、MACアドレスとベンダー名を併記する形の出力もできたほうがいいんじゃないか、ということ。

気が向いたら、修正してみようかな。