# 機能設計書 145-インターフェースアドレス取得

## 概要

本ドキュメントは、libuvのネットワークユーティリティにおけるネットワークインターフェースアドレス一覧取得・解放機能 `uv_interface_addresses()` / `uv_free_interface_addresses()` の設計仕様を定義する。

### 本機能の処理概要

`uv_interface_addresses()` は、システムに存在するすべてのネットワークインターフェースのアドレス情報（IPアドレス、ネットマスク、MACアドレス等）を取得する。`uv_free_interface_addresses()` は取得した情報のメモリを解放する。

**業務上の目的・背景**：ネットワークアプリケーションでは、サーバーがバインドすべきアドレスの自動検出、ネットワーク構成の表示、マルチホーム環境でのインターフェース選択など、システムのネットワークインターフェース情報が必要となる場面がある。本機能はこれらの情報をクロスプラットフォームで統一的に取得する手段を提供する。

**機能の利用シーン**：利用可能なネットワークインターフェースの列挙、サーバーバインドアドレスの自動決定、ネットワーク診断ツールの実装、IPv4/IPv6デュアルスタック環境でのアドレス確認などに使用される。

**主要な処理内容**：
1. OS固有のAPIでネットワークインターフェース情報を取得する
2. ループバック、無効なインターフェースをフィルタリングする
3. 各インターフェースのIPアドレス、ネットマスク、MACアドレス、内部フラグを構造体配列に格納する
4. 取得した結果のメモリを解放する関数を提供する

**関連システム・外部連携**：Unix系では `getifaddrs()` POSIX API、Linux固有では `/proc` ファイルシステム、Windows系では独自のAPI群を使用する。

**権限による制御**：一般ユーザー権限で実行可能。ただし一部のOS設定によりインターフェース情報の取得が制限される場合がある。

## 関連画面

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

## 機能種別

情報取得処理（システムネットワーク情報のリードオンリー参照）

## 入力仕様

### 入力パラメータ

#### uv_interface_addresses()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| addresses | uv_interface_address_t** | Yes | 結果配列のポインタ格納先 | NULLの場合は未定義動作 |
| count | int* | Yes | 結果配列の要素数格納先 | NULLの場合は未定義動作 |

#### uv_free_interface_addresses()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| addresses | uv_interface_address_t* | Yes | 解放対象の配列ポインタ | NULLの場合はnoop |
| count | int | Yes | 配列の要素数 | 非負整数 |

### 入力データソース

OSのネットワークインターフェース情報。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | int | 成功時0、失敗時はlibuvエラーコード |
| addresses | uv_interface_address_t* | インターフェース情報の配列 |
| count | int | 配列の要素数 |

#### uv_interface_address_t 構造体

| フィールド | 型 | 説明 |
|-----------|-----|------|
| name | char* | インターフェース名（例: "eth0", "lo"） |
| phys_addr | char[6] | MACアドレス（6バイト） |
| is_internal | int | ループバックインターフェースの場合1 |
| address.address4 | struct sockaddr_in | IPv4アドレス |
| address.address6 | struct sockaddr_in6 | IPv6アドレス |
| netmask.netmask4 | struct sockaddr_in | IPv4ネットマスク |
| netmask.netmask6 | struct sockaddr_in6 | IPv6ネットマスク |

### 出力先

呼び出し元が提供するポインタを介してヒープメモリ上の配列が返却される。

## 処理フロー

### 処理シーケンス

```
[uv_interface_addresses - BSD/macOS版]
1. count=0, addresses=NULLで初期化
2. getifaddrs()でインターフェース情報を取得
   └─ 失敗時はUV__ERR(errno)を返却
3. フィルタリングループ（1回目）
   └─ 各インターフェースに対してuv__ifaddr_exclude()で除外判定
   └─ 有効なインターフェースの数とname長をカウント
4. メモリ確保（uv__calloc）
   └─ count * sizeof(uv_interface_address_t) + 名前文字列領域
5. データ格納ループ（2回目）
   └─ 名前、IPv4/IPv6アドレス、ネットマスク、is_internalフラグを格納
6. MACアドレス格納ループ（3回目、BSD系のみ）
   └─ AF_LINKのエントリからphys_addrを取得
7. freeifaddrs()で一時データを解放
8. 0を返却
```

### フローチャート

```mermaid
flowchart TD
    A[uv_interface_addresses 呼び出し] --> B[getifaddrs でインターフェース取得]
    B --> C{取得成功?}
    C -->|No| D[UV__ERR errno を返却]
    C -->|Yes| E[有効インターフェースをカウント]
    E --> F{count == 0?}
    F -->|Yes| G[freeifaddrs して 0 を返却]
    F -->|No| H[uv__calloc でメモリ確保]
    H --> I{確保成功?}
    I -->|No| J[UV_ENOMEM を返却]
    I -->|Yes| K[アドレス・ネットマスク・フラグを格納]
    K --> L[MACアドレスを格納 BSD系のみ]
    L --> M[freeifaddrs で一時データ解放]
    M --> N[0 を返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-145-01 | フィルタリング | IFF_UPかつIFF_RUNNINGでないインターフェースは除外 | 常時 |
| BR-145-02 | ifa_addrチェック | ifa_addrがNULLのインターフェースは除外 | 常時 |
| BR-145-03 | BSD固有フィルタ | macOS/FreeBSD等ではAF_LINKの生デバイス情報を非対象として除外 | BSD系プラットフォーム |
| BR-145-04 | ループバック判定 | IFF_LOOPBACKフラグでis_internal=1を設定 | 常時 |
| BR-145-05 | メモリ一括確保 | 構造体配列と名前文字列用メモリを1回のcallocで確保 | 常時 |

### 計算ロジック

メモリ確保サイズ = count * sizeof(uv_interface_address_t) + 全名前文字列の合計長

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UV_ENOMEM | メモリ不足 | uv__callocが失敗した場合 | 十分なメモリを確保する |
| UV__ERR(errno) | システムエラー | getifaddrs()が失敗した場合 | OSのネットワーク設定を確認する |

### リトライ仕様

リトライは不要。一時的なリソース不足の場合は再試行可能。

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

該当なし。

## パフォーマンス要件

OS APIへの問い合わせを伴うため、ミリ秒オーダーの処理時間が想定される。メモリアロケーションは1回のcallocで完了する。

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

- ネットワーク構成情報（IPアドレス、MACアドレス）が取得されるため、情報漏洩に注意
- 取得した情報は使用後に `uv_free_interface_addresses()` で適切に解放すること

## 備考

- BSD系（macOS, FreeBSD等）と Linux で実装が異なる
- OS390では独自の `ioctl(SIOCGIFCONF)` ベースの実装が使用される
- `uv_free_interface_addresses()` はOS390以外では単純な `uv__free()` で、OS390では各nameを個別解放する
- 同一インターフェースがIPv4とIPv6の両方のアドレスを持つ場合、別エントリとして返される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | uv_interface_address_t構造体定義（L1217-1229） |

**読解のコツ**: address/netmaskはunion型で、IPv4(address4/netmask4)とIPv6(address6/netmask6)が同じメモリ領域を共有する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | uv.h | `include/uv.h` | API宣言（L1359-1362） |

#### Step 3: BSD/macOS版の実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | bsd-ifaddrs.c | `src/unix/bsd-ifaddrs.c` | BSD版 uv_interface_addresses() 実装 |

**主要処理フロー**:
- **38-66行目**: `uv__ifaddr_exclude()` - IFF_UP/IFF_RUNNING/AF_LINKによるフィルタリング
- **69-76行目**: 初期化とgetifaddrs()呼び出し
- **82-89行目**: 1回目ループ - 有効インターフェース数カウント
- **97-101行目**: メモリ確保（構造体配列+名前文字列領域を一括calloc）
- **106-131行目**: 2回目ループ - アドレス/ネットマスク/is_internalフラグ格納
- **133-151行目**: 3回目ループ - AF_LINKエントリからMACアドレス取得

#### Step 4: 解放関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | uv-common.c | `src/uv-common.c` | uv_free_interface_addresses() 実装（L1060-1063） |

**主要処理フロー**:
- **1060-1063行目**: 非OS390環境では単純に `uv__free(addresses)` で一括解放

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

```
uv_interface_addresses(addresses, count)     [公開API]
    ├─ getifaddrs()                          [OS API]
    ├─ uv__ifaddr_exclude()                  [内部関数 - フィルタリング]
    ├─ uv__calloc()                          [メモリ確保]
    └─ freeifaddrs()                         [OS API]

uv_free_interface_addresses(addresses, count) [公開API]
    └─ uv__free(addresses)                   [メモリ解放]
```

### データフロー図

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

OS NIC情報 ────▶ uv_interface_addresses()          ────▶ uv_interface_address_t[]
                  ├─ getifaddrs()                         ├─ name
                  ├─ フィルタリング                        ├─ phys_addr
                  ├─ メモリ確保                            ├─ is_internal
                  └─ データ格納                            ├─ address (IPv4/IPv6)
                                                          └─ netmask (IPv4/IPv6)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダー | uv_interface_address_t構造体定義 (L1217-1229)、API宣言 (L1359-1362) |
| bsd-ifaddrs.c | `src/unix/bsd-ifaddrs.c` | ソース | BSD/macOS版実装 |
| linux.c | `src/unix/linux.c` | ソース | Linux版実装 (L1939) |
| aix.c | `src/unix/aix.c` | ソース | AIX版実装 |
| os390.c | `src/unix/os390.c` | ソース | OS390版実装 |
| sunos.c | `src/unix/sunos.c` | ソース | Solaris版実装 |
| util.c | `src/win/util.c` | ソース | Windows版実装 |
| uv-common.c | `src/uv-common.c` | ソース | uv_free_interface_addresses() 共通実装 (L1060-1063) |
