# 帳票設計書 27-ifmcstat - マルチキャスト統計レポート

## 概要

本ドキュメントは、FreeBSDのifmcstatコマンドが出力するマルチキャスト統計レポートの帳票設計書である。ifmcstatはネットワークインターフェースごとのマルチキャストグループメンバーシップ情報をダンプする。

### 本帳票の処理概要

ifmcstatコマンドは、getifmaddrs(3)システムコールおよびsysctl経由でカーネルからマルチキャストグループ情報を取得し、インターフェースごとにグループアドレスとフィルタモード、ソースリストを表示する。IGMP（IPv4）とMLD（IPv6）の両方に対応する。

**業務上の目的・背景**：マルチキャストネットワークの管理において、各インターフェースがどのマルチキャストグループに参加しているかを把握することは、マルチキャストルーティングの設定確認やトラブルシューティングに必要不可欠である。

**帳票の利用シーン**：マルチキャストグループメンバーシップの確認、IGMPv3/MLDv2のソースフィルタリング状態確認、マルチキャスト関連の障害解析、ネットワーク構成の監査などで使用される。

**主要な出力内容**：
1. インターフェース名
2. プライマリアドレス（inet/inet6/link）
3. IGMP/MLDバージョンとフラグ
4. マルチキャストグループアドレス
5. フィルタモード（include/exclude）
6. ソースアドレスリスト（-v時）
7. リンク層マルチキャストアドレス

**帳票の出力タイミング**：コマンドラインからifmcstatコマンドを実行した時点で即座に出力される。

**帳票の利用者**：ネットワーク管理者、マルチキャスト運用担当者

## 帳票種別

一覧表（テキスト形式の階層出力）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| N/A | コマンドライン | ターミナル | `ifmcstat [-i interface] [-f family] [-v]` 実行 |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | テキスト（標準出力） |
| 用紙サイズ | N/A（ターミナル出力） |
| 向き | N/A |
| ファイル名 | N/A（標準出力） |
| 出力方法 | 標準出力（stdout） |
| 文字コード | ASCII |

## 帳票レイアウト

### レイアウト概要

```
┌─────────────────────────────────────────┐
│ em0:                                    │
│     inet 192.168.1.1                    │
│     igmpv3 flags=<SILENT> rv 2 qi ...   │
│         group 224.0.0.1 mode exclude    │
│         group 239.1.1.1 mode include    │
│             mcast-macaddr 01:00:5e:...  │
│     inet6 fe80::1%em0                   │
│     mldv2 flags=<> rv 2 qi ...          │
│         group ff02::1 mode exclude      │
│ lo0:                                    │
│     ...                                 │
└─────────────────────────────────────────┘
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | インターフェース名 | ネットワークインターフェース | ifmaddrs.ifma_name | "%s:\n" |

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | アドレスファミリ | inet/inet6/link | sockaddr.sa_family | "\t%s %s\n" | タブインデント |
| 2 | プライマリアドレス | IPアドレス | getnameinfo() | 文字列 | 可変 |
| 3 | IGMP/MLDバージョン | igmpv1/v2/v3, mldv1/v2 | igmp_ifinfo/mld_ifinfo | "\tigmpv%d" | タブインデント |
| 4 | フラグ | SILENT, LOOPBACK等 | igi_flags/mli_flags | printb形式 | 可変 |
| 5 | グループアドレス | マルチキャストグループ | ifma_addr | "\t\tgroup %s" | 2タブインデント |
| 6 | フィルタモード | include/exclude | sysctl取得 | "mode %s" | 可変 |
| 7 | ソースアドレス | ソースフィルタリスト | sysctl取得 | "srcs %s,..." | 可変 |
| 8 | MACアドレス | リンク層マルチキャスト | ifma_lladdr | "\t\t\tmcast-macaddr %s" | 3タブインデント |

### フッター部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| N/A | なし | フッターは出力されない | - | - |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| -i interface | 特定インターフェースのみ | No |
| -f family | アドレスファミリでフィルタ（inet/inet6/link） | No |
| -v | 詳細モード（ソースリスト、タイマー情報） | No |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | インターフェースインデックス | システム順 |

### 改ページ条件

テキスト出力のため改ページなし。

## データベース参照仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| getifmaddrs() | マルチキャストアドレス一覧 | なし |
| getifaddrs() | インターフェースアドレス一覧 | インターフェース名で結合 |
| net.inet.igmp.ifinfo（sysctl） | IGMP per-interface情報 | ifindexで指定 |
| net.inet6.mld.ifinfo（sysctl） | MLD per-interface情報 | ifindexで指定 |
| net.inet.ip.mcast.filters（sysctl） | IPv4ソースフィルタ | ifindex + group address |
| net.inet6.ip6.mcast.filters（sysctl） | IPv6ソースフィルタ | ifindex + group address |

### テーブル別参照項目詳細

#### net.inet.igmp.ifinfo（sysctl）

| 参照項目（カラム名） | 帳票項目との対応 | 取得条件 | 備考 |
|-------------------|----------------|---------|------|
| igi_version | IGMPバージョン | ifindex指定 | 1, 2, 3 |
| igi_flags | フラグ | ifindex指定 | SILENT, LOOPBACK |
| igi_rv | Robustness Variable | ifindex指定 | -v時のみ表示 |
| igi_qi | Query Interval | ifindex指定 | -v時のみ表示 |
| igi_qri | Query Response Interval | ifindex指定 | -v時のみ表示 |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| N/A | 計算項目なし | - | カーネルから取得した値を表示 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[コマンド実行] --> B[getopt - オプション解析]
    B --> C[ifmcstat_getifmaddrs]
    C --> D[getifaddrs - IF一覧取得]
    D --> E[getifmaddrs - マルチキャスト一覧取得]
    E --> F[IFごとにループ]
    F --> G[プライマリアドレス表示]
    G --> H{IPv4?}
    H -->|Yes| I[IGMP情報表示 + ソースフィルタ]
    H -->|No| J{IPv6?}
    J -->|Yes| K[MLD情報表示 + ソースフィルタ]
    J -->|No| L[次のグループ]
    I --> L
    K --> L
    L --> F
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| IF未検出 | 指定インターフェース不存在 | "unknown interface" | 正しいIF名を指定 |
| getifmaddrs失敗 | システムコール失敗 | warn出力 | システム状態を確認 |
| sysctl失敗 | IGMP/MLD情報取得失敗 | perror出力 | カーネルのIGMP/MLD対応確認 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 数十〜数百マルチキャストグループ |
| 目標出力時間 | 即時（ミリ秒単位） |
| 同時出力数上限 | 制限なし |

## セキュリティ考慮事項

- 一般ユーザーでも参照可能
- マルチキャストグループメンバーシップ情報からネットワーク構成が推測される可能性

## 備考

- KVMモード（-K）は現在破損しており、使用不可（ソースコードのコメントに記載）
- getifmaddrs()ベースのsysctlバックエンドがデフォルトで使用される
- IGMPv3/MLDv2のソースフィルタリング情報は-vオプションで表示される
- KAME由来のコード（ifmcstat.c先頭のコメント参照）

---

## コードリーディングガイド

本帳票を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ifmcstat.c | `usr.sbin/ifmcstat/ifmcstat.c` | sockunion_t共用体（行97-108）: sockaddr_storage/sockaddr/sockaddr_dl/sockaddr_in/sockaddr_in6を統合 |
| 1-2 | ifmcstat.c | `usr.sbin/ifmcstat/ifmcstat.c` | グローバル変数: ifindex（行110）、af（行111）、vflag（行115）がフィルタ条件 |

**読解のコツ**: このコードはKAME由来で比較的古いスタイル。#ifdef INET/#ifdef INET6で条件コンパイルが多用される。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ifmcstat.c | `usr.sbin/ifmcstat/ifmcstat.c` | main()関数（行190-276）。getopt()でオプション解析後、ifmcstat_getifmaddrs()を呼び出す |

**主要処理フロー**:
1. **行199-256**: getopt()による-i, -f, -vオプション解析
2. **行258-259**: AF_LINKとvflagの組み合わせチェック
3. **行270**: ifmcstat_getifmaddrs()呼び出し（メイン処理）
4. **行271-274**: エラーチェックと終了

#### Step 3: マルチキャスト情報収集を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ifmcstat.c | `usr.sbin/ifmcstat/ifmcstat.c` | ifmcstat_getifmaddrs()関数（行981-1245）。getifaddrs()/getifmaddrs()で情報取得し、インターフェースごとにIGMP/MLD情報とグループ一覧を表示 |
| 3-2 | ifmcstat.c | `usr.sbin/ifmcstat/ifmcstat.c` | in_ifinfo()関数（行281-306）: IGMP per-interface情報表示 |
| 3-3 | ifmcstat.c | `usr.sbin/ifmcstat/ifmcstat.c` | in6_ifinfo()関数（行738-763）: MLD per-interface情報表示 |
| 3-4 | ifmcstat.c | `usr.sbin/ifmcstat/ifmcstat.c` | inm_print_sources_sysctl()関数（行791-873）: IPv4ソースフィルタ取得・表示 |
| 3-5 | ifmcstat.c | `usr.sbin/ifmcstat/ifmcstat.c` | in6m_print_sources_sysctl()関数（行888-978）: IPv6ソースフィルタ取得・表示 |

### プログラム呼び出し階層図

```
main() [ifmcstat.c 行190]
    │
    ├─ getopt() - オプション解析 [行199]
    │
    └─ ifmcstat_getifmaddrs() [行981]
           │
           ├─ getifaddrs() - IF一覧取得 [行1002]
           ├─ getifmaddrs() - マルチキャスト一覧取得 [行1007]
           │
           └─ IFごとのループ [行1013]
                  │
                  ├─ getnameinfo() - アドレス表示
                  │
                  ├─ in_ifinfo() [行281] - IGMP情報（IPv4時）
                  │      └─ sysctl("net.inet.igmp.ifinfo")
                  │
                  ├─ in6_ifinfo() [行738] - MLD情報（IPv6時）
                  │      └─ sysctl("net.inet6.mld.ifinfo")
                  │
                  ├─ inm_print_sources_sysctl() [行791] - IPv4ソース
                  │      └─ sysctl("net.inet.ip.mcast.filters")
                  │
                  └─ in6m_print_sources_sysctl() [行888] - IPv6ソース
                         └─ sysctl("net.inet6.ip6.mcast.filters")
```

### データフロー図

```
[入力]                       [処理]                      [出力]

getifaddrs()            ───▶ IF一覧取得             ──┐
getifmaddrs()           ───▶ マルチキャスト一覧取得   ──┤
                                                      ▼
net.inet.igmp.ifinfo    ───▶ IGMP情報取得          ──▶ IF名:
net.inet6.mld.ifinfo    ───▶ MLD情報取得           ──▶   アドレス
                                                        IGMP/MLD info
net.inet.ip.mcast.      ───▶ ソースフィルタ取得     ──▶   group アドレス
  filters                                                mode + srcs
net.inet6.ip6.mcast.    ───▶ ソースフィルタ取得     ──▶   mcast-macaddr
  filters
                                                      ▼
                                                 標準出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ifmcstat.c | `usr.sbin/ifmcstat/ifmcstat.c` | ソース | 全ロジック（1246行の単一ファイル） |
| Makefile | `usr.sbin/ifmcstat/Makefile` | ビルド | ビルド設定 |
