1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ネットワーク運用で地味に便利なMACアドレスの変換・解析・差分比較ツール「MACForge」を作った話

1
Posted at

はじめに

無線APやDHCPサーバーへのMACアドレスフィルタリング登録、日常的にやっていると地味に手間がかかりませんか。

  • 機器メーカーによってコロン区切り・ハイフン区切り・区切りなし、形式がバラバラ
  • 大量登録後に「どれが追加されてどれが誤って消えたか」を目視確認
  • 「このMAC、ランダムMACじゃないか?」という判断を毎回手作業
  • ipconfig /all の出力からMACアドレスだけを素早く抜き出したい
  • このOUIはどのベンダーのものか調べたい

こういった運用現場の小さな面倒を解消するために、HTMLファイル単体で動くMACアドレスユーティリティMACForge を作りました。(主に自分用)


MACForge とは

MACForge はブラウザ上で動作するMACアドレス管理ツールです。インストール不要で、HTMLファイルをブラウザで開くだけで使えます。
https://macforge.nafusaba.com/

主な機能は5つです。

  • 変換 / 解析 — 6形式への一括変換とOUIベンダー自動参照
  • 差分比較 — 変更前後のMACリスト比較(追加・削除・保持の判定)
  • OUI 検索 — 正引き(MAC → ベンダー)と逆引き(ベンダー名 → OUI)
  • MAC 生成 — 条件指定による大量生成
  • アドレス解説 — ビット構造図付きのリファレンス

技術スタック

フレームワーク・ライブラリは一切使っていません。依存関係ゼロのバニラ実装です。

項目 採用技術
フォント Inter + JetBrains Mono(Google Fonts)
スタイリング CSS カスタムプロパティ(ライト/ダーク両対応)
ロジック Vanilla JS('use strict'
OUI DB参照 fetch('./oui_db.json') でローカルJSON読み込み
DB更新 Python スクリプト(標準ライブラリのみ)

機能解説

変換 / 解析

image.png

3カラムのレイアウトで、左からMACアドレス入力・変換設定・変換結果テーブルが並びます。

対応フォーマット(自動判別・相互変換)

AA:BB:CC:DD:EE:FF   # コロン区切り(Linux / macOS)
AA-BB-CC-DD-EE-FF   # ハイフン区切り(Windows)
AABBCCDDEEFF        # 区切りなし 大文字
aabbccddeeff        # 区切りなし 小文字
aa.bb.cc.dd.ee.ff   # ドット区切り
aaaa.bbbb.cccc      # Cisco 形式

複数の出力形式を同時選択でき、実行すると1本の横スクロール対応テーブルとして結果が並びます。同じ行を横に見れば、同一MACアドレスの全形式とベンダー情報が一目でわかります。

OUIのみの入力にも対応

先頭3バイト(例:AA:BB:CC)だけを入力してもベンダー検索が動作します。これはネットワーク機器のログ解析時に「OUIだけわかっていてNIC固有部は不明」という場面で役立ちます。

MAC抽出機能

ipconfig /allshow mac-address-table などの生テキストを貼り付けて「MAC抽出」ボタンを押すと、4パターンの正規表現でMACアドレスだけを抜き出します。

# ipconfig /all の出力例(こういったテキストをそのまま貼り付けられる)
   物理アドレス. . . . . . . . . . . . .: AA:BB:CC:DD:EE:01
   物理アドレス. . . . . . . . . . . . .: AA:BB:CC:DD:EE:02

抽出後はそのまま変換・解析の対象にできます。


差分比較

image.png

3カラム構成(事前リスト・事後リスト・結果)で、変更前後のMACリストを比較します。

# 事前(リストA)     # 事後(リストB)     # 結果
AA:BB:CC:DD:EE:01    AA:BB:CC:DD:EE:01    保持
AA:BB:CC:DD:EE:02    AA:BB:CC:DD:EE:03    削除
AA:BB:CC:DD:EE:03                         追加
                     AA:BB:CC:DD:EE:04

判定結果は追加・削除・保持でフィルタリングでき、CSV / TSV / テキスト / JSON の4形式でエクスポートできます。


OUI DB

image.png

IEEE の公式OUIリストを元に生成した 39,227件 のデータベースを内蔵しています。DBは oui_db.json(約1.3MB)として同階層に配置し、ブラウザが fetch() で読み込む設計です。

oui_db.json の構造

{
  "_meta": {
    "generated": "2026-04-26T00:02:52Z",
    "entries": 39227,
    "source": "IEEE Standards Association"
  },
  "data": {
    "00000C": "Cisco Systems, Inc",
    "001B63": "Apple, Inc.",
    ...
  }
}

_meta.generated の値がUIの「DB最終更新」として表示されます。

DB更新スクリプト(Python)

# 通常実行(変更がなければスキップ)
python3 update_oui_db.py
 
# 強制更新
python3 update_oui_db.py --force
 
# 出力先を指定
python3 update_oui_db.py --output /var/www/html/oui_db.json

SHA-256ハッシュで前回取得分と差分チェックし、変更がなければ書き込みをスキップします。IEEEのサーバーが落ちていた場合はWiresharkのGitHubミラーにフォールバックします。

cron設定例(月1回深夜に自動更新)

0 3 1 * * /usr/bin/python3 /path/to/update_oui_db.py >> /var/log/macforge_oui.log 2>&1

MAC 生成

image.png

オプション 説明
生成数 1〜1,000件
OUI固定 先頭3バイトを指定ベンダーに固定
ランダムMAC U/Lビット(bit1)を1にセット(LAA形式)
ユニキャスト保証 I/Gビット(bit0)を0に強制

テスト環境でのMAC学習テストや、スイッチのポートセキュリティ設定の検証などで使えます。


実装の工夫

MACアドレスの正規化

形式がバラバラな入力を正規化する関数はシンプルに書けます。

function parseMACOrOUI(raw) {
  // 区切り文字を除去して16進数だけ残す
  const h = raw.replace(/[^a-fA-F0-9]/g, '').toUpperCase();
  if (h.length === 12) return { hex: h, pairs: h.match(/.{2}/g), isOUI: false };
  if (h.length === 6)  return { hex: h + '000000', pairs: (h + '000000').match(/.{2}/g), isOUI: true, ouiHex: h };
  return null;
}

Cisco形式の aaaa.bbbb.cccc も、コロン区切りの AA:BB:CC:DD:EE:FF も、replace(/[^a-fA-F0-9]/g, '') で12桁の16進数に統一されます。

MAC抽出の正規表現

生テキストからのMAC抽出は3パターンの正規表現で対応しています。

function extractMACs(text) {
  const patterns = [
    /([0-9A-Fa-f]{2}[:\-][0-9A-Fa-f]{2}[:\-][0-9A-Fa-f]{2}[:\-][0-9A-Fa-f]{2}[:\-][0-9A-Fa-f]{2}[:\-][0-9A-Fa-f]{2})/g,
    /([0-9A-Fa-f]{4}\.[0-9A-Fa-f]{4}\.[0-9A-Fa-f]{4})/g,
    /([0-9A-Fa-f]{12})/g,
  ];
  const found = new Set();
  patterns.forEach(p => { let m; while ((m = p.exec(text)) !== null) found.add(m[1]); });
  return [...found];
}

Set を使うことで重複を自動排除しています。

I/GビットとU/Lビットの判定

MACアドレスの第1バイトの最下位2ビットが特殊な意味を持ちます。

function isRandMAC(hex) { return (parseInt(hex.slice(0, 2), 16) & 0x02) !== 0; } // U/Lビット
function isMulticast(hex) { return (parseInt(hex.slice(0, 2), 16) & 0x01) !== 0; } // I/Gビット
ビット 名称 0 1
bit0(I/G) Individual/Group ユニキャスト マルチキャスト / BC
bit1(U/L) Universal/Local グローバル管理(OUI有効) ローカル管理(ランダムMAC)

iOS 14 / Android 10 以降のWi-Fiプライバシー機能で生成されるランダムMACはU/Lビットが1になっています。

CSSカスタムプロパティによるダークモード

ライト/ダークの切り替えは data-theme 属性の付け替えだけで完結します。

:root {
  --bg0: #f5f6fa;
  --txt0: #1a2035;
  --blue: #2563eb;
}
 
[data-theme="dark"] {
  --bg0: #0f1117;
  --txt0: #e8ecf5;
  --blue: #3b82f6;
}
document.documentElement.dataset.theme = dark ? 'dark' : '';

ファイル構成

macforge.html       # ツール本体(これだけでも動作、ベンダー情報はフォールバックDB)
oui_db.json         # OUI DB(39,227件)※同階層に配置で自動参照
update_oui_db.py    # DB更新スクリプト(Python 標準ライブラリのみ)

oui_db.json がない場合は主要ベンダー(Cisco・Apple・Ubiquiti・VMware など)を含むフォールバックDBで動作します。


配布・公開について

MACForge は Nafusaba のネットワーク管理ツールシリーズの一つとして公開しています。

利用上の注意
MACアドレスの偽装・なりすましへの悪用は固く禁じます。正当な業務・学習目的のみご利用ください。


おわりに

外部ライブラリへの依存ゼロ・サーバー不要・ブラウザだけで動くという制約の中で、実務で使えるツールを作ることができました。OUIデータベースを定期更新できる仕組みと、ipconfig などの生テキストからのMAC抽出機能が特に現場で役立っています。

同じNafusabaツールとして、パケット解析ツール PacketLens も公開しています。
ネットワーク管理に携わる方の参考になれば幸いです。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?