# 機能設計書 144-inet変換

## 概要

本ドキュメントは、libuvのネットワークユーティリティにおけるIPアドレスのバイナリ・文字列間変換機能 `uv_inet_ntop()` / `uv_inet_pton()` の設計仕様を定義する。

### 本機能の処理概要

`uv_inet_ntop()` はバイナリ形式のIPアドレスを文字列形式に変換（Network to Presentation）し、`uv_inet_pton()` は文字列形式のIPアドレスをバイナリ形式に変換（Presentation to Network）する関数である。POSIXの `inet_ntop()`/`inet_pton()` のクロスプラットフォーム実装を提供する。

**業務上の目的・背景**：POSIXの `inet_ntop()`/`inet_pton()` はWindows環境では直接利用できないか、利用に追加のヘッダーが必要となる場合がある。libuvはこれらの機能をプラットフォーム非依存で提供し、IPv4/IPv6両方のアドレス変換を統一的なインターフェースで実現する。本機能はlibuvの他のネットワーク関数（uv_ip4_addr, uv_ip6_addr, uv_ip4_name, uv_ip6_name等）の基盤として使用される。

**機能の利用シーン**：直接的にはアプリケーションからIPアドレスの形式変換に使用される。また、libuv内部ではuv_ip4_addr/uv_ip6_addr/uv_ip4_name/uv_ip6_name/uv_ip_name等の高レベルAPI実装の基盤として使用される。

**主要な処理内容**：
1. `uv_inet_ntop()`: アドレスファミリに応じてIPv4/IPv6のバイナリデータを文字列に変換
2. `uv_inet_pton()`: アドレスファミリに応じてIPv4/IPv6の文字列をバイナリデータに変換
3. IPv6の::短縮表記、IPv4-mapped IPv6アドレスの処理を含む

**関連システム・外部連携**：libuvの独自実装であり、外部システムへの依存はない。ISC（Internet Systems Consortium）のリファレンス実装がベース。

**権限による制御**：権限による実行可否の制御は存在しない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 29 | その他ユーティリティ | 主機能 | uv_inet_ntop()/inet_pton()によるIPアドレスバイナリ・文字列間変換のAPI定義 |

## 機能種別

データ変換処理（IPアドレスのバイナリ⇔文字列双方向変換）

## 入力仕様

### 入力パラメータ

#### uv_inet_ntop()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| af | int | Yes | アドレスファミリ（AF_INET/AF_INET6） | AF_INET/AF_INET6以外はUV_EAFNOSUPPORT |
| src | const void* | Yes | バイナリIPアドレスへのポインタ | NULLの場合は未定義動作 |
| dst | char* | Yes | 変換結果格納先バッファ | NULLの場合は未定義動作 |
| size | size_t | Yes | dstバッファのサイズ | 不足時UV_ENOSPC |

#### uv_inet_pton()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| af | int | Yes | アドレスファミリ（AF_INET/AF_INET6） | AF_INET/AF_INET6以外はUV_EAFNOSUPPORT |
| src | const char* | Yes | IPアドレス文字列 | NULLの場合UV_EINVAL |
| dst | void* | Yes | バイナリアドレス格納先 | NULLの場合UV_EINVAL |

### 入力データソース

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

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | int | 成功時0、失敗時はlibuvエラーコード |
| dst(ntop) | char* | IPアドレス文字列（IPv4: "x.x.x.x"、IPv6: "x:x::x"形式） |
| dst(pton) | void* | バイナリIPアドレス（struct in_addr / struct in6_addr のサイズ） |

### 出力先

呼び出し元が提供するバッファに結果が格納される。

## 処理フロー

### 処理シーケンス

```
[uv_inet_ntop]
1. アドレスファミリを確認
   ├─ AF_INET → inet_ntop4()を呼び出す
   │   └─ snprintfで "%u.%u.%u.%u" 形式に変換
   │   └─ バッファサイズ不足ならUV_ENOSPCを返却
   ├─ AF_INET6 → inet_ntop6()を呼び出す
   │   └─ 最長ゼロ連続を検出して::短縮表記を適用
   │   └─ IPv4-mapped IPv6アドレスの特別処理
   └─ その他 → UV_EAFNOSUPPORTを返却

[uv_inet_pton]
1. src/dstのNULLチェック → UV_EINVAL
2. アドレスファミリを確認
   ├─ AF_INET → inet_pton4()を呼び出す
   │   └─ ドット区切り10進数4オクテットをパース
   ├─ AF_INET6 → inet_pton6()を呼び出す
   │   └─ '%'によるゾーンインデックスを除去してからパース
   │   └─ コロン区切り16進数をパース（::短縮対応）
   └─ その他 → UV_EAFNOSUPPORTを返却
```

### フローチャート

```mermaid
flowchart TD
    A[uv_inet_pton 呼び出し] --> B{src or dst が NULL?}
    B -->|Yes| C[UV_EINVAL を返却]
    B -->|No| D{af の値}
    D -->|AF_INET| E[inet_pton4 で変換]
    D -->|AF_INET6| F{"'%'を含む?"}
    D -->|その他| G[UV_EAFNOSUPPORT を返却]
    F -->|Yes| H[ゾーンインデックスを除去]
    F -->|No| I[inet_pton6 で変換]
    H --> I
    E --> J{変換成功?}
    I --> J
    J -->|Yes| K[0 を返却]
    J -->|No| L[UV_EINVAL を返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-144-01 | IPv6短縮表記 | ntop変換時、2グループ以上の連続する0を::で短縮する | inet_ntop6で連続ゼロが2以上 |
| BR-144-02 | IPv4-mapped IPv6 | ntop変換時、IPv4-mapped IPv6アドレスは "::ffff:x.x.x.x" 形式で出力 | inet_ntop6で先頭が特定パターン |
| BR-144-03 | ゾーンインデックス除去 | pton変換時、IPv6の'%'以降はパース前に除去される | uv_inet_ptonでAF_INET6かつ'%'を含む |
| BR-144-04 | NULLチェック | uv_inet_ptonはsrc/dstがNULLの場合UV_EINVALを返す | 入力がNULLの場合 |

### 計算ロジック

IPv4: 4バイトを各10進数に変換してドット区切り（ntop）、逆にドット区切り10進数を4バイトに変換（pton）。
IPv6: 8つの16ビットワードを16進数でコロン区切り、最長ゼロランを::短縮（ntop）、逆に16進数コロン区切りを16バイトに変換（pton）。

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UV_EINVAL | 入力エラー | 不正なIPアドレス文字列、またはsrc/dstがNULL | 正しい入力を提供する |
| UV_ENOSPC | バッファ不足 | 出力バッファが結果文字列より小さい | より大きなバッファを用意（IPv4:16, IPv6:46） |
| UV_EAFNOSUPPORT | 非サポート | AF_INET/AF_INET6以外のアドレスファミリ | IPv4/IPv6のみ使用可能 |

### リトライ仕様

リトライは不要。

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

該当なし。

## パフォーマンス要件

O(1)の定数時間（IPv4）、O(1)（IPv6、固定長16バイト処理）。メモリアロケーションなし。

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

- バッファオーバーフローは発生しない（サイズチェック済み）
- 入力のNULLチェックが実装されている（uv_inet_pton）

## 備考

- ISC（Internet Systems Consortium）のリファレンス実装がベース
- libuvの独自実装であり、プラットフォームのinet_ntop/inet_pton関数に依存しない
- `UV__INET_ADDRSTRLEN` は16、`UV__INET6_ADDRSTRLEN` は46として定義

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | uv_inet_ntop()/uv_inet_pton() API宣言（L1787-1788） |

**読解のコツ**: POSIXのinet_ntop/inet_ptonと同じインターフェース設計だが、戻り値がlibuvエラーコード（0成功、負値エラー）である点に注意。

#### Step 2: メイン実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | inet.c | `src/inet.c` | 全変換関数の実装 |

**主要処理フロー**:
1. **25-26行目**: 定数定義 - `UV__INET_ADDRSTRLEN=16`, `UV__INET6_ADDRSTRLEN=46`
2. **35-45行目**: `uv_inet_ntop()` - アドレスファミリでswitch分岐
3. **48-59行目**: `inet_ntop4()` - snprintfによるIPv4文字列化。tmpバッファに変換後、サイズチェックしてからdstにコピー
4. **62-143行目**: `inet_ntop6()` - ワード配列への変換(L80-82)、最長ゼロラン検出(L83-106)、::短縮適用(L112-138)、IPv4-mapped特殊処理(L124-131)
5. **146-172行目**: `uv_inet_pton()` - NULLチェック(L147-148)後、アドレスファミリ分岐。IPv6はゾーンインデックス('%')除去(L157-164)
6. **175-211行目**: `inet_pton4()` - ドット区切り10進数のパース。先頭0拒否(L189-190)、値範囲検証(L191-192)
7. **214-298行目**: `inet_pton6()` - コロン区切り16進数パース、::展開、IPv4-in-IPv6対応

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

```
uv_inet_ntop(af, src, dst, size)            [公開API - src/inet.c L35]
    ├─ inet_ntop4(src, dst, size)            [内部関数 - src/inet.c L48]
    │     └─ snprintf()
    └─ inet_ntop6(src, dst, size)            [内部関数 - src/inet.c L62]
          └─ inet_ntop4() [IPv4-mapped時]

uv_inet_pton(af, src, dst)                  [公開API - src/inet.c L146]
    ├─ inet_pton4(src, dst)                  [内部関数 - src/inet.c L175]
    └─ inet_pton6(src, dst)                  [内部関数 - src/inet.c L214]
          └─ inet_pton4() [IPv4-in-IPv6時]
```

### データフロー図

```
[ntop: バイナリ→文字列]
バイナリアドレス(void*) ──▶ uv_inet_ntop() ──▶ 文字列(char*)
                             ├─ inet_ntop4: "%u.%u.%u.%u"
                             └─ inet_ntop6: "x:x::x" (::短縮)

[pton: 文字列→バイナリ]
文字列(const char*) ──▶ uv_inet_pton() ──▶ バイナリアドレス(void*)
                          ├─ inet_pton4: ドット区切り解析
                          └─ inet_pton6: コロン区切り解析
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダー | API宣言 (L1787-1788) |
| inet.c | `src/inet.c` | ソース | 全変換関数の実装（ISCベース） |
| uv-common.h | `src/uv-common.h` | ヘッダー | ARRAY_SIZEマクロ等の内部定義 |
