Em geral, cada cabeçalho de extensão começa com dois bytes indicando o tipo do próximo cabeçalho e o comprimento do cabeçalho atual.
Você não pode presumir que isso seja verdade em geral. Depende do tipo de cabeçalho de extensão que você está analisando, esse tipo foi indicado pelo próximo campo de cabeçalho no cabeçalho anterior.
O campo de tamanho é interpretado como um pouco diferente no IPSec em comparação com outros cabeçalhos de extensão IPv6.
Para um cabeçalho de extensão IPv6 normal, você obtém do valor de byte até o comprimento do cabeçalho. Primeiro, adicione 1 e, em seguida, multiplique por 8.
para um cabeçalho IPSec que você obtém do valor de byte para o comprimento do cabeçalho, primeiro adicione 2 e, em seguida, multiplique por 4.
Por que foi projetado assim
O receptor de um pacote precisa validar o campo de comprimento do pacote conforme ele está sendo processado. O IPv6 requer que todos os cabeçalhos de extensão sejam múltiplos de 8 bytes de tamanho, de modo que possam ser implementados eficientemente em CPUs de 64 bits.
O cabeçalho da extensão tem um comprimento mínimo de 8 bytes e, embora o cabeçalho da extensão não tenha comprimento máximo, seria inválido que um cabeçalho da extensão fosse estendido além do final do pacote em que está incorporado.
Conseguir qualquer uma dessas validações incorretas provavelmente levaria a um sério problema de segurança. Por exemplo, se um receptor aceitasse cegamente um cabeçalho de extensão afirmando ter 0 bytes de comprimento, isso faria com que a análise assumisse que o próximo cabeçalho de extensão fosse iniciado exatamente no mesmo endereço. Isso pode levar a um loop infinito, em que o receptor continua analisando o mesmo cabeçalho de extensão várias vezes. Seria bastante provável que isso desencadeasse um congelamento instantâneo do sistema operacional se um pacote tão corrompido fosse recebido.
Mas ao exigir que o receptor adicione 1 e multiplique por 8, duas das validações não são mais necessárias porque, independentemente de qual valor de byte no intervalo de 0 a 255 você aplicar esse cálculo, ele produzirá um resultado que está em pelo menos 8 e é um múltiplo de 8. Como um benefício adicional, aumenta o tamanho do cabeçalho de extensão possível de 255 bytes para 2048 bytes.
O receptor ainda tem que validar o comprimento máximo, não há maneira de contornar isso. Qualquer pacote com um cabeçalho de extensão válido pode ser corrompido diminuindo o campo de tamanho da carga útil no cabeçalho principal para que seja muito curto para o cabeçalho da extensão.
Por que o IPSec é diferente
O IPSec é usado em IPv4 e IPv6. Mas o IPv4 em geral requer apenas alinhamento de 4 bytes (otimizado para CPUs de 32 bits), onde o IPv6 requer 8 bytes de alinhamento (otimizado para CPUs de 64 bits). Por esse motivo, o multiplicador é de apenas 4 nesse caso. O tamanho mínimo do cabeçalho ainda é de 8 bytes.
Isso significa que quando o IPSec é usado no IPv6, o receptor precisa verificar se o campo de comprimento é um valor de byte igual. No entanto, assumindo que a arquitetura da CPU é capaz de acessar valores não alinhados (com desempenho reduzido), o risco no caso de o desenvolvedor esquecer essa validação específica é menor. Na pior das hipóteses, um pacote corrompido exigirá mais alguns ciclos de CPU para processar.
Usando isso para encontrar o cabeçalho da carga útil
O seguinte pseudocódigo mostra como processar os cabeçalhos.
Initialize a pointer to the first byte of the IPv6 header.
Initialize the header type to 41.
While the header type is a known IP or extension header:
Compute current header length
Process current header if applicable
Copy next header field from current header
Move pointer forward by current header length
Nesse algoritmo, os tipos de cabeçalho 4 e 41 são especiais, pois indicam cabeçalho IPv4 e cabeçalho IPv6.