Em primeiro lugar, você não precisa apenas dividir o MAC e inserir ff: fe, você também precisa inverter o 7º bit para representar corretamente um endereço universal / local.
Este script irá formatar corretamente um endereço IPv6 local de link com base em um endereço ether, incluindo a redução de zeros à esquerda.
#!/bin/bash
IFS=':'; set $1; unset IFS
printf "fe80::%x:%x:%x:%x\n" $(( 0x${1}${2} ^ 0x200 )) 0x${3}ff 0xfe${4} 0x${5}${6}
Exemplo de inversão de bits e redução de zero:
$ ether_to_ipv6 00:00:00:00:00:00
fe80::200:ff:fe00:0
$ ether_to_ipv6 11:11:11:11:11:11
fe80::1311:11ff:fe11:1111
Lembre-se também de que não é tecnicamente garantido que um link tenha um endereço que corresponda a esse algoritmo. Se houver uma colisão (maliciosa ou não), um novo endereço deve ser escolhido por um ou ambos. Implementações podem se comportar diferentemente de como isso é realmente tratado, então YMMV.
No entanto, se tudo o que você realmente está tentando fazer é obter uma lista de seus vizinhos reais (semelhante a arp
no IPv4), então existe uma maneira mais fácil. Use o protocolo de descoberta de vizinho (ndp).
Linux:
ip -6 neigh show
Solaris:
netstat -pf inet6
Mac OS X, AIX, * BSD:
ndp -a
JunOS, IOS, Vyatta:
show ipv6 neighbors
Cada um desses comandos mostrará uma lista de todos os vizinhos IPv6 ativos usando o ndp nativo.