O Protocolo IPv4
O protocolo IPv4 é o maior protocolo de redes de computadores e um dos mais importantes para toda a infraestrutura internacional. Neste artigo, iremos entender melhor o seu funcionamento.
Mas o que é IP? IP, acrônimo para Internet Protocol, é um protocolo de redes de computadores que descreve as regras de como e para onde será feita uma comunicação. A princípio, esse protocolo foi descrito na RFC 791 de 1981 e, oficialmente em sua versão 4, conhecida como IPv4 (Internet Protocol Version 4).
- As RFCs (Request For Comments) são uma rede de documentos oficiais que descrevem como os protocolos e regras de redes de computadores devem funcionar. Caso tenha curiosidade, você pode visitar: RFC-EDITOR.
Endereços IPv4
Neste artigo, vou evitar aprofundar-me na estrutura de máscara de rede, sub-redes, classes e assuntos afins, para focar exclusivamente no protocolo. Posteriormente (se não for possível agora), recomendo que estude essa parte.
Os endereços IPv4 têm o formato x.x.x.x, com um tamanho total de 32 bits, sendo divididos em 4 octetos. Cada octeto varia de 0 a 255, resultando em uma faixa de endereços de 0.0.0.0 a 255.255.255.255.
- Existem várias faixas de IPs reservadas que não podem ser usadas em aparelhos comuns, e essas são declaradas no site oficial da IANA.
Header IPv4
Oficialmente, não houve IPv1 e IPv2. O protocolo começou com uma breve versão de testes chamada IPv3, mas esta não foi oficial. Também houve o IPv5, que foi apenas experimental e não foi adotado. Logo, as únicas versões oficiais do protocolo IP são o IPv4 e o IPv6. Mais adiante, veremos que o IPv4 e o IPv6 são protocolos distintos. Atualmente, a RFC 791, que inicialmente propunha servir como o protocolo IP como um todo, foi aderida apenas pelo IPv4.
Todos os protocolos de redes de computadores possuem um cabeçalho (header) que define o pacote IP que está sendo enviado.
- Um pacote IP representa uma transmissão única de dados, que pode ou não ser fragmentada dependendo de seu tamanho (falaremos sobre isso mais tarde). Cada pacote IP possui um cabeçalho e um payload. O cabeçalho descreve a origem do pacote, seu destino e outras informações de verificação que discutiremos adiante, enquanto o payload é onde ficam os dados desse pacote.
Todo pacote ip deve conter um outro protocolo em seu payload, protocolos esses que são chamados de protocolos IP (Exemplos: TCP, UDP, ICMP, …).
O header do protocolo IPv4 é o seguinte:
- Campo Version
Este é o primeiro campo de header do IPv4, possui 4 bits e descreve qual a versão do protocolo IP referente ao pacote. Nesse campo o valor sempre será 0100 (4).
- Campo IHL
IHL, acrônimo de Internet Header Length, descreve o tamanho de um header IPv4, também possui 4 bits.
Cada linha do cabeçalho tem 4 bytes de tamanho total, no campo IHL terá a quantidade de linhas que há no cabeçalho, assim realizando 4xIHL teremos o tamanho do header (Em bytes).
Como o IHL só tem 4 bits, então o tamanho do cabeçalho não pode ultrapassar 60 bytes, o cabeçalho padrão contém 5 linhas (20 bytes) e não pode ser menor que isso.
- Campo Type of Service
O campo Type of Service (ToS), segundo byte do header, possui 8 bits (1 byte) de tamanho. Ele descreve como o pacote deverá ser tratado na rede e também para melhora de qualidade de serviço (QoS), porém para maior performance na rede ele é ignorado por roteadores.
- Campo Total Length
Total Length possui 2 bytes (0 -> 65535) e descreve o tamanho total do pacote, esse tamanho pode ser de 0000000000010101 (21 bytes) até 1111111111111111 (65535 bytes).
Podemos também obter o tamanho do payload usando a fórmula:existe cabeçalho IPv4 maior de 25 bytes ou não
Payload = Total Length — 4xIHL
- Campo Identification
Esse campo descreve o pacote IP que está sendo entregue e também possui 2 bytes, esse campo é gerado aleatoriamente pelo kernel do seu sistema operacional.
Ele é responsável por identificar o pacote IP e é útil principalmente em fragmentações de pacotes.
Fragmentação de pacotes é basicamente um mesmo pacote fragmentado em várias partes com o mesmo header, isso ocorre pois quando há uma limitação de capacidade de transmissão na rede (Geralmente 1500 bytes), então há de fragmentar o pacote, cada parte fragmentada terá o mesmo header (Na verdade terá algumas modificações que veremos mais adiante mas o id e informações do pacote são as mesmas), enquanto o payload é dividido e colocado conforme o tamanho em cada parte da fragmentação.
- Lembre-se que apesar da limitação comum de transmissão ser 1500 bytes um pacote não pode ser fragmentado infinitamente pois cada pacote, de acordo com o campo total length, não pode exceder 65535 bytes.
Um exemplo de fragmentação de pacotes:
Foi feita uma análise de um pacote IP em seu payload o protocolo ICMP, esse pacote continha 20 bytes de header e um conteúdo de 3500 bytes, um só fragmento não seria capaz então o pacote precisou ser dividido em 3, dois fragmentos de 1480 bytes de payload e 20 bytes de header e um outro com 540 bytes de payload e 20 bytes de header.
O que está acontecendo? O programa usado para realizar essa captura é o tcpdump, que é muito utilizado para capturas de tráfego, similar ao wireshark, também conhecido. Para entende-lô melhor recomendo que leia sua documentação: https://www.tcpdump.org/ (Não é necessário para continuarmos).
As linhas 1 , 3 e 5 determinam o pacote IP da transmissão sendo que a cada duas linhas temos uma transmissão. Observe:
1. IP (tos 0x0, ttl 64, id 41548, offset 0, flags [+], proto ICMP (1), length 1500)
2. 192.168.1.9 > 192.168.1.4: ICMP echo request, id 29, seq 1, length 1480
A primeira linha define o protocolo IP e seus campos, a segunda linha mostra os protocolos e os conteúdos de seus payloads, no caso, IP:ICMP, divididos por dois pontos. Outros exemplos: IP: TCP, IP: UDP, IP:TCP:HTTP, …
Então vamos fazer uma análise baseado na figura 1, temos um pacote IP sendo enviado de 192.168.1.9 para 192.168.1.4, em seus campos vemos algo que já conhecemos, observe que o id desse pacote é 41548.
Na segunda linha, segundo protocolo, temos um ICMP echo request, o famoso “ping”, ou seja, está sendo feito um “ping 192.168.1.9”, o que isso significa? Um ping basicamente vai enviar pacotes IP’s para a máquina referenciada, no caso 192.168.1.9. Um “ping” espera sempre um “pong” da outra máquina, se não houve algum essa máquina não conseguiu responder, o “pong” é dado por ICMP echo reply.
O campo “length” (Da primeira linha) se refere ao campo Total Length, e diz o tamanho total do pacote.
Observe que a segunda máquina só respondeu quando todo o pacote de 3500 bytes terminou, mas como ela sabia que ainda vinha mais pacotes? E sabendo disso, como ela consegue saber qual a ordem correta (Algo pode acontecer no caminho e algum fragmento sair primeiro que outro)? Veremos isso nos próximos dois campos.
- Campo Flags
Esse campo define se o pacote é ou não fragmentado, possui 3 bits. Cada um dos 3 bits diz se uma propriedade é verdadeirtenho que fazer algo quea ou falsa. A seguir os três bits:
Reserved: Esse bit é reservado pro futuro, atualmente, sempre será 0.
Don’t fragment (DF): Significa don’t fragment, se essa flag está ativa o pacote não pode ser fragmentado.
More fragments (MF): Significa que o pacote está sendo fragmentado e que ainda vem mais fragmentos, ou seja, não é o último fragmento.
000: Quando todos os bits são zero, isso significa que, ou é um pacote que já foi fragmentado e esse é o último fragmento, ou que ele pode ser fragmentado em caso de necessidade futura (Geralmente só não são fragmentados).
- Campo Fragment Offset
Esse campo possui 13 bits (0 -> 8191) e serve para ordenar a transmissão, como disse anteriormente, algo pode ocasionalmente ocorrer e os fragmentos não chegarem em ordem, nesse caso o fragment offset irá realizar a ordenação.
Para calcular o Fragment Offset pegamos o primeiro número do payload de cada fragmento, vemos em qual posição ele está na ordem de bytes do payload inicial (Sem estar fragmentado) e dividimos por 8.
Exemplo: O mesmo pacote de 3500 bytes fragmentado em três. Na primeira transmissão teremos 1480 bytes de payload e 20 de header, logo o primeiro byte na ordem (0 -> 1479) é 0, 0/8 = 0, assim esse fragment offset é de 0; Já na segunda transmissão temos que o primeiro byte na ordem será 1480 (1480 -> 2959), seu fragment offset será de 1480/8 = 185; Enquanto o primeiro byte da terceira será 2960, 2960/8 = 370 é o valor.
- Campo TTL
Finalmente chegamos na terceira linha! TTL é acrônimo de Time to Live e determina o tempo que um pacote irá sobreviver na rede, esse campo possui 1 byte de tamanho (0 -> 255).
Chamamos de HOP o processo de passagem de um pacote em um roteador, e a cada vez que ocorre um HOP o TTL é decrementado em 1.
Sistemas operacionais possuem TTL’s padrões, sendo a maioria dos GNU/Linux com um padrão de 64 (Ou seja, irá durar 64 roteadores), sistemas como Windows possuem TTL padrão de 128, alguns outros como CiscoOS, Solaris, Unix e outros têm um TTL padrão de 255.
Uma prática interessante para entender o TTL é testar o traceroute e ping em sites aleatórios e ver o seu TTL.
- Campo Protocol
Com 8 bits de tamanho, esse protocolo descreve os protocolos IP, cada número de 0–255 representa um protocolo diferente.
Podemos encontrar esses protocolos em /etc/protocols em sistemas GNU/Linux e também no site da IANA.
- Campo Header Checksum
O campo Header Checksum possui 2 bytes e é responsável por realizar a verificação dos dados para checar se eles permanecem íntegros, para tanto é feito um processo matemático não tão complexo mas longo demais para colocar aqui, recomendo então:
2. https://www.packetmania.net/en/2021/12/26/IPv4-IPv6-checksum/
- Campo Source Address
Neste campo será posto o seu IP, ele possui 32 bits e ocupa uma linha inteira.
- Campo Destination Address
O campo Destination Address, analogamente ao Source Address possui 32 bits e se refere ao IP do destinatário.
Esses foram os campos obrigatórios, agora existem campos como Options e Padding que geralmente nem estão inclusos em pacotes IP’s padrão, então não irei falar deles.
Agradecimentos e Referência
Isso foi um resumo do protocolo IPv4 e futuramente, se houver aprovação posso trazer mais desse tipo.
Eu não poderia finalizar esse artigo sem citar a referência máxima, todo o artigo foi baseado no capítulo 5 (De modo bem resumido) do livro do ilustre Professor João Eriberto, autor do livro Análise de Tráfego em Redes TCP/IP, livro ótimo que com toda certeza me deu uma melhor abordagem do assunto e me forneceu propriedade para escrever isto.