Trabalho 09: Geração de Pacotes e Tabela de Roteamento IPv6 Redes de Computadores 1 Descrição Você pode fazer este trabalho em dupla, desde que o seu parceiro não seja o mesmo do trabalho 08. Neste trabalho você precisará implementar dois programas. O segundo é muito similar ao do trabalho 8, mas ao invés de IPv4, você deve implementar o IPv6 (você pode reutilizar e adaptar qualquer código que você ou seu colega criaram no trabalho 8). O primeiro programa cria um pacote IPv6 e envia para o seu segundo programa. Como no trabalho 08, a função de encaminhamento do seu segundo programa é limitada a imprimir o próximo salto (hop) e interface que o pacote deveria ser encaminhado pelo roteador ou host (assim como imprimir a origem e o endereço de destino do pacote). Como no trabalho 08, as tabelas de roteamento são estáticas e especificadas como argumento de linha de comando, logo, você não precisa implementar qualquer protocolo de roteamento, ou, mesmo, uma tabela de roteamento. 2 Criando um pacote IPv6 Escreva um programa em C, ipgen, para criar um pacote IPv6 válido como descrito na RFC2460 1. Em particular, o seu pacote deve ter: número de versão 6 classe de tráfego e rótulo de fluxo zero tamanho do payload zero próximo cabeçalho zero limite de hop s com pelo menos 1 endereço de origem de destino especificados na linha de comando sem payload, ou seja, o pacote tem somente o cabeçalho IPv6 1 https://tools.ietf.org/html/rfc2460 1
ipgen6 recebe três argumentos na linha de comando: o número da porta e dois endereços IPv6. Isso cria um pacote como descrito acima e envia ele para ::1 (localhost) para uma porta UDP fornecida na linha de comando. Ou seja, você está enviando um pacote IPv6 (com apenas o cabeçalho IPv6) sobre IPv6 e UDP para o seu programa rlookup6 que será descrito a seguir. Por exemplo: $./ipgen6 12345 1:2:3::4 5:6:7:8:9:a:b:c cria um pacote IPv6 (somente cabeçalho) com endereço de origem 1:2:3::4 (que é o mesmo que 1:2:3:0:0:0:0:4) e o endereço destino 5:6:7:8:a:b:c. Ele envia o pacote para o endereço IPv6 local (que é o endereço ::1) e a porta UDP 12345. Eu sugiro usar o inet_pton para converter as strings em endereços IP. Por exemplo: char src [16]; if (inet_pton (AF_INET6, argv [2], src)!= 1) { printf ("usage: %s udp-port ipv6-source ipv6-dest\n", argv [0]); printf (" source address %s is not a valid IPv6 address", argv [2]); return 1; } 2.1 ipgen6 do Professor O professor criou um binário do Linux para o ipgen6 (para 32-bits 2 ou para 64-bits 3 ) que podem te ajudar a testar o seu código. O seu próprio código devem gerar os mesmos bytes que o do professor quando você executar o wireshark na interface de loopback (você vai precisar tornar o binário executável após baixá-lo com o comando chmod +x ipgen6-*). 3 Tabela de Roteamento 1. um Destino, que é um endereço IP 2. um Gateway ou próximo salto (hop), que é também um endereço IP 3. uma máscara, que é uma string de 128-bits, mas não é um endereço IP 4. várias flags, que para este trabalho podem ser ignoradas 5. uma métrica, que para este trabalho podem ser ignoradas 6. uma interface, que pode ser uma string arbitrária 2 http://facom.ufms.br/~brivaldo/bin/ipgen6-i32 3 http://facom.ufms.br/~brivaldo/bin/ipgen6-x64 2
A maioria dos roteadores usam métodos automatizados como protocolos de roteamento ou DHCP para construir suas tabelas de roteamento. Para este trabalho, a tabela de roteamento deve ser especificada com ouma série de argumentos por linha de comando no seguinte formato: destino/gateway/máscara/interface Cada destino, gateway e máscara são fornecidos na notação dois-pontos-hexadecimal suportada pelo inet_pton. A máscara é um número entre 0 e 128 inclusive (note que isso é diferente do trabalho 8).A interface é uma string arbitrária (não maior do que 100 caracteres). Cada argumento desses é usado para construir uma entrada na tabela de roteamento, na ordem fornecida na linha de comando. Para procurar na tabela de roteamento, o IP usa um algoritmo chamado de longest match. De todas as entradas na tabela de roteamento que casariam com um padrão, aquele com a maior máscara é usado. Se existirem diversas entradas que casam com o padrão e tem máscara de mesmo tamanho, a primeira é usada. Uma rota casa com um endereço IP quando seu destino E sua máscara são os mesmos que o endereço IP E a máscara, ou (route[i].dest & route[i].mask) == (ip->dest & route[i].mask) Ambas as máscaras totalmente com zero e totalmente com uns são legais. A primeira é a rota padrão, usada se nenhuma outra rota casar. A segunda é a rota para o host, usada somente se o destino do pacote é o mesmo destino que o da tabela de roteamento. O primeiro parâmetro é o número de uma porta UDP que escutará por pacotes que chegam (novamente, isso difere do trabalho 8). Eu sugiro usar o inet_ntop para converter um endereço IP para strings. Por exemplo, char prtsrc [INET6_ADDRSTRLEN]; inet_ntop (AF_INET6, src, prtsrc, sizeof (prtsrc)); printf ("source address is %s\n", prtsrc); 4 Exemplos Todos os exemplos assumem que o seu programa é invocado como segue: $./rlookup6 12345 ::/1:2:3::99/0/eth1 1::/1:2:3::abcd/16/eth1 1::/2:4:6::8/16/eth0 1:2::/2:4:6::9/32/eth0 1:2:3::0/1:2:3::1/48/eth1 1:2:3::4/1:2:3::4/128/eth1 A porta para todos os exemplos a seguir é 12345. O endereço de origem é ignorado no 3
encaminhamento, mas ainda deve ser definido corretamente pelo seu ipgen6 e impresso pelo rlookup6. 1. $./ipgen6 12345 1::2 1:2:3::4 Isso casa com todas as rotas. A mais longa é a última rota, que é a rota para o host, logo, o rlookup6 deverá imprimir: packet from 1::2 to 1:2:3::4, forwarding to 1:2:3::4 over eth1 2. $./ipgen6 12345 2::3 1:2:3::99 Os primeiros 48 bits de 1:2:3::99 casam com os primeiros 48 bits da quinta rota (assim como das rotas anteriores), logo o rlookup6 deverá imprimir: packet from 2::3 to 1:2:3::99, forwarding to 1:2:3::1 over eth1 3. $./ipgen6 12345 3::4 1:3:5:7:9:b:d:f 1:3:5:7:9:b:d:f casa com a segunda e a terceira rota, logo, o rlookup6 deverá usar a segunda rota e imprimir: packet from 3::4 to 1:3:5:7:9:b:d:f, forwarding to 1:2:3::abcd over eth1 4. $./ipgen6 12345 4::5 8:7:6:5:4:3:2:1 8:7:6:5:4:3:2:1 só casa com a primeira (padrão) rota, logo, o rlookup6 deverá imprimir: packet from 4::5 to 8:7:6:5:4:3:2:1, forwarding to 1:2:3::99 over eth1 5. $./ipgen6 12345 1::2 1:2:3::4 o rlookup6 deverá imprimir: packet from 1::2 to 1:2:3::4, forwarding to 1:2:3::4 over eth1 6. Se não existir um casamento (somente é possível se não existir uma rota padrão), o rlookup6 deverá imprimir: destination 9:8:7::6 not found in routing table, dropping packet 5 Resultados Por favor siga os exemplos anteriores e relate os resultados do seu analisador de tabelas de roteamento (um pequeno texto explicativo). Anexe o texto em.txt com um descritivo de uso, junto com os seus códigos fonte com nomes rlookup6.c e ipgen6.c e envie tudo em um único.zip 4
6 Opções Se você tiver tempo, você é bem vindo para enviar pacotes IP válidos, por exemplo, pacotes de ping ICMPv6 4. 4 https://tools.ietf.org/html/rfc4443 5