# 帳票設計書 5-netstat - ネットワーク統計レポート

## 概要

本ドキュメントは、FreeBSDシステムにおけるネットワーク統計レポート(netstat)の帳票設計書である。netstatコマンドはネットワークソケット、ルーティングテーブル、インターフェース統計、プロトコル統計、マルチキャストルーティング、BPF統計、netisrキュー情報などの多岐にわたるネットワーク関連情報をテキスト形式またはlibxo形式で出力する。

### 本帳票の処理概要

**業務上の目的・背景**：ネットワーク管理者がシステムのネットワーク接続状況、プロトコル統計、ルーティング情報を把握し、ネットワーク障害の診断やセキュリティ監査に必要なレポートである。

**帳票の利用シーン**：アクティブなネットワーク接続の確認、プロトコル別の統計分析、ルーティングテーブルの確認、インターフェースの通信量監視、マルチキャスト経路の確認、ネットワーク障害のトラブルシューティング。

**主要な出力内容**：
1. ソケット一覧（デフォルト）：プロトコル、受信/送信キュー長、ローカル/リモートアドレス、状態
2. インターフェース統計（-i）：MTU、パケット数、バイト数、エラー、ドロップ
3. ルーティングテーブル（-r）：宛先、ゲートウェイ、フラグ、参照数、インターフェース
4. プロトコル統計（-s）：TCP/UDP/IP/ICMP等のプロトコル別詳細統計
5. マルチキャスト情報（-g）
6. メモリ使用統計（-m）
7. netisrキュー統計（-Q）
8. BPF統計（-B）

**帳票の出力タイミング**：コマンド実行で即時出力。-wオプションで定期的なインターフェース統計出力。

**帳票の利用者**：ネットワーク管理者、セキュリティ管理者、システム管理者。

## 帳票種別

一覧表/集計表（テキスト/libxo形式のネットワーク統計レポート）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| N/A | ターミナル/コンソール | N/A | `netstat [-46AaBCcdhIijLlMmNnOoPpQRrSTsuWwxz] [-f protocol_family] [-p protocol] [-M core] [-N system]` コマンド実行 |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | テキスト（標準出力）またはlibxo形式 |
| 用紙サイズ | N/A |
| 向き | N/A |
| ファイル名 | N/A |
| 出力方法 | 標準出力への直接出力（xo_emit使用） |
| 文字コード | ASCII |

## 帳票レイアウト

### レイアウト概要

主に8つのモードがあり、それぞれ異なるレイアウトで出力する。

### 明細部（ソケット一覧: デフォルト）

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | Proto | プロトコル名 | protox配列 | 文字列 | 可変 |
| 2 | Recv-Q | 受信キュー長 | ソケットバッファ | 整数 | 6桁 |
| 3 | Send-Q | 送信キュー長 | ソケットバッファ | 整数 | 6桁 |
| 4 | Local Address | ローカルアドレス:ポート | ソケット構造体 | IP:ポート | 可変 |
| 5 | Foreign Address | リモートアドレス:ポート | ソケット構造体 | IP:ポート | 可変 |
| 6 | (state) | TCP状態 | TCP PCB | 文字列 | 可変 |

### 明細部（インターフェース統計: -iオプション）

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | Name | インターフェース名 | if_data | 文字列 |
| 2 | Mtu | MTU | if_data.ifi_mtu | 整数 |
| 3 | Network | ネットワークアドレス | if_addr | IP/マスク |
| 4 | Address | インターフェースアドレス | if_addr | IP |
| 5 | Ipkts | 受信パケット数 | if_data.ifi_ipackets | 整数 |
| 6 | Ierrs | 受信エラー数 | if_data.ifi_ierrors | 整数 |
| 7 | Opkts | 送信パケット数 | if_data.ifi_opackets | 整数 |
| 8 | Oerrs | 送信エラー数 | if_data.ifi_oerrors | 整数 |
| 9 | Coll | 衝突数 | if_data.ifi_collisions | 整数 |
| 10 | Drop | ドロップ数 | if_data.ifi_iqdrops | 整数 |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| プロトコルファミリ（-f） | inet, inet6, unix, link, pfkey, netgraph | No |
| プロトコル（-p） | tcp, udp, icmp等の特定プロトコル | No |
| インターフェース（-I） | 特定インターフェースのみ | No |
| アドレスファミリ（-4/-6） | IPv4/IPv6限定 | No |
| FIB番号（-F） | 特定FIBのルーティングテーブル | No |
| Jail（-j） | 特定Jail内のネットワーク情報 | No |

### ソート順

出力モードに依存（ソケットはプロトコル順、ルーティングはルート順）

### 改ページ条件

改ページ機能なし（-wオプション時はインターバルごとに出力）

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

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| net.inet.tcp.pcblist (sysctl) | TCP PCB一覧 | プロトコル指定 |
| net.inet.udp.pcblist (sysctl) | UDP PCB一覧 | プロトコル指定 |
| net.inet.*.stats (sysctl) | プロトコル統計 | -sオプション |
| net.route.0.*.dump (sysctl) | ルーティングテーブル | -rオプション |
| net.link.generic.ifdata (sysctl) | インターフェースデータ | -iオプション |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| インターフェーストラフィック | packets差分 / interval | 整数 | -wオプション時 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[コマンド実行] --> B[xo_parse_args]
    B --> C[getoptでオプション解析]
    C --> D{出力モード判定}
    D -->|B| E[bpf_stats: BPF統計]
    D -->|m| F[mbpr: メモリ統計]
    D -->|Q| G[netisr_stats: netisrキュー]
    D -->|i && !s| H[intpr: インターフェース統計]
    D -->|r| I[routepr/rt_stats: ルーティング]
    D -->|o| J[nhops_print: nexthop]
    D -->|O| K[nhgrp_print: nexthopグループ]
    D -->|g| L[mroutepr/mrt_stats: マルチキャスト]
    D -->|default| M[protox配列走査 printproto]
    M --> N{sflag?}
    N -->|Yes| O[pr_stats: プロトコル統計出力]
    N -->|No| P[pr_cblocks: PCB一覧出力]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| Jail未発見 | -jで指定Jailが存在しない | xo_errx(EX_UNAVAILABLE, "Jail not found") | Jail名確認 |
| -xと-Tの競合 | 両方指定 | xo_errx(EX_USAGE, "-x and -T are incompatible") | 片方のみ使用 |
| sysctl失敗 | 統計取得失敗 | xo_warn("sysctl %s", ...) | カーネル対応確認 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | ソケット数、ルート数、インターフェース数に依存 |
| 目標出力時間 | リアルタイム出力 |
| 同時出力数上限 | N/A |

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

- 一般ユーザーでも基本的な統計は取得可能
- -Aオプション（PCBアドレス表示）はカーネルメモリ情報の露出リスクあり
- -jオプション（Jail指定）はjail_attach権限が必要
- -zオプション（統計リセット）はroot権限が必要

## 備考

- protox構造体配列でプロトコルごとの処理関数（統計/PCB表示）をテーブル駆動で管理（69-128行目）
- INET6, IPSEC, SCTP, SDP, NETGRAPH, PFはコンパイル時条件付き
- live変数（462行目）でカーネルライブ/コアダンプの切り替え
- NETSTAT_XO_VERSIONでlibxo出力バージョン管理

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | main.c | `usr.bin/netstat/main.c` | 69-128行目: protox構造体配列。各プロトコルの印刷ルーチン（pr_cblocks, pr_stats, pr_istats）をテーブル駆動で管理 |
| 1-2 | netstat.h | `usr.bin/netstat/netstat.h` | 関数プロトタイプ集。各プロトコル統計関数の宣言 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | main.c | `usr.bin/netstat/main.c` | 240-621行目: main関数。40種類以上のオプション解析とモード分岐 |

**主要処理フロー**:
1. **258行目**: 非常に長いgetopt文字列で40以上のフラグを解析
2. **462行目**: live変数でライブ/コアダンプモード判定
3. **470-550行目**: 各モード(-B, -m, -Q, -i, -r, -o, -O, -g)のディスパッチ
4. **590-617行目**: デフォルトモード（プロトコルテーブル走査）

#### Step 3: プロトコル出力処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | main.c | `usr.bin/netstat/main.c` | 668-728行目: printproto関数。protox配列に基づくプロトコル別出力ディスパッチ |

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

```
main() [240行目]
    |
    +-- bpf_stats() ... -Bモード
    +-- mbpr() ... -mモード
    +-- netisr_stats() ... -Qモード
    +-- intpr() ... -iモード（インターフェース）
    +-- routepr() / rt_stats() ... -rモード（ルーティング）
    +-- nhops_print() ... -oモード
    +-- nhgrp_print() ... -Oモード
    +-- mroutepr() / mrt_stats() ... -gモード
    +-- printproto() [668行目] ... デフォルトモード
    |      +-- pr_cblocks() (protopr等) ... PCB一覧
    |      +-- pr_stats() (tcp_stats等) ... プロトコル統計
    +-- unixpr() ... UNIXドメインソケット
```

### データフロー図

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

net.inet.*.pcblist (sysctl) ──▶ protopr()              ──▶ 標準出力
net.inet.*.stats (sysctl) ───▶ tcp_stats()/udp_stats()      (xo_emit)
net.route.*.dump (sysctl) ───▶ routepr()
net.link.*.ifdata (sysctl) ──▶ intpr()
カーネルメモリ (kvm) ─────────▶ kread()/kread_counter()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| main.c | `usr.bin/netstat/main.c` | ソース | エントリーポイント、オプション解析 |
| netstat.h | `usr.bin/netstat/netstat.h` | ヘッダ | 関数プロトタイプ、グローバル変数宣言 |
| nl_defs.h | `usr.bin/netstat/nl_defs.h` | ヘッダ | nlistインデックス定義 |
| inet.c | `usr.bin/netstat/inet.c` | ソース | IPv4プロトコル統計 |
| inet6.c | `usr.bin/netstat/inet6.c` | ソース | IPv6プロトコル統計 |
| route.c | `usr.bin/netstat/route.c` | ソース | ルーティングテーブル表示 |
| if.c | `usr.bin/netstat/if.c` | ソース | インターフェース統計 |
| unix.c | `usr.bin/netstat/unix.c` | ソース | UNIXドメインソケット |
| mroute.c | `usr.bin/netstat/mroute.c` | ソース | マルチキャストルーティング |
| bpf.c | `usr.bin/netstat/bpf.c` | ソース | BPF統計 |
| netisr.c | `usr.bin/netstat/netisr.c` | ソース | netisrキュー統計 |
| nhops.c | `usr.bin/netstat/nhops.c` | ソース | nexthop表示 |
| nhgrp.c | `usr.bin/netstat/nhgrp.c` | ソース | nexthopグループ表示 |
| mbuf.c | `usr.bin/netstat/mbuf.c` | ソース | メモリバッファ統計 |
