You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
72 lines
2.8 KiB
72 lines
2.8 KiB
/* eim_nat — таблица Endpoint-Independent Mapping для IPv4 TCP/UDP и ICMP echo. |
|
* init_ctx создаёт состояние из global_config; при отключённом NAT оставляет initialized=0. |
|
* egress/ingress меняют IP/порты и checksums на месте, не отправляют пакеты и не владеют TUN/ETCP. |
|
* Перед обработкой нужен инициализированный ctx; вызовы последовательны в uasync-потоке. |
|
* gateway/internal IP — host order, internal_port — network order, внешний порт — host order. |
|
* src_conn заимствован; срок жизни и выбор транспорта обратной отправки контролирует nat_transport. */ |
|
#ifndef EIM_NAT_H |
|
#define EIM_NAT_H |
|
|
|
#ifdef __cplusplus |
|
extern "C" { |
|
#endif |
|
|
|
|
|
#include <stdint.h> |
|
#include <stddef.h> |
|
|
|
struct ETCP_CONN; |
|
|
|
#define EIM_NAT_TABLE_SIZE 65536 |
|
|
|
#define EIM_NAT_ENTRY_FREE 0 |
|
#define EIM_NAT_ENTRY_ACTIVE 1 |
|
#define EIM_NAT_ENTRY_STATIC 2 |
|
|
|
#define IPPROTO_TCP_UINT8 6 |
|
#define IPPROTO_UDP_UINT8 17 |
|
#define IPPROTO_ICMP_UINT8 1 |
|
|
|
struct eim_nat_entry { |
|
uint32_t internal_ip; |
|
uint16_t internal_port; |
|
uint8_t proto; |
|
uint8_t state; |
|
uint64_t src_node_id; // which node sent the original packet |
|
uint64_t last_seen; |
|
struct ETCP_CONN* src_conn; // cached connection for sendback |
|
}; |
|
|
|
// Состояние преобразования; TUN и транспортные ресурсы принадлежат nat_transport. |
|
struct eim_nat_ctx { |
|
uint32_t gateway_ip; |
|
uint16_t port_start; |
|
uint16_t port_end; |
|
uint16_t next_port; |
|
struct eim_nat_entry* table; |
|
size_t table_size; |
|
int initialized; |
|
}; |
|
|
|
struct global_config; |
|
|
|
int eim_nat_init_ctx(struct eim_nat_ctx* ctx, const struct global_config* g); |
|
void eim_nat_destroy_ctx(struct eim_nat_ctx* ctx); |
|
|
|
/* 0 — обработано или пакет не подлежит NAT, -1 — ошибка; буфер принадлежит вызывающему. */ |
|
int eim_nat_egress(struct eim_nat_ctx* ctx, uint8_t* ip_data, size_t ip_len, |
|
uint64_t src_node_id, struct ETCP_CONN* src_conn); |
|
/* out_entry изменяется только при найденном mapping; заранее установить *out_entry=NULL. |
|
* Запись заимствована у ctx. 0 само по себе не означает, что пакет был преобразован. */ |
|
int eim_nat_ingress(struct eim_nat_ctx* ctx, uint8_t* ip_data, size_t ip_len, |
|
struct eim_nat_entry** out_entry); |
|
|
|
int eim_nat_add_forward(struct eim_nat_ctx* ctx, uint8_t proto, |
|
uint32_t internal_ip_host, uint16_t internal_port_net, |
|
uint16_t external_port); |
|
|
|
|
|
#ifdef __cplusplus |
|
} |
|
#endif |
|
#endif
|
|
|