O que ela faz

Quando um carrier-grade NAT (CGN) divide um endereço IPv4 público entre muitos assinantes, o que se divide de fato é o campo de porta de 16 bits desse endereço. Esta ferramenta faz a aritmética dessa divisão em três modos: port blocks (quantos blocos e quantos assinantes cabem em um endereço e em um pool, e quanto logging os blocos economizam), o mapeamento determinístico como a RFC 7422 o define (que endereço público e que portas um endereço interno recebe, e o caminho inverso: de endereço público, porta e horário de volta ao endereço interno) e o port set de um Port Set Identifier (PSID) do Mapping of Address and Port (MAP), do jeito que o MAP-E (RFC 7597) e o MAP-T (RFC 7599) calculam. Tudo é aritmética de inteiros rodando no seu navegador; os horários são entradas, nunca lidos de um relógio.

Por que a faixa utilizável começa em 1024

O campo de porta tem 65.536 valores, e a RFC 6335 os divide em "the System Ports, also known as the Well Known Ports, from 0-1023", as portas de sistema, as User Ports de 1024 a 49151 e as Dynamic Ports de 49152 a 65535 (RFC 6335, seção 6). As fontes que dimensionam a alocação de portas de um CGN começam todas acima das System Ports: o primeiro passo de alocação da RFC 7422 tira as portas reservadas e diz "At a minimum, the CGN SHOULD remove system ports [RFC6335] from the port candidate list", no mínimo as portas de sistema saem da lista (RFC 7422, seção 2); o offset da RFC 7597 vale 6 por padrão "as this excludes the system ports (0-1023)", porque assim elas ficam de fora (RFC 7597, seção 5.1); e a RFC 6269 cita a RFC 4787 para dizer que "the use of port space (1024-65535) is safe", seguro para portas de origem de saída (RFC 6269, seção 5). Por isso a faixa utilizável padrão é de 1024 a 65535, 64.512 portas por endereço. Você pode mudá-la: a ferramenta avisa quando a sua faixa mantém System Ports.

Modo 1: port blocks

Entradas: o pool público (um prefixo como 192.0.2.0/24, uma faixa, um endereço ou só a quantidade de endereços), a faixa de portas utilizáveis, o tamanho do bloco em portas, quantos blocos cada assinante pode ter e, se quiser, a demanda, como quantidade de assinantes ou como o prefixo interno de onde vêm os endereços deles.

Saídas: portas utilizáveis por endereço, blocos inteiros por endereço e as portas que nenhum bloco inteiro cobre, assinantes por endereço, assinantes no pool inteiro, o limite de portas por assinante e, diante da demanda, quantos endereços são necessários e se o pool comporta.

Uma regra define a conta. A RFC 6888 exige o pooling de endereço "Paired": "a CGN must use the same external IP address mapping for all sessions associated with the same internal IP address", o mesmo endereço externo para todas as sessões de um assinante (RFC 6888, seção 3, REQ-2). Então todos os blocos de um assinante ficam em um só endereço, e assinantes por endereço é o número de blocos inteiros por endereço dividido pelos blocos por assinante, arredondado para baixo. O tamanho do bloco vezes os blocos por assinante é o limite por assinante que a REQ-4 pede: "A CGN MUST support limiting the number of external ports (or, equivalently, 'identifiers' for ICMP) that are assigned per subscriber", um limite de portas por assinante.

O painel de log quantifica só o que as RFCs quantificam. A RFC 7422 relata mensagens de log com "approximately 150 bytes long for NAT444 [NAT444] and 175 bytes for DS-Lite" e "approximately 33,000 connections per day" por domicílio, o que ela converte em "approximately 5 MB per subscriber per day", cerca de 5 MB por assinante por dia (RFC 7422, seção 1); a ferramenta mostra 33.000 linhas e 4.950.000 bytes (ou 5.775.000 com mensagens de DS-Lite), calculados desses dois números. A RFC 7768 diz que a alocação em blocos gera log "only when blocks are allocated or deallocated", só na alocação e na liberação, "reducing log generation by a factor equal to the block size", um fator igual ao tamanho do bloco (RFC 7768, seção 2); a linha dos blocos divide por esse fator. É um número calculado, não uma medição: a única medição que a RFC cita é de 42,5 TB de log por sessão contra 40,6 GB com port blocks, para 20.000 assinantes em 60 dias (seção 1).

Modo 2: mapeamento determinístico (RFC 7422)

A RFC 7422 troca o log de tradução por uma função: "(External IP Address, Port Range) = function 1 (Internal IP Address)" e "Internal IP Address = function 2 (External IP Address, Port Number)", a ida e a volta (RFC 7422, seção 2). As variáveis são a faixa interna I, a faixa externa O, a razão de compressão C, o fator do pool dinâmico D, o máximo de portas por usuário M, o algoritmo A e a lista de portas reservadas R. A ferramenta implementa o algoritmo 0, Sequential, o mesmo do exemplo resolvido da RFC, passo a passo:

  1. Tira R (padrão 0-1023) da lista de portas candidatas.
  2. Dá a cada endereço interno 1/(C + D) das candidatas, arredondado para baixo; "Any remaining ports are allocated to the dynamic pool", a sobra vai para o pool dinâmico.
  3. Sequential: o primeiro bloco vai para o primeiro endereço interno, o segundo para o segundo, e assim por diante.
  4. Portas além do bloco de um assinante saem do pool dinâmico, até M, e "The CGN MUST log dynamically assigned port blocks", esses blocos vão obrigatoriamente para o log.

A faixa interna é um prefixo ou uma faixa. Um prefixo conta os endereços de host, como a seção 2.3 conta o seu exemplo: 198.51.100.0/28 dá os 14 endereços de .1 a .14, e C fica 14. Por padrão C é I dividido por O, arredondado para cima; você pode definir outro valor. Quando O tem mais de um endereço, a ferramenta preenche os endereços externos em ordem, C endereços internos em cada um: o exemplo da RFC tem um só endereço externo e não mostra esse caso, então trate isso como o layout da ferramenta. Uma lista de reservadas com portas extras (0-1023,5004,5060) é respeitada exatamente, e um bloco que atravessa uma porta reservada aparece como duas faixas.

Consulta direta: um endereço interno dá o seu endereço externo e a sua faixa de portas. Consulta reversa: endereço externo e porta dão o endereço interno quando a porta está em um bloco pré-alocado; "dinâmico" quando está no pool dinâmico, onde só o log dos blocos dinâmicos responde; "reservada" quando está em R; "fora do pool" quando o endereço não está em O. Um horário (UTC, com precisão de segundo, como a RFC 6302 recomenda para logs de servidor) pode acompanhar a consulta e, com "em vigor desde" e "em vigor até", a ferramenta diz se a configuração informada valia naquele horário. A RFC 7422 diz por que isso importa: identificar um assinante exige a configuração em vigor naquele momento, então "the CGN MUST generate a record any time such variables are changed", um registro a cada mudança (RFC 7422, seção 3). A ferramenta escreve esse registro no formato da RFC, timestamp, prefixo e máscara internos, prefixo e máscara externos, D, M, A e R: com os campos da própria RFC ela imprime [Wed Oct 11 14:32:52 2000]:198.51.100.0:28:192.0.2.0:32:2:5040:0:1-1023,5004,5060.

Fora do escopo: os algoritmos 1 a 5 (a RFC descreve Staggered, Round robin e Interlaced horizontally só por exemplo, e o 4 e o 5 dependem de chaves ou de fabricante) e uma faixa interna IPv6 (DS-Lite), que a RFC 7422 admite. O endereço interno é o fim da aritmética: a seção 2.3 depois o cruza "with DHCP/PPP lease connection records", com os registros de lease.

Modo 3: port sets do MAP (RFC 7597, RFC 7599)

O MAP divide um endereço sem um NAT central, dando a cada customer edge (CE) um port set fixo. A RFC 7597 escreve uma porta como três campos, A (a bits), o PSID (k bits) e j (m bits), com a + k + m = 16 (RFC 7597, seção 5.1). "For 'a' > 0, A MUST be larger than 0", A não pode ser 0, então o bloco de portas em que A vale 0 não é de ninguém: com o a = 6 padrão, isso é de 0 a 1023, e "'a' = 4 will exclude ports 0-4095", com a = 4 saem de 0 a 4095. "The sharing ratio is 2^k. The number of ports assigned to the user is 2^(16 - k) - 2^m (excluded ports)", a razão de compartilhamento e as portas por usuário, cada faixa contígua tem 2^m portas, e "The interval between initial port numbers of successive contiguous ranges assigned to the same user is 2^(16 - a)", o espaçamento entre faixas. O MAP-T usa as mesmas regras: o apêndice de mapeamento de portas dele aponta para o da RFC 7597 (RFC 7599, Apêndice B).

Entradas: a, k, e um PSID (decimal, ou hexadecimal com 0x) e/ou uma porta. Saídas: m, a razão de compartilhamento, portas por set, o tamanho e o intervalo das faixas, o bloco excluído, todas as faixas do PSID (até 1.024 delas) e, para uma porta, o PSID dono dela, pela fórmula da RFC 7597 "PSID = trunc((P modulo (R * M)) / M)" (Apêndice B), ou "excluída" quando o A dela é 0. Com a = 0 não existe campo A e o port set inteiro é uma faixa só; a RFC 7597 então tira as portas baixas "by putting a lower bound equal to ceil(N / M) on the allowed set of PSID values", com um limite inferior para o PSID (Apêndice B.1), e a ferramenta dá esse limite para N = 1024.

Exemplos resolvidos

  • Blocks: 192.0.2.0/24 com blocos de 300 portas, o tamanho do bloco de exemplo da RFC 7768, "ports 2001~2300": 215 blocos por endereço com 12 portas sobrando, 55.040 assinantes no pool e 110 linhas de log por assinante por dia em vez de 33.000.
  • Determinístico: o exemplo da RFC 7422, interno 198.51.100.0/28, externo 192.0.2.1, D = 2, M = 5040. C + D = 16, cada endereço interno recebe 4.032 portas, 198.51.100.1 fica com 1024 a 5055 e 198.51.100.14 com 53440 a 57471, o pool dinâmico vai de 57472 a 65535, e M permite mais 1.008 portas por assinante. A porta 2001 volta para 198.51.100.1; a porta 58204 está no pool dinâmico. As duas consultas são as da própria RFC.
  • MAP: a = 6, k = 8, PSID 0x34: 63 faixas de 4 portas, de 1232-1235 e 2256-2259 até 63696-63699 e 64720-64723, 252 portas no total, o port set impresso no Apêndice A da RFC 7597. A porta 1232 volta para o PSID 0x34, como mostra o Exemplo 2 do Apêndice A.

O que ela não faz

Ela não aloca nada, não lê log e não fala com equipamento, e não dá orientação jurídica. Quem guarda quais registros, por quanto tempo e como se responde a um pedido legal dependem da jurisdição; o artigo sobre CGNAT expõe o que dizem a RFC 6269, a RFC 6302 e, no Brasil, o Marco Civil da Internet, com as fontes.

Procedência

Todo número vem das RFCs abaixo, baixadas em 2026-10-19. A ferramenta traz 36 golden vectors (conjunto cgn-port-blocks/2026-10-19a). Os números das próprias RFCs estão fixados ao pé da letra: a tabela de catorze linhas da RFC 7422, as duas consultas reversas e o registro de configuração dela, o port set do PSID 0x34 da RFC 7597, o exemplo de porta para PSID e os dois exemplos do Apêndice B.2. Os demais são calculados pela regra que citam, e dizem isso. A errata verificada 5324 da RFC 7599 corrige o Exemplo 5 dela de PSID 0x20 para 0x34, o PSID que bate com as portas impressas; a errata verificada 4211 da RFC 7422 corrige uma citação de "RFC 6292" para RFC 6269.

API

O mesmo engine responde à operação /api/v1/cgn-port-blocks da API HTTP do site, descrita campo a campo no contrato OpenAPI na página da API, com exemplos tirados dos golden vectors. O contrato também diz se este site serve a API.

  • Pedido. Um objeto JSON que diz o modo. {"mode":"blocks","pool":"192.0.2.0/24","blockSize":300} com portRange, blocksPerSubscriber, subscribers ou inside e logFormat (nat444 ou ds-lite) opcionais. {"mode":"deterministic","inside":"198.51.100.0/28","outside":"192.0.2.1","dynamicFactor":2,"maxPorts":5040} com reserved, compressionRatio, lookup, reverse (address, port, time), configFrom, configUntil e recordTime opcionais. {"mode":"map","offset":6,"psidLength":8,"psid":"0x34"} com port opcional.
  • Resposta. O resultado do modo, com mode dizendo qual. Para {"mode":"map","offset":6,"psidLength":8,"port":1232} a API responde reverse.psid 52 e reverse.psidHex 0x34; para o pedido da RFC 7422 com reverse na porta 2001 ela responde reverse.status deterministic e reverse.inside 198.51.100.1.
  • Erros. HTTP 400, invalid_input, com a mensagem do engine, por exemplo with k = 8 the PSID must be 0 to 255 para o PSID 256.

Fontes