# EIM NAT (Endpoint-Independent Mapping NAT) ## 1. Назначение Трансляция сетевых адресов с endpoint-independent поведением: для каждого кортежа `(внутренний IP, внутренний порт, протокол)` выделяется уникальный внешний порт на шлюзе, не зависящий от внешнего адресата. Поддерживает TCP, UDP и ICMP Echo. Инкрементальный пересчёт контрольных сумм. ## 2. Как пользоваться ```c struct eim_nat_ctx nat; eim_nat_init_ctx(&nat, &global_cfg); // таблица 64K записей eim_nat_egress(&nat, pkt, len, node_id, conn); // src IP/port -> внешние eim_nat_ingress(&nat, pkt, len, &entry); // dst IP/port -> внутренние eim_nat_add_forward(&nat, proto, ip, port, ext_port); // статический проброс eim_nat_destroy_ctx(&nat); ``` **Таблица:** 64K записей, индексируется по внешнему порту (внешний порт == индекс в таблице). **eim_nat_egress:** выделяет внешний порт (аллоцирует из циклического пула `next_port`), заменяет src IP на шлюзовой и src порт на внешний, корректирует IP- и транспортную контрольные суммы. Фрагментированные пакеты пропускаются без обработки. **eim_nat_ingress:** ищет запись по внешнему dst-порту в таблице, заменяет dst IP на внутренний и dst порт на внутренний, корректирует контрольные суммы. Возвращает `out_entry` — указатель на запись (содержит `src_node_id` и `src_conn` для маршрутизации ответа). **eim_nat_add_forward:** добавляет статическую запись (`EIM_NAT_ENTRY_STATIC`), которая не вытесняется динамическими. **Контрольные суммы:** пересчитываются инкрементально через `csum_update_n()` — старые значения вычитаются из ~csum, новые прибавляются. Это работает для TCP pseudo-header checksum и UDP. **Конфиг:** ```ini [nat] enabled = 1 tun_ip = 10.0.0.1 port_start = 10000 port_end = 20000 [nat_forward] rule = tcp 192.168.1.2:80 :8080 ``` ## 3. API | Функция/Структура | Описание | |---|---| | `struct eim_nat_entry` | Запись: internal_ip, internal_port, proto, state (FREE/ACTIVE/STATIC), src_node_id, src_conn, last_seen | | `struct eim_nat_ctx` | Контекст: gateway_ip, port_start/end, next_port (циклический аллокатор), table[64K], initialized | | `eim_nat_init_ctx(ctx, cfg)` | Инициализация таблицы, загрузка статических пробросов из конфига | | `eim_nat_destroy_ctx(ctx)` | Освобождение таблицы, обнуление | | `eim_nat_egress(ctx, ip_data, ip_len, src_node_id, src_conn)` | Трансляция исходящего пакета: src IP/port → шлюзовые. Создаёт динамическую запись при первом проходе | | `eim_nat_ingress(ctx, ip_data, ip_len, out_entry)` | Обратная трансляция входящего пакета: dst IP/port → внутренние. Заполняет out_entry для маршрутизации | | `eim_nat_add_forward(ctx, proto, ip_host, port_net, ext_port)` | Добавление статического проброса (runtime API) |