Nous allons sans tarder effectuer une première manipulation. Pour l'instant, nous ne disposons que de deux hôtes, connectés entre eux par un simple HUB, sans aucune passerelle vers l'internet. L'un des deux hôtes est déjà démarré et configuré en IP v6. Il dispose d'un « sniffeur » (l'incontournable Wireshark).
L'objectif est de contrôler ce qu'il se passe lorsque le second hôte est mis en service. Cet hôte dispose d'une interface dont l'adresse MAC est :
00:0d:88:37:73:e9
Ce qui nous laisse supposer un futur jeton:
20d:88ff:fe37:73e9
Voyons d'abord l'ensemble des trames capturées :
No. Time Source Destination Protocol Info 1 0.000000 :: ff02::1:ff37:73e9 ICMPv6 Neighbor solicitation 2 0.999924 fe80::20d:88ff:fe37:73e9 ff02::2 ICMPv6 Router solicitation 3 4.999740 fe80::20d:88ff:fe37:73e9 ff02::2 ICMPv6 Router solicitation 4 8.999580 fe80::20d:88ff:fe37:73e9 ff02::2 ICMPv6 Router solicitation
Il y a plusieurs choses à dire ici.
L'hôte qui démarre cherche à auto-configurer son lien local, en utilisant le principe vu plus haut. Il va donc préalablement s'assurer que l'adresse IP qu'il compte exploiter n'est pas déjà utilisée.
Pour ce faire, il exploite une nouvelle fonctionnalité d'ICMP qui est appelée « Neighbor discovery » (Découverte du voisinage).
Il n'y a pas de réponse à ce message, ce qui veut dire que l'adresse convoitée n'est pas en usage sur le lien local. Notre hôte adopte donc l'adresse :
fe80::20d:88ff:fe37:73e9
construite comme nous l'avons vu plus haut.
Viennent ensuite trois messages de type « Router solicitation » (découverte de routeurs) qui restent sans réponse, ce qui est rassurant, puisqu'il n'y en a pas sur notre réseau embryonnaire.
Voyons plus en détail la première trame :
Frame 1 (78 bytes on wire, 78 bytes captured) ... Ethernet II, Src: D-Link_37:73:e9 (00:0d:88:37:73:e9), Dst: IPv6-Neighbor-Discovery_ff:37:73:e9 (33:33:ff:37:73:e9) Destination: IPv6-Neighbor-Discovery_ff:37:73:e9 (33:33:ff:37:73:e9) Address: IPv6-Neighbor-Discovery_ff:37:73:e9 (33:33:ff:37:73:e9) .... ...1 .... .... .... .... = IG bit: Group address (multicast/broadcast) .... ..1. .... .... .... .... = LG bit: Locally administered address (this is NOT the factory default) Source: D-Link_37:73:e9 (00:0d:88:37:73:e9) Address: D-Link_37:73:e9 (00:0d:88:37:73:e9) .... ...0 .... .... .... .... = IG bit: Individual address (unicast) .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default) Type: IPv6 (0x86dd) Internet Protocol Version 6 0110 .... = Version: 6 .... 0000 0000 .... .... .... .... .... = Traffic class: 0x00000000 .... .... .... 0000 0000 0000 0000 0000 = Flowlabel: 0x00000000 Payload length: 24 Next header: ICMPv6 (0x3a) Hop limit: 255 Source: :: (::) Destination: ff02::1:ff37:73e9 (ff02::1:ff37:73e9) Internet Control Message Protocol v6 Type: 135 (Neighbor solicitation) Code: 0 Checksum: 0x0ad9 [correct] Target: fe80::20d:88ff:fe37:73e9 (fe80::20d:88ff:fe37:73e9)
La source (l'hôte qui cherche à s'auto-configurer avec l'IPv6 fe80::20d:88ff:fe37:73e9
) dispose de l'adresse MAC 00:0d:88:37:73:e9
et envoie un message ICMP de type: 135 (Neighbor solicitation) sur une adresse de broadcast IPv6 ff02::1:ff37:73e9
, ce qui correspond à une adresse MAC multicast de la forme 33:33:ff:37:73:e9
.
Si d'aventure, un autre hôte disposait d'une adresse MAC dont les 3 derniers octets seraient 37:73:e9
, ce dernier répondrait à la sollicitation en envoyant son adresse IPv6 ainsi que son adresse MAC complète. Dans le cas où l'adresse IPv6 serait identique à celle convoitée par notre poste qui démarre, il y aurait alors conflit et l'auto-configuration ne pourrait se faire.
Vous aimeriez ben savoir ce qu'il se passerait si, par un hasard extraordinaire, l'adresse construite à partir de l'adresse MAC était déjà en service sur le lien ? Rien de plus simple ! Faisons la manip. Nous allons exploiter la possibilité du multi-adressage d'un nœud pour attribuer à la machine « espion » l'adresse convoitée par le nouvel arrivant.
Sur la machine munie du « Wireshark » (la commande « ip -6 » fonctionne avec IP v6 exactement comme la commande « ip » le fait avec IP v4) :
# ip -6 addr add fe80::20d:88ff:fe37:73e9/64 dev eth0
Vérification :
# ifconfig eth0
eth0 Lien encap:Ethernet HWaddr 00:10:B5:40:B7:04
adr inet6: fe80::210:b5ff:fe40:b704/64 Scope:Lien
adr inet6: fe80::20d:88ff:fe37:73e9/64 Scope:Lien
...
Voyons maintenant le démarrage de notre cobaye :
No. Time Source Destination Protocol Info
1 0.000000 :: ff02::1:ff37:73e9 ICMPv6 Neighbor solicitation
2 0.000077 fe80::20d:88ff:fe37:73e9 ff02::1 ICMPv6 Neighbor advertisement
Si la première trame est identique au cas précédent, nous observons ici une réponse « Neighbor advertisement » de fe80::20d:88ff:fe37:73e9 (l'adresse que nous avons manuellement ajoutée à notre espion). Le processus s'arrête là, il n'y a pas de découverte de routeurs et pour cause, notre cobaye n'a pu auto-configurer son interface.
Voyons le détail de la trame 2 :
Frame 2 (86 bytes on wire, 86 bytes captured) ... Ethernet II, Src: AcctonTe_40:b7:04 (00:10:b5:40:b7:04), Dst: IPv6-Neighbor-Discovery_00:00:00:01 (33:33:00:00:00:01) Destination: IPv6-Neighbor-Discovery_00:00:00:01 (33:33:00:00:00:01) Address: IPv6-Neighbor-Discovery_00:00:00:01 (33:33:00:00:00:01) .... ...1 .... .... .... .... = IG bit: Group address (multicast/broadcast) .... ..1. .... .... .... .... = LG bit: Locally administered address (this is NOT the factory default) Source: AcctonTe_40:b7:04 (00:10:b5:40:b7:04) Address: AcctonTe_40:b7:04 (00:10:b5:40:b7:04) .... ...0 .... .... .... .... = IG bit: Individual address (unicast) .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default) Type: IPv6 (0x86dd) Internet Protocol Version 6 0110 .... = Version: 6 .... 0000 0000 .... .... .... .... .... = Traffic class: 0x00000000 .... .... .... 0000 0000 0000 0000 0000 = Flowlabel: 0x00000000 Payload length: 32 Next header: ICMPv6 (0x3a) Hop limit: 255 Source: fe80::20d:88ff:fe37:73e9 (fe80::20d:88ff:fe37:73e9) Destination: ff02::1 (ff02::1) Internet Control Message Protocol v6 Type: 136 (Neighbor advertisement) Code: 0 Checksum: 0x72ec [correct] Flags: 0xa0000000 1... .... .... .... .... .... .... .... = Router .0.. .... .... .... .... .... .... .... = Not adverted ..1. .... .... .... .... .... .... .... = Override Target: fe80::20d:88ff:fe37:73e9 (fe80::20d:88ff:fe37:73e9) ICMPv6 Option (Target link-layer address) Type: Target link-layer address (2) Length: 8 Link-layer address: 00:10:b5:40:b7:04
Notre espion signale par un message ICMP de type 136 que l'adresse IPv6 fe80::20d:88ff:fe37:73e9
est attachée à l'interface dont l'adresse MAC est 00:10:b5:40:b7:04
. Ce message est envoyé à tous les hôtes du réseau (ff02::1
, ce qui correspond à l'adresse MAC multicast 33:33:00:00:00:01
). Notre postulant à l'adresse IPv6 fe80::20d:88ff:fe37:73e9
en est donc informé.
Voyons l'état de la configuration IP v6 du cobaye :
2: eth0:mtu 1500 qlen 1000 inet6 fe80::20d:88ff:fe37:73e9/64 scope link tentative valid_lft forever preferred_lft forever
Le « scope link » que nous observions tout à l'heure s'est transformé en « scope link tentative ». Autrement dit, cette adresse ne sera pas exploitable, l'hôte n'est pas configuré.
Moralité : En cas de duplication d'adresse, le processus d'auto-configuration montre ses limites. Dans un tel cas, nous devrons résoudre manuellement le conflit.
Notez aussi au passage que tout ceci ressemble furieusement à ce que fait ARP en IPv4. Mais ici, c'est de l'ICMP.
A priori, il n'y a pas de problèmes, dans la mesure où la construction de l'adresse se fait à partir de l'adresse MAC. Nous devrions trouver deux adresses IPv6 différentes :
eth0 Link encap:Ethernet HWaddr 00:10:b5:40:b7:04 adr inet6: fe80::210:b5ff:fe40:b704/64 Scope:Lien ... eth1 Link encap:Ethernet HWaddr 00:0c:6e:63:e6:ed inet adr:192.168.10.30 Bcast:192.168.10.255 Masque:255.255.255.0 adr inet6: fe80::20c:6eff:fe63:e6ed/64 Scope:Lien ...
C'est bien, c'est comme on avait prévu
Il y a plusieurs façons d'afficher les routes IPv6, dont la classique commande « route », avec quelques aménagements :
~# route -A inet6 Table de routage IPv6 du noyau Destination Next Hop Flag Met Ref Use If ::1/128 :: Un 0 1 4 lo fe80::/128 :: Un 0 2 0 lo fe80::/128 :: Un 0 2 0 lo fe80::20c:6eff:fe63:e6ed/128 :: Un 0 1 0 lo fe80::210:b5ff:fe40:b704/128 :: Un 0 1 0 lo fe80::/64 :: U 256 0 0 eth1 fe80::/64 :: U 256 0 0 eth0 ff00::/8 :: U 256 0 0 eth1 ff00::/8 :: U 256 0 0 eth0 ::/0 :: !n -1 1 1 lo
Pour l'instant contentons-nous de noter ceci : la route pour fe080::/64
peut passer aussi bien par eth0 que par eth1…
Nous avons sur un même lien local deux nœuds auto-configurés en IPv6 :
fe80::20c:6eff:fe63:e6ed
;fe80::21b:11ff:fe52:bfab
(sur eth0).
Depuis ce dernier nœud, nous tentons un ping (ipv6) sur fe80::20c:6eff:fe63:e6ed
:
~$ ping6 -c4 fe80::20c:6eff:fe63:e6ed connect: Invalid argument
Pourquoi tant de haine ?
La remarque préalable sur les routes n'a pas été faite par hasard. Avec les adresses de type lien local, il faut préciser sur quelle interface nous désirons travailler. La commande ping6
propose diverses syntaxes. La plus courte est sans doute :
ping 6 <adresse de la cible>%ethx
Voyons ceci :
:~$ ping6 -c4 fe80::20c:6eff:fe63:e6ed%eth0
PING fe80::20c:6eff:fe63:e6ed%eth0(fe80::20c:6eff:fe63:e6ed) 56 data bytes
64 bytes from fe80::20c:6eff:fe63:e6ed: icmp_seq=1 ttl=64 time=3.54 ms
64 bytes from fe80::20c:6eff:fe63:e6ed: icmp_seq=2 ttl=64 time=0.121 ms
64 bytes from fe80::20c:6eff:fe63:e6ed: icmp_seq=3 ttl=64 time=0.123 ms
64 bytes from fe80::20c:6eff:fe63:e6ed: icmp_seq=4 ttl=64 time=0.120 ms
--- fe80::20c:6eff:fe63:e6ed%eth0 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3002ms
rtt min/avg/max/mdev = 0.120/0.976/3.543/1.482 ms
Nettement plus efficace. Nous verrons plus loin que cette limitation n'intervient pas avec des adresses de type global.