# 機能設計書 95-libalias

## 概要

本ドキュメントは、FreeBSDのlibaliasライブラリの機能設計を記述する。libaliasはNAT（Network Address Translation）エンジンを提供するライブラリであり、IPパケットのアドレス変換処理を実装している。

### 本機能の処理概要

libaliasは、IPパケットのソース/デスティネーションアドレスおよびポート番号を変換するNATエンジンライブラリである。IPFWファイアウォールのNAT機能（divert/natd）やカーネル内NATモジュールの基盤として使用される。

**業務上の目的・背景**：FreeBSDシステムにおいてNAT（ネットワークアドレス変換）を実装するために、パケットのアドレス/ポート変換を行うエンジンが必要である。libaliasはユーザ空間（natd）とカーネル空間の両方で利用可能な共通NATエンジンとして設計されている。

**機能の利用シーン**：natd（ネットワークアドレス変換デーモン）によるNATゲートウェイ構築、IPFWのin-kernel NAT機能、PPP接続でのNAT処理などで使用される。

**主要な処理内容**：
1. 送信パケットのアドレス変換（LibAliasOut）：プライベートアドレスをグローバルアドレスに変換
2. 受信パケットのアドレス変換（LibAliasIn）：グローバルアドレスをプライベートアドレスに逆変換
3. ポートリダイレクト設定（LibAliasRedirectPort）：特定ポートへの転送ルール設定
4. アドレスリダイレクト設定（LibAliasRedirectAddr）：特定アドレスへの転送ルール設定
5. プロトコルリダイレクト設定（LibAliasRedirectProto）：特定プロトコルの転送
6. フラグメントパケットの処理（LibAliasGetFragment/LibAliasSaveFragment）
7. ロードバランシング（LibAliasAddServer）：複数サーバへの分散
8. FTP/IRC/PPTP等のアプリケーションレベルゲートウェイ（ALG）

**関連システム・外部連携**：IPFW（ファイアウォール）、natd（NATデーモン）、ppp（PPPデーモン）、カーネルNATモジュール

**権限による制御**：NATの設定には通常root権限が必要。libaliasライブラリ自体はパケット変換ロジックのみを提供し、権限チェックは行わない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 画面機能マッピングに直接の関連画面なし |

## 機能種別

データ変換（パケットアドレス変換ライブラリ）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| struct libalias * | struct libalias * | Yes | NATインスタンス（LibAliasInit()で作成） | NULLチェック |
| void *ptr | void * | Yes | IPパケットバッファへのポインタ | NULLチェック |
| int maxpacketsize | int | Yes | パケットバッファの最大サイズ | 正の整数 |
| struct in_addr | struct in_addr | Yes（設定時） | IPアドレス | IPv4アドレス形式 |
| unsigned short port | unsigned short | Yes（ポート操作時） | ポート番号 | 0-65535 |

### 入力データソース

- divertソケットまたはカーネルから受け取った生IPパケット
- アプリケーションからのリダイレクト設定API呼び出し

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| PKT_ALIAS_OK | int | パケット変換成功 |
| PKT_ALIAS_IGNORED | int | パケットは変換対象外 |
| PKT_ALIAS_UNRESOLVED_FRAGMENT | int | 未解決フラグメント |
| PKT_ALIAS_ERROR | int | エラー |
| struct alias_link * | struct alias_link * | リダイレクトルール（RedirectPort/Addr/Proto） |

### 出力先

- 入力パケットバッファの直接変更（in-place変換）
- 呼び出し元への結果コード返却

## 処理フロー

### 処理シーケンス

```
1. NATインスタンス初期化（LibAliasInit）
   └─ libalias構造体の確保・初期化
2. エイリアスアドレス設定（LibAliasSetAddress）
   └─ グローバル側IPアドレスの設定
3. モード設定（LibAliasSetMode）
   └─ 動作モードフラグの設定
4. リダイレクトルール設定（オプション）
   └─ LibAliasRedirectPort / LibAliasRedirectAddr
5. パケット変換処理ループ
   └─ LibAliasOut（送信パケット）/ LibAliasIn（受信パケット）
6. インスタンス解放（LibAliasUninit）
   └─ リソース解放
```

### フローチャート

```mermaid
flowchart TD
    A[LibAliasInit] --> B[LibAliasSetAddress: エイリアスアドレス設定]
    B --> C[LibAliasSetMode: モード設定]
    C --> D{パケット方向}
    D -->|送信| E[LibAliasOut: 送信パケット変換]
    D -->|受信| F[LibAliasIn: 受信パケット変換]
    E --> G{結果}
    F --> G
    G -->|PKT_ALIAS_OK| H[変換済みパケット送出]
    G -->|PKT_ALIAS_IGNORED| I[パケットそのまま通過]
    G -->|PKT_ALIAS_ERROR| J[エラー処理]
    H --> D
    I --> D
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-95-1 | In-place変換 | パケットバッファ内のアドレス/ポートを直接書き換える | LibAliasIn/Out呼び出し時 |
| BR-95-2 | エイリアスリンク管理 | NAT変換テーブルのエントリはタイムアウトで自動削除 | 常時 |
| BR-95-3 | ALGサポート | FTP、IRC、PPTP等のプロトコルは専用モジュールで処理 | 該当プロトコル検出時 |
| BR-95-4 | カーネル/ユーザ空間共通 | NO_FW_PUNCH、NO_USE_SOCKETSを定義してカーネル空間で利用可能 | _KERNEL定義時 |

### 計算ロジック

IPチェックサムおよびTCP/UDPチェックサムの差分更新：アドレス/ポート変更に伴うチェックサムの増分計算。

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

### 操作別データベース影響一覧

本機能はデータベースを使用しない。NAT変換テーブルはメモリ内のalias_linkリストで管理される。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| PKT_ALIAS_ERROR | 変換エラー | 不正なパケット、メモリ不足 | パケット破棄 |
| PKT_ALIAS_UNRESOLVED_FRAGMENT | フラグメント未解決 | フラグメントの先頭パケット未着 | フラグメント保存、後で再処理 |

### リトライ仕様

フラグメントパケットの場合、LibAliasSaveFragment()で保存し、先頭パケット到着後にLibAliasFragmentIn()で処理する。

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

該当なし。パケット単位で処理が完結する。

## パフォーマンス要件

- パケット処理はリアルタイム性が求められるため、低レイテンシが必要
- NAT変換テーブルの検索効率が重要

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

- NATによるアドレス隠蔽はセキュリティ機能ではない（ファイアウォールとの併用を推奨）
- リダイレクトルールの誤設定による意図しないポート公開に注意
- ALGモジュールの脆弱性に注意

## 備考

- LIBALIAS_BUF_SIZE = 128
- カーネル空間版ではsocket操作やファイアウォールパンチスルーが無効化される
- モジュラー設計により、プロトコル固有のALGモジュールを追加可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | alias.h | `sys/netinet/libalias/alias.h` | 公開API宣言。struct libalias（不透明型、74行目）、struct alias_link（不透明型、82行目）。LibAlias*関数群の宣言（85-120行目） |
| 1-2 | alias_local.h | `sys/netinet/libalias/alias_local.h` | 内部構造体定義。struct libaliasの実体、alias_linkの実体 |
| 1-3 | alias_db.h | `sys/netinet/libalias/alias_db.h` | NAT変換テーブル管理のヘッダ |
| 1-4 | alias_mod.h | `sys/netinet/libalias/alias_mod.h` | ALGモジュール管理のヘッダ |

**読解のコツ**: alias.hはユーザ空間/カーネル空間共通の公開ヘッダ。_KERNEL定義時にはNO_FW_PUNCH、NO_USE_SOCKETSが自動定義される（47-53行目）。LibAlias*（新API）とPacketAlias*（旧API）の2系統が存在するが、新APIを使用すべき。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | alias.h | `sys/netinet/libalias/alias.h` | LibAliasInit（85行目）、LibAliasIn（94行目）、LibAliasOut（95行目）がメインAPI |

**主要処理フロー**:
- **85行目**: LibAliasInit - NATインスタンスの初期化
- **86行目**: LibAliasSetAddress - エイリアスアドレスの設定
- **90行目**: LibAliasSetMode - 動作モードフラグの設定
- **94行目**: LibAliasIn - 受信パケットのデアリアス処理
- **95行目**: LibAliasOut - 送信パケットのエイリアス処理
- **96行目**: LibAliasOutTry - 新規エントリ作成制御付きエイリアス処理

#### Step 3: リダイレクト機能を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | alias.h | `sys/netinet/libalias/alias.h` | LibAliasRedirectPort（107-110行目）、LibAliasRedirectAddr（103-104行目）、LibAliasRedirectProto（111-113行目）: 静的NAT/ポートフォワーディング |

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

```
LibAliasInit(la)                    [インスタンス初期化]
    │
    ├─ LibAliasSetAddress(la, addr)  [エイリアスアドレス設定]
    ├─ LibAliasSetMode(la, flags, mask) [モード設定]
    │
    ├─ LibAliasRedirectPort(la, ...) [ポートリダイレクト設定]
    │      └─ LibAliasAddServer(la, lnk, ...) [ロードバランス追加]
    │
    ├─ LibAliasOut(la, ptr, maxsize) [送信パケット変換]
    │      ├─ IPヘッダ解析
    │      ├─ TCP/UDP/ICMPプロトコル判定
    │      ├─ alias_link検索/作成
    │      ├─ アドレス/ポート書き換え
    │      ├─ チェックサム再計算
    │      └─ ALGモジュール呼び出し（FTP/IRC等）
    │
    ├─ LibAliasIn(la, ptr, maxsize)  [受信パケット変換]
    │      └─ （LibAliasOutの逆方向処理）
    │
    └─ LibAliasUninit(la)            [インスタンス解放]
```

### データフロー図

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

送信パケット        ───▶ LibAliasOut()            ───▶ NAT変換済みパケット
(プライベートIP)           ├─ alias_link検索              (グローバルIP)
                          ├─ アドレス/ポート変換
                          └─ チェックサム更新

受信パケット        ───▶ LibAliasIn()             ───▶ デアリアス済みパケット
(グローバルIP)             ├─ alias_link検索              (プライベートIP)
                          ├─ アドレス/ポート逆変換
                          └─ チェックサム更新

設定パラメータ      ───▶ LibAliasSetAddress()     ───▶ NAT設定更新
                   ───▶ LibAliasRedirectPort()
                   ───▶ LibAliasSetMode()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| alias.h | `sys/netinet/libalias/alias.h` | ヘッダ | 公開API宣言 |
| alias_local.h | `sys/netinet/libalias/alias_local.h` | ヘッダ | 内部構造体定義 |
| alias_db.h | `sys/netinet/libalias/alias_db.h` | ヘッダ | NAT変換テーブル管理 |
| alias_mod.h | `sys/netinet/libalias/alias_mod.h` | ヘッダ | ALGモジュール管理 |
| alias_sctp.h | `sys/netinet/libalias/alias_sctp.h` | ヘッダ | SCTP ALGモジュール |
| libalias.3 | `sys/netinet/libalias/libalias.3` | マニュアル | manページ |
| Makefile | `lib/libalias/Makefile` | ビルド | ライブラリビルド設定 |
| libalias.conf | `lib/libalias/libalias/libalias.conf` | 設定 | ALGモジュール設定 |
