labunix's blog

labunixのラボUnix

MACアドレスのOUIをローカルで調べるコマンドを作ってみる。

■MACアドレスのOUIをローカルで調べるコマンドを作ってみる。
 Webからなら以下で検索出来る。

 MAC Address and OUI Lookup
 https://aruljohn.com/mac.pl

■基本的な考え方は以下と同じ。
 lsecだけでも良いのでは?という話は置いといて。

 Cisco CLIのsection風lsecの別バージョンを書いてみた。
 http://labunix.hateblo.jp/entry/20181007/1538849761

■辞書となるoui.txtをダウンロード

$ wget http://standards-oui.ieee.org/oui/oui.txt

$ cat oui.txt.1 | lsec F4BD9E
F4BD9E     (base 16)		Cisco Systems, Inc
				80 West Tasman Drive
				San Jose  CA  94568
				US

■小文字なら大文字に、「-」「:」「.」は削りたい。

$ echo $(seq 32 126) | awk '{for(a=1;a<=NF;a++){printf "%c,\\%03o\n",$a,$a}}' | grep "\-\|\.\|:"
-,\055
.,\056
:,\072

■実装する。
 hex行はこの際無視する。
 gsub("[^A-Fa-f0-9]","",key)16進数文字以外はすべて除去。
 先頭から最大6文字が検索対象なので途中の文字からの検索は出来ない。subkey="^"toupper(substr(key,1,6))

$ cat loui 
#!/bin/bash
# Script Name	: Linux OUI Search
# Last Update	: 2019/08/05
# Author	: labunix
# Description	: http://standards-oui.ieee.org/oui/oui.txt
# 

if [ $# -eq 0 ] || [ $# -gt 1 ];then
  test -f oui.txt || wget http://standards-oui.ieee.org/oui/oui.txt
  echo "Usage $0 [HW Addr]" >&2
  exit 1
fi
if [ $# -eq 1 ] && [ -f oui.txt ];then
  awk -v key="$1" 'BEGIN{f=0;gsub("[^A-Fa-f0-9]","",key);subkey="^"toupper(substr(key,1,6))} \
    {if($0 ~ /^[A-z0-9]/){f++;a[f]=$0}else{a[f]=a[f]"___"$0}}\
    END{for(n in a){if(a[n] ~ subkey){gsub("___","\n",a[n]);print a[n]}}}' oui.txt
fi



■変わった方法で試してみる。

$ loui ZX4c:7.1-0[C
4C710C     (base 16)		Cisco Systems, Inc
				80 West Tasman Drive
				San Jose  CA  94568
				US


■wget出来る環境なら。
 出来ない環境なら、コマンドを実行するディレクトリに何らかの方法で「oui.txt」を保存しておく。

$ ./loui
--2019-08-05 20:57:40--  http://standards-oui.ieee.org/oui/oui.txt
172.31.31.60:8080 に接続しています... 接続しました。
Proxy による接続要求を送信しました、応答を待っています... 200 OK
長さ: 4209124 (4.0M) [text/plain]
`oui.txt' に保存中

oui.txt       100%[============================================================>]   4.01M  68.2KB/s    in 91s     

2019-08-05 20:59:12 (45.1 KB/s) - `oui.txt' へ保存完了 [4209124/4209124]
■検索キーワードを付けない、オプション無しの上京で「oui.txt」があるなら簡単な使い方を表示する。

$ ./loui
Usage ./loui [HW Addr]16進数が無い引数ならcat。

$ loui z | md5sum
95269c81a83c1f4fede8baa2e297804c  -

$ cat oui.txt | md5sum
95269c81a83c1f4fede8baa2e297804c  -

■途中の検索はlsecで出来る。
 catと同じだからと言って、こんな使い方はしないはずではあるけれど。

$ loui z | lsec D00D
00D00D     (base 16)		MICROMERITICS INSTRUMENT
				CORPORATION
				NORCROSS  GA  30093-1877
				US

94D00D     (base 16)		HUAWEI TECHNOLOGIES CO.,LTD
				No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
				Dongguan     523808
				CN

14D00D     (base 16)		Apple, Inc.
				1 Infinite Loop
				Cupertino  CA  95014
				US

$ cat oui.txt | lsec D00D
00D00D     (base 16)		MICROMERITICS INSTRUMENT
				CORPORATION
				NORCROSS  GA  30093-1877
				US

94D00D     (base 16)		HUAWEI TECHNOLOGIES CO.,LTD
				No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
				Dongguan     523808
				CN

14D00D     (base 16)		Apple, Inc.
				1 Infinite Loop
				Cupertino  CA  95014
				US


■先頭から[A-Fa-f0-9]を見つけた16進数は6文字分のみ有効なので、
 こんな感じで使える。

$ ip a | awk '/link.ether/{print "./loui "$2}' | sh
000C29     (base 16)		VMware, Inc.
				3401 Hillview Avenue
				Palo Alto  CA  94304
				US


■検索文字数は1文字以上。先頭からという制限はMACアドレスベンダーを探すのに特に問題にはならないはず。
 正規表現はパイプすれば良いので、例えば「lsec」と組み合わせて。

$ loui 1 | lsec 3BD
183BD2     (base 16)		BYD Precision Manufacture Company Ltd.
				No3000 LongDong Avenue, Pudong District
				Shanghai    201203
				CN

$ loui 00 | lsec C29
000C29     (base 16)		VMware, Inc.
				3401 Hillview Avenue
				Palo Alto  CA  94304
				US

001C29     (base 16)		CORE DIGITAL ELECTRONICS CO., LTD
				1006# 102 CHUNUITECHNOPARK 200-1
				BUCHEON-CITY  GYUNGGI-DO  420-857
				KR