# 機能設計書 146-インターフェース名変換

## 概要

本ドキュメントは、libuvのネットワークユーティリティにおけるインターフェースインデックスと名前の変換機能 `uv_if_indextoname()` / `uv_if_indextoiid()` の設計仕様を定義する。

### 本機能の処理概要

`uv_if_indextoname()` はネットワークインターフェースのインデックス番号から名前文字列に変換し、`uv_if_indextoiid()` はインデックスからインターフェース識別子（IID）に変換する関数である。Unix系では `uv_if_indextoiid()` は `uv_if_indextoname()` と同一の処理を行う。

**業務上の目的・背景**：IPv6のスコープ付きアドレス（リンクローカルアドレス等）では、アドレスにインターフェース識別情報（ゾーンID）を付加する必要がある。OSによってはインターフェースをインデックス番号で管理しており、人間が読める名前への変換が必要となる。本機能はこの変換をクロスプラットフォームで提供する。

**機能の利用シーン**：IPv6リンクローカルアドレスにゾーンIDを付加する際のインターフェース名解決、ネットワーク構成情報の表示、UDPマルチキャストのインターフェース指定などに使用される。

**主要な処理内容**：
1. インターフェースインデックスを受け取る
2. POSIX `if_indextoname()` を呼び出してインデックスから名前を取得する
3. 結果をユーザー提供バッファにコピーする
4. `uv_if_indextoiid()` は `uv_if_indextoname()` に委譲する（Unix系）

**関連システム・外部連携**：POSIX `if_indextoname()` システムコールに依存する。

**権限による制御**：一般ユーザー権限で実行可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 29 | その他ユーティリティ | 主機能 | uv_if_indextoname()/if_indextoiid()のAPI定義 |

## 機能種別

データ変換処理（インターフェースインデックス→名前変換）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ifindex | unsigned int | Yes | インターフェースインデックス番号 | 有効なインデックスであること |
| buffer | char* | Yes | 結果格納先バッファ | NULLの場合UV_EINVAL |
| size | size_t* | Yes | バッファサイズ（入出力） | NULLの場合UV_EINVAL、*size==0の場合UV_EINVAL |

### 入力データソース

呼び出し元から直接渡されるパラメータ。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | int | 成功時0、失敗時はlibuvエラーコード |
| buffer | char* | インターフェース名文字列（NULL終端） |
| *size | size_t | 実際の名前文字列長（NULL終端を含まない） |

### 出力先

呼び出し元が提供するバッファに文字列が格納される。sizeにはバッファ不足時に必要なサイズ、成功時に実際の文字列長が返される。

## 処理フロー

### 処理シーケンス

```
[uv_if_indextoname]
1. 入力パラメータのバリデーション
   └─ buffer==NULL or size==NULL or *size==0 → UV_EINVAL
2. if_indextoname(ifindex, ifname_buf) を呼び出す
   └─ 失敗時は UV__ERR(errno) を返却
3. 結果文字列の長さを計算
4. バッファサイズチェック
   └─ *size <= len の場合: *size = len + 1, UV_ENOBUFS を返却
5. バッファにコピー + NULL終端
6. *size = len として成功 (0) を返却

[uv_if_indextoiid]
1. uv_if_indextoname() に委譲
```

### フローチャート

```mermaid
flowchart TD
    A[uv_if_indextoname 呼び出し] --> B{buffer/size/size==0?}
    B -->|いずれかNG| C[UV_EINVAL を返却]
    B -->|OK| D[if_indextoname 呼び出し]
    D --> E{成功?}
    E -->|No| F[UV__ERR errno を返却]
    E -->|Yes| G[文字列長を計算]
    G --> H{"*size <= len?"}
    H -->|Yes| I["*size = len+1, UV_ENOBUFS を返却"]
    H -->|No| J[buffer にコピー + NULL終端]
    J --> K["*size = len, 0 を返却"]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-146-01 | バッファサイズ通知 | バッファ不足時は*sizeに必要なサイズ(len+1)を設定してUV_ENOBUFSを返す | *size <= lenの場合 |
| BR-146-02 | IID同一性 | Unix系ではuv_if_indextoiid()はuv_if_indextoname()と同じ結果を返す | Unix系プラットフォーム |
| BR-146-03 | UV_IF_NAMESIZE | 内部バッファサイズはUV_IF_NAMESIZE（16+1=17バイト）で定義 | 常時 |

### 計算ロジック

特になし。

## データベース操作仕様

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UV_EINVAL | 入力エラー | buffer/sizeがNULL、または*sizeが0 | 有効なパラメータを指定する |
| UV_ENOBUFS | バッファ不足 | バッファサイズが名前文字列長以下 | *sizeに返された値以上のバッファを用意する |
| UV__ERR(errno) | システムエラー | if_indextoname()が失敗（不正なインデックス等） | 有効なインターフェースインデックスを指定する |

### リトライ仕様

バッファ不足の場合は*sizeの値を使って適切なサイズで再試行可能。

## トランザクション仕様

該当なし。

## パフォーマンス要件

OS APIへの1回の呼び出しで完了する。O(1)の定数時間。

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

- インターフェース名にはセキュリティ上のリスクはない
- バッファオーバーフローは発生しない（サイズチェック済み）

## 備考

- `UV_IF_NAMESIZE` はプラットフォームによって異なるが、未定義の場合はデフォルト17バイト（16+1）
- Windows版では `uv_if_indextoiid()` は異なる実装（インデックス番号を文字列化）を持つ可能性がある

---

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

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

### 推奨読解順序

#### Step 1: API宣言と定数を確認する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | API宣言（L1818-1823）とUV_IF_NAMESIZE定義（L1815） |

**読解のコツ**: UV_IF_NAMESIZEはプラットフォーム固有のIF_NAMESIZEまたはデフォルト17バイト。

#### Step 2: Unix実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | getaddrinfo.c | `src/unix/getaddrinfo.c` | uv_if_indextoname()/uv_if_indextoiid() 実装 |

**主要処理フロー**:
1. **231-253行目**: `uv_if_indextoname()` - NULLチェック(L235-236)、if_indextoname()呼び出し(L238)、strnlenで長さ計算(L241)、サイズチェック(L243-245)、memcpyでコピー(L248-250)
2. **255-257行目**: `uv_if_indextoiid()` - `uv_if_indextoname()` に直接委譲する1行実装

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

```
uv_if_indextoname(ifindex, buffer, size)   [公開API - src/unix/getaddrinfo.c L231]
    ├─ パラメータバリデーション
    ├─ if_indextoname()                     [POSIX API]
    ├─ strnlen()
    └─ memcpy()

uv_if_indextoiid(ifindex, buffer, size)    [公開API - src/unix/getaddrinfo.c L255]
    └─ uv_if_indextoname()                 [公開API]
```

### データフロー図

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

unsigned int ifindex ──▶ uv_if_indextoname()      ──▶ char* buffer (名前文字列)
size_t* size ──────▶   ├─ if_indextoname()             size_t* size (実際の長さ)
                        ├─ strnlen()                   int 戻り値
                        └─ memcpy()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダー | API宣言 (L1818-1823)、UV_IF_NAMESIZE定義 (L1815) |
| getaddrinfo.c | `src/unix/getaddrinfo.c` | ソース | Unix版実装 (L231-257) |
| getaddrinfo.c | `src/win/getaddrinfo.c` | ソース | Windows版実装 |
