# 帳票設計書 8-ネットワークインターフェース一覧

## 概要

本ドキュメントは、libuvライブラリにおける `uv_interface_addresses()` API関数の帳票設計書である。システムのネットワークインターフェース情報（名前・物理アドレス・IPアドレス・ネットマスク・内部フラグ）をuv_interface_address_t構造体の配列として出力する機能について定義する。

### 本帳票の処理概要

本帳票は、システムに存在する全てのネットワークインターフェースの情報を動的配列として取得する機能を提供する。各インターフェースについて、名前、MACアドレス、IPアドレス（IPv4/IPv6）、ネットマスク、内部インターフェースかどうかのフラグが出力される。

**業務上の目的・背景**：ネットワーク関連アプリケーションにおいて、利用可能なネットワークインターフェースの一覧と各インターフェースの設定情報を取得する必要がある。バインドアドレスの自動選択、マルチキャスト設定、ネットワーク診断等の基礎情報として使用する。

**帳票の利用シーン**：サーバーアプリケーションのバインドアドレス自動検出、ネットワーク構成の自動検出、マルチホーム環境でのインターフェース選択、ネットワーク診断ツール。

**主要な出力内容**：
1. name（char*）：インターフェース名（例：eth0, en0）
2. phys_addr[6]（char[6]）：MACアドレス（6バイト）
3. is_internal（int）：内部（ループバック）インターフェースかどうか
4. address（sockaddr_in/sockaddr_in6）：IPアドレス
5. netmask（sockaddr_in/sockaddr_in6）：ネットマスク

**帳票の出力タイミング**：`uv_interface_addresses(&addresses, &count)` 呼び出し時に動的メモリ確保と共に出力される。使用後は `uv_free_interface_addresses()` で解放が必要。

**帳票の利用者**：ネットワークアプリケーション開発者、システム管理者。

## 帳票種別

システム情報一覧（動的配列出力）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| N/A | N/A（C API呼び出し） | N/A | `uv_interface_addresses(&addresses, &count)` 関数呼び出し |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | メモリ動的配列（uv_interface_address_t*） |
| 出力方法 | ポインタ経由で動的配列を返却 |
| 解放方法 | uv_free_interface_addresses(addresses, count) |

## 帳票レイアウト

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 備考 |
|----|-------|------|-------------|---------|------|
| 1 | name | インターフェース名 | getifaddrs().ifa_name | char*（ヒープ割当） | |
| 2 | phys_addr[6] | MACアドレス | プラットフォーム依存 | char[6]（バイナリ） | Linuxはsockaddr_ll, BSD系はsdl_data |
| 3 | is_internal | 内部IF判定 | ifa_flags & IFF_LOOPBACK | int（0/1） | |
| 4 | address.address4 | IPv4アドレス | ifa_addr (AF_INET) | struct sockaddr_in | |
| 5 | address.address6 | IPv6アドレス | ifa_addr (AF_INET6) | struct sockaddr_in6 | |
| 6 | netmask.netmask4 | IPv4ネットマスク | ifa_netmask (AF_INET) | struct sockaddr_in | |
| 7 | netmask.netmask6 | IPv6ネットマスク | ifa_netmask (AF_INET6) | struct sockaddr_in6 | |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| addressesポインタ | 結果配列を受け取るポインタ変数のアドレス | Yes |
| countポインタ | インターフェース数を受け取るint変数のアドレス | Yes |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | getifaddrs()の返却順 | システム依存 |

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

### 参照テーブル一覧

| プラットフォーム | データソース | 取得方法 |
|----------------|------------|---------|
| BSD系/macOS | getifaddrs() | POSIX API |
| Linux | getifaddrs() | glibc API |
| AIX | ioctl(SIOCGIFCONF) | ソケットioctl |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| is_internal | (ifa_flags & IFF_LOOPBACK) != 0 | N/A | ループバックインターフェースかどうか |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[uv_interface_addresses呼び出し] --> B[getifaddrs実行]
    B --> C{成功?}
    C -->|No| D[UV__ERR errno 返却]
    C -->|Yes| E[1回目走査: AF_INET/AF_INET6のIF数をカウント]
    E --> F[uv__callocで配列確保]
    F --> G{成功?}
    G -->|No| H[freeifaddrs後にUV_ENOMEM返却]
    G -->|Yes| I[2回目走査: 各IFの情報をコピー]
    I --> J[freeifaddrsでリソース解放]
    J --> K[0を返却]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| getifaddrs失敗 | getifaddrs()がエラーを返した場合 | N/A | UV__ERR(errno)を返却 |
| メモリ確保失敗 | uv__calloc()がNULLを返した場合 | N/A | freeifaddrs後にUV_ENOMEMを返却 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 数件〜数十件のインターフェース |
| 目標出力時間 | ミリ秒オーダー |
| 同時出力数上限 | N/A |

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

ネットワークインターフェース情報（IPアドレス、MACアドレス）はネットワーク構成の機密情報に該当する可能性がある。特にMACアドレスはデバイス追跡に利用できるため、取り扱いに注意が必要。

## 備考

- 返却された配列は `uv_free_interface_addresses(addresses, count)` で解放する必要がある
- AF_INETとAF_INET6以外のアドレスファミリ（AF_PACKET/AF_LINK等）は除外される
- 同一インターフェースがIPv4とIPv6の両方のアドレスを持つ場合、別エントリとして出力される
- Linuxでは物理アドレスの取得にsockaddr_ll（AF_PACKET）を使用する
- BSD系ではsockaddr_dl（AF_LINK）を使用する

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | uv_interface_address_s構造体（1217-1229行目）のname, phys_addr, is_internal, address, netmaskメンバ |

**読解のコツ**: address/netmaskはunion型で、address4（sockaddr_in）とaddress6（sockaddr_in6）のいずれかが有効。sa_familyで判別する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | bsd-ifaddrs.c | `src/unix/bsd-ifaddrs.c` | BSD系のuv_interface_addresses()（69行目〜）の実装を確認 |
| 2-2 | linux.c | `src/unix/linux.c` | Linux版uv_interface_addresses()（1939行目〜）の実装を確認 |

#### Step 3: メモリ解放を理解する

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

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

```
uv_interface_addresses(addresses, count)           [プラットフォーム別]
    |
    +-- [BSD/macOS] src/unix/bsd-ifaddrs.c:69
    |       +-- getifaddrs()                       [POSIX API]
    |       +-- uv__calloc()                       [メモリ確保]
    |       +-- freeifaddrs()                      [リソース解放]
    |
    +-- [Linux] src/unix/linux.c:1939
    |       +-- getifaddrs()                       [glibc API]
    |       +-- uv__calloc()                       [メモリ確保]
    |       +-- freeifaddrs()                      [リソース解放]
    |
    +-- [AIX] src/unix/aix.c:1104
            +-- ioctl(SIOCGIFCONF)                 [ソケットioctl]
```

### データフロー図

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

getifaddrs()                  uv_interface_addresses()          uv_interface_address_t**
  struct ifaddrs* -----+      1) カウント走査                   [0].name = "en0"
                       +----> 2) メモリ確保                     [0].phys_addr = {...}
                       |      3) データコピー走査               [0].is_internal = 0
  ifa_name     ------> |         name, phys_addr, address      [0].address = ...
  ifa_addr     ------> |         netmask, is_internal          [0].netmask = ...
  ifa_netmask  ------> |                                       *count = N
  ifa_flags    ------> +
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダ | uv_interface_address_t構造体定義、API宣言 |
| bsd-ifaddrs.c | `src/unix/bsd-ifaddrs.c` | ソース | BSD/macOS版実装 |
| linux.c | `src/unix/linux.c` | ソース | Linux版実装 |
| aix.c | `src/unix/aix.c` | ソース | AIX版実装 |
| uv-common.c | `src/uv-common.c` | ソース | uv_free_interface_addresses()実装 |
