jpskill.com
💬 コミュニケーション コミュニティ

routeros-mndp

MikroTikルーターの近隣探索プロトコルMNDPの仕組みやパケット構造、RouterOSの/ip/neighbor機能との連携を理解し、WinBoxでのデバイス発見や近隣リスト表示に関する問題を解決するSkill。

📜 元の英語説明(参考)

MNDP (MikroTik Neighbor Discovery Protocol) wire format, behavior, and RouterOS /ip/neighbor integration. Use when: implementing MNDP discovery, parsing MNDP packets, working with /ip/neighbor, understanding WinBox device discovery, debugging why a router doesn't appear in neighbor lists, or when the user mentions MNDP, neighbor discovery, WinBox discovery, or /ip/neighbor.

🇯🇵 日本人クリエイター向け解説

一言でいうと

MikroTikルーターの近隣探索プロトコルMNDPの仕組みやパケット構造、RouterOSの/ip/neighbor機能との連携を理解し、WinBoxでのデバイス発見や近隣リスト表示に関する問題を解決するSkill。

※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o routeros-mndp.zip https://jpskill.com/download/20955.zip && unzip -o routeros-mndp.zip && rm routeros-mndp.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/20955.zip -OutFile "$d\routeros-mndp.zip"; Expand-Archive "$d\routeros-mndp.zip" -DestinationPath $d -Force; ri "$d\routeros-mndp.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して routeros-mndp.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → routeros-mndp フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-18
取得日時
2026-05-18
同梱ファイル
1

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

MNDP — MikroTik Neighbor Discovery Protocol

MNDPは、RouterOSがローカルネットワーク上でデバイスを自動的に検出するために使用するUDPブロードキャスト/マルチキャストプロトコルです。これは、WinBoxがルーターを見つけるために使用するのと同じプロトコルです。すべてのRouterOSデバイスはデフォルトで参加します。

エージェントにとってこれが重要な理由

  • RouterOSの/ip/neighborは、MNDPの結果を表示するCLI/RESTインターフェースです。
  • WinBoxの「Neighbors」タブはMNDPリスナーです。
  • MikroTik機器のデバイス検出を実装するエージェントはMNDPを必要とします。
  • このプロトコルは、ライブラリを必要とせず、ゼロから実装するのに十分シンプルです。

プロトコルの基本

プロパティ
トランスポート UDP
ポート 5678
IPv4 255.255.255.255:5678へのブロードキャスト
IPv6 ff02::1 (all-nodes link-local)へのマルチキャスト
方向 双方向 — 送信と受信に同じポートを使用
認証 なし — 読み取り専用の検出、資格情報は不要
スコープ レイヤー2ブロードキャストドメイン (ルーターを越えない)

検出の仕組み

  1. リスナーがリフレッシュパケットを送信します — 255.255.255.255:5678への9バイトのUDPデータグラムです。
  2. LAN上のすべてのRouterOSデバイスが応答します — 各デバイスは、ID、バージョン、ボード、MAC、IP、稼働時間などを含むTLVエンコードされたアナウンスを送信します。
  3. 応答は非同期に到着します — ネットワークの状態に応じて、デバイスはミリ秒から数秒で応答します。
  4. RouterOSデバイスは、プロンプトなしで定期的にアナウンスも行います (約60秒サイクル) — パッシブリスニングは機能しますが、情報が埋まるのが遅いです。

リフレッシュパケット (検出リクエスト)

ブロードキャストドメイン上のすべてのRouterOSデバイスから即座の応答をトリガーする9バイトのパケットです。

Offset  Length  Value       Field
0       2       0x0000      type (MNDP)
2       2       0x0000      sequence number (0 for request)
4       2       0x0000      TLV type (none)
6       2       0x0000      TLV length (none)
8       1       0x00        padding

生バイト列: 00 00 00 00 00 00 00 00 00

応答パケット

Offset  Length  Field
0       2       type = 0x0000 (MNDP)
2       2       sequence number (monotonically increasing per device)
4+      TLV[]   zero or more TLV records (see below)

TLVフォーマット

応答内の各TLV (Type-Length-Value) レコード:

Offset  Length  Field
0       2       type   (little-endian uint16)
2       2       length (little-endian uint16) — byte count of value
4       N       value  (raw bytes — interpretation depends on type)

バイトオーダー: TLVのタイプと長さはリトルエンディアンです。値のエンコーディングはタイプによって異なります。

TLVタイプ参照

Type Hex Name Value Format Notes
1 0x0001 MAC Address 6 bytes, big-endian シャーシMACではなく、インターフェースごとのMAC
5 0x0005 Identity UTF-8 string ホスト名 — すべてのインターフェースで同じ
7 0x0007 Version UTF-8 string 例: 7.18 (stable), 7.22rc1
8 0x0008 Platform UTF-8 string 通常 MikroTik
10 0x000a Board UTF-8 string 例: RB4011iGS+5HacQ2HnD, CHR
11 0x000b Uptime 4 bytes LE uint32 起動からの秒数
12 0x000c Software ID UTF-8 string ライセンス識別子
13 0x000d Board (alt) UTF-8 string 一部のファームウェアはタイプ10の代わりにタイプ13を使用
14 0x000e Unpack 1 byte ファームウェア圧縮フラグ
15 0x000f IPv6 Address 16 bytes リンクローカルまたはグローバルIPv6
16 0x0010 Interface Name UTF-8 string ルーター上の送信インターフェース (例: ether1)
17 0x0011 IPv4 Address 4 bytes, big-endian 送信インターフェースのIP

ボード名: 一部のファームウェアバージョンはTLVタイプ10を使用し、他のバージョンはタイプ13を使用します。パーサーは両方を処理する必要があります — 両方が存在する場合はタイプ10を優先します。

マルチインターフェースの動作

N個のアクティブなインターフェースを持つRouterOSデバイスは、インターフェースごとにN個の個別のMNDPアナウンスを送信します。各アナウンスには以下が含まれます。

  • 異なるMACアドレス (インターフェース自身のMAC)
  • 異なるインターフェース名 (TLV 16)
  • 異なるIPアドレス (割り当てられている場合)
  • 同じID (ホスト名)

これは予期される動作であり、バグではありません。結果を表示する際には、同じルーターがN回表示されるのを避けるために、IDでグループ化してください。IDが工場出荷時のデフォルト (MikroTik) の場合は、MACアドレスを使用して区別してください。

タイミングと信頼性

シナリオ 予想される応答時間
ローカルLAN (有線) 1-3秒
WiFi / 混雑したネットワーク 3-10秒
ZeroTier / トンネルオーバーレイ 5-20秒
衛星 / 高遅延 10-30秒

ベストプラクティス: リッスンウィンドウ中に複数のリフレッシュパケットを送信します (WinBoxの動作に合わせて5秒ごと)。パケットロス、WiFiの省電力、またはトンネルリレーの遅延により最初のブロードキャストを見逃したデバイスは、その後のリフレッシュに応答します。

デバイスが見つからないことをオフラインと決して解釈しないでください。 短いスキャンウィンドウでは部分的な結果しか得られません。デバイスが到達不能であると結論付ける前に、タイムアウトを長くしてください。

RouterOS /ip/neighbor

/ip/neighborは、MNDP (およびCDP/LLDP) 検出結果のRouterOS側のビューです。これは、ルーターが直接接続されたネットワーク上の他のデバイスから受信した情報を表示します。

# 発見されたネイバーを表示
/ip/neighbor/print

# 列: interface, address, mac-address, identity, platform, version, board

/ip/neighbor/discovery-settings

ネイバー検出に参加するインターフェースを制御します。

# 現在の検出設定を表示
/ip/neighbor/discovery-settings/print

# 特定のインターフェースでMNDPを無効にする (セキュリティ強化)
/interface/list/member/add list=no-mndp interface=ether1
/ip/neighbor/discovery-settings/set discover-interface-list=!no-mndp

# サポートされているプロトコル (組み合わせ可能)
# cdp — Cisco Discovery Protocol
# lldp — Link Layer Discovery Protocol
# mndp — MikroTik Neighbor Discovery Protocol
/ip/neighbor/discovery-settings/set protocol=mndp,lldp

REST APIアクセス

# REST経由でネイバーをリスト表示
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

MNDP — MikroTik Neighbor Discovery Protocol

MNDP is the UDP broadcast/multicast protocol that RouterOS uses for automatic device discovery on the local network. It is the same protocol WinBox uses to find routers. Every RouterOS device participates by default.

Why This Matters for Agents

  • /ip/neighbor on RouterOS is the CLI/REST surface for MNDP results
  • WinBox's "Neighbors" tab is an MNDP listener
  • Any agent implementing device discovery for MikroTik equipment needs MNDP
  • The protocol is simple enough to implement from scratch — no library needed

Protocol Basics

Property Value
Transport UDP
Port 5678
IPv4 Broadcast to 255.255.255.255:5678
IPv6 Multicast to ff02::1 (all-nodes link-local)
Direction Bidirectional — same port for send and receive
Authentication None — read-only discovery, no credentials
Scope Layer 2 broadcast domain (does not cross routers)

How Discovery Works

  1. Listener sends a refresh packet — a 9-byte UDP datagram to 255.255.255.255:5678
  2. All RouterOS devices on the LAN reply — each sends a TLV-encoded announcement with identity, version, board, MAC, IP, uptime, etc.
  3. Replies arrive asynchronously — devices respond within milliseconds to seconds depending on network conditions
  4. RouterOS devices also announce periodically (~60s cycle) without being prompted — passive listening works but is slow to populate

Refresh Packet (Discovery Request)

A 9-byte packet that triggers immediate replies from all RouterOS devices on the broadcast domain:

Offset  Length  Value       Field
0       2       0x0000      type (MNDP)
2       2       0x0000      sequence number (0 for request)
4       2       0x0000      TLV type (none)
6       2       0x0000      TLV length (none)
8       1       0x00        padding

As raw bytes: 00 00 00 00 00 00 00 00 00

Response Packet

Offset  Length  Field
0       2       type = 0x0000 (MNDP)
2       2       sequence number (monotonically increasing per device)
4+      TLV[]   zero or more TLV records (see below)

TLV Format

Each TLV (Type-Length-Value) record in the response:

Offset  Length  Field
0       2       type   (little-endian uint16)
2       2       length (little-endian uint16) — byte count of value
4       N       value  (raw bytes — interpretation depends on type)

Byte order: TLV type and length are little-endian. Value encoding varies by type.

TLV Type Reference

Type Hex Name Value Format Notes
1 0x0001 MAC Address 6 bytes, big-endian Per-interface MAC, not chassis MAC
5 0x0005 Identity UTF-8 string Hostname — same across all interfaces
7 0x0007 Version UTF-8 string e.g. 7.18 (stable), 7.22rc1
8 0x0008 Platform UTF-8 string Usually MikroTik
10 0x000a Board UTF-8 string e.g. RB4011iGS+5HacQ2HnD, CHR
11 0x000b Uptime 4 bytes LE uint32 Seconds since boot
12 0x000c Software ID UTF-8 string License identifier
13 0x000d Board (alt) UTF-8 string Some firmware uses type 13 instead of 10
14 0x000e Unpack 1 byte Firmware compression flag
15 0x000f IPv6 Address 16 bytes Link-local or global IPv6
16 0x0010 Interface Name UTF-8 string Sending interface on the router (e.g. ether1)
17 0x0011 IPv4 Address 4 bytes, big-endian IP of the sending interface

Board name: Some firmware versions use TLV type 10, others use type 13. Parsers should handle both — prefer type 10 if both are present.

Multi-Interface Behavior

A RouterOS device with N active interfaces sends N separate MNDP announcements — one per interface. Each announcement has:

  • A different MAC address (the interface's own MAC)
  • A different interface name (TLV 16)
  • A different IP address (if assigned)
  • The same identity (hostname)

This is expected behavior, not a bug. When displaying results, group by identity to avoid showing the same router N times. Use MAC address to disambiguate when the identity is the factory default (MikroTik).

Timing and Reliability

Scenario Expected Response Time
Local LAN (wired) 1-3 seconds
WiFi / congested network 3-10 seconds
ZeroTier / tunnel overlay 5-20 seconds
Satellite / high-latency 10-30 seconds

Best practice: Send multiple refresh packets during the listen window (every 5 seconds, matching WinBox behavior). Devices that miss the first broadcast due to packet loss, WiFi power-save, or tunnel relay latency will respond to subsequent refreshes.

Never interpret missing devices as offline. A short scan window produces partial results. Increase the timeout before concluding a device is unreachable.

RouterOS /ip/neighbor

/ip/neighbor is the RouterOS-side view of MNDP (and CDP/LLDP) discovery results. It shows what the router has heard from other devices on its directly-connected networks.

# Print discovered neighbors
/ip/neighbor/print

# Columns: interface, address, mac-address, identity, platform, version, board

/ip/neighbor/discovery-settings

Controls which interfaces participate in neighbor discovery:

# Show current discovery settings
/ip/neighbor/discovery-settings/print

# Disable MNDP on a specific interface (security hardening)
/interface/list/member/add list=no-mndp interface=ether1
/ip/neighbor/discovery-settings/set discover-interface-list=!no-mndp

# Supported protocols (can be combined)
# cdp — Cisco Discovery Protocol
# lldp — Link Layer Discovery Protocol
# mndp — MikroTik Neighbor Discovery Protocol
/ip/neighbor/discovery-settings/set protocol=mndp,lldp

REST API Access

# List neighbors via REST
curl -u admin: http://<router-ip>/rest/ip/neighbor

# Response is JSON array with the same fields as CLI print

Security Considerations

  • MNDP has no authentication — any device on the broadcast domain can discover routers
  • Disable MNDP on untrusted interfaces (public-facing, guest networks)
  • RouterOS defaults to discovery on all interfaces — review and restrict
  • MNDP reveals: identity (hostname), version, board model, IPs, MACs, uptime
  • This information is useful for attackers — treat MNDP like an open SNMP community

Socket Implementation Notes

Port Sharing (SO_REUSEPORT)

MNDP uses the same port (5678) for both sending and receiving. If another process (e.g., WinBox) already has UDP/5678 bound, your listener needs SO_REUSEPORT to coexist:

// Node.js / Bun dgram
import { createSocket } from "node:dgram";
const sock = createSocket({ type: "udp4", reuseAddr: true, reusePort: true });
sock.bind(5678, "0.0.0.0", () => {
  sock.setBroadcast(true);
});
// C / POSIX
int opt = 1;
setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt));
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &opt, sizeof(opt));

Platform note: SO_REUSEPORT works on macOS and Linux. On Windows, SO_REUSEADDR alone may be sufficient. In Bun, reusePort: true requires Bun >= 1.3.11 (earlier versions silently ignored it on macOS).

Self-Echo Filtering

When you send a broadcast to 255.255.255.255:5678, the OS delivers a copy back to your own socket. Filter out packets from your own IP addresses to avoid processing your own refresh as a neighbor response. The looped-back packet will have no MNDP TLVs (it's your 9-byte refresh, not a device announcement).

IPv6 Multicast

IPv6 MNDP uses ff02::1 (all-nodes multicast). Less commonly used than IPv4 broadcast but supported:

sock.addMembership("ff02::1");

IPv6 link-local addresses include a zone ID (e.g., fe80::1%en0) that identifies the receiving interface — useful topology information not available in IPv4.

Parsing Example (TypeScript)

function parseMndpResponse(buf: Buffer): Record<string, string | number> {
  const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
  let offset = 4; // skip 2-byte type + 2-byte sequence
  const fields: Record<string, string | number> = {};

  while (offset + 4 <= buf.length) {
    const tlvType = view.getUint16(offset, true);     // little-endian
    const tlvLen  = view.getUint16(offset + 2, true);  // little-endian
    offset += 4;

    if (offset + tlvLen > buf.length) break; // malformed
    const value = buf.subarray(offset, offset + tlvLen);

    switch (tlvType) {
      case 1:  // MAC Address — 6 bytes big-endian
        fields.macAddress = [...value].map(b => b.toString(16).padStart(2, "0")).join(":");
        break;
      case 5:  fields.identity = value.toString("utf8"); break;
      case 7:  fields.version = value.toString("utf8"); break;
      case 8:  fields.platform = value.toString("utf8"); break;
      case 10: // Board (primary)
      case 13: // Board (alternate — some firmware)
        if (!fields.board) fields.board = value.toString("utf8");
        break;
      case 11: // Uptime — 4 bytes LE uint32 (seconds)
        fields.uptime = view.getUint32(offset - tlvLen, true);
        break;
      case 12: fields.softwareId = value.toString("utf8"); break;
      case 15: // IPv6 — 16 bytes
        fields.ipv6 = formatIpv6(value);
        break;
      case 16: fields.interfaceName = value.toString("utf8"); break;
      case 17: // IPv4 — 4 bytes big-endian
        fields.ipv4 = `${value[0]}.${value[1]}.${value[2]}.${value[3]}`;
        break;
    }
    offset += tlvLen;
  }
  return fields;
}

Reference Implementations

Language Source Notes
Go github.com/middelink/mikrotik-fwupdate Used as protocol ground truth during original research
Elixir hex.pm mndp package Confirms TLV type IDs
C Various open-source MNDP clients Direct setsockopt for REUSEPORT
Swift Open-source macOS implementations Confirms big-endian MAC encoding

Related Skills

  • For RouterOS CLI/REST basics: see routeros-fundamentals skill
  • For the /console/inspect command tree: see routeros-command-tree skill
  • For packet capture and TZSP streaming: see routeros-sniffer skill
  • For QEMU CHR setup (testing without hardware): see routeros-qemu-chr skill

Related MCP Tools

  • For RouterOS docs lookup: use the rosetta MCP server tools (routeros_search, routeros_get_page)