Como usar o shell para derivar um endereço IPv6 de um endereço MAC?

11

Sabemos que podemos usar o endereço MAC para criar um identificador de interface, por exemplo, para um endereço IPv6 local de link que deve ser exclusivo na rede.

A imagem mostra a maneira de fazer isso:

Criar identificador de interface a partir do endereço MAC

Minhas perguntas são:

  • Como posso criar um endereço IPv6 a partir de um MAC usando awkou sed?
  • OU existe algum comando que me forneça o endereço IPv6 local do link para um MAC específico (algo assim createIPv6 myMAC)?
Nidal
fonte
Eu reformulei sua pergunta um pouco (revisão pendente). Os endereços IPv6 não são extraídos dos endereços MAC, mas criados. E aqui você lida apenas com a parte identificadora da interface (os últimos 64 bits) de um endereço IPv6. Mas não tenho certeza: você deseja apenas o identificador de interface ou um endereço IPv6 inteiro? Edite novamente se eu não o entendi corretamente.
Dubu
@ Dubu, Obrigado pela edição, quero todo o endereço IPv6.
Nidal

Respostas:

10

Se você deseja criar um endereço IPv6 inteiro a partir de um MAC (e um determinado prefixo), você pode usar a excelente ipv6calcferramenta de Peter Bieringer.

O comando a seguir cria um endereço IPv6 local de link ( fe80::prefixo) a partir de um endereço MAC:

$ ipv6calc --action prefixmac2ipv6 --in prefix+mac --out ipv6addr fe80:: 00:21:5b:f7:25:1b
fe80::221:5bff:fef7:251b

Você pode deixar a maioria das opções de lado e deixar o comando adivinhar o que fazer:

$ ipv6calc --in prefix+mac fe80:: 00:21:5b:f7:25:1b
No action type specified, try autodetection...found type: prefixmac2ipv6
fe80::221:5bff:fef7:251b

Para distribuições Debian, ipv6calcestá no repositório principal.

Dubu
fonte
4

Na entrada da Wikipedia IPv6, uma descrição mais textual:

Um identificador de interface de 64 bits é mais comumente derivado de seu endereço MAC de 48 bits.

Um endereço MAC 00: 0C: 29: 0C: 47: D5 é transformado em um EUI-64 de 64 bits inserindo FF: FE no meio: 00: 0C: 29: FF: FE: 0C: 47: D5.

Portanto, substituir o terceiro :por :FF:FE:deve fazer o truque:

echo  00:0C:29:0C:47:D5 | sed s/:/:FF:FE:/3
00:0C:29:FF:FE:0C:47:D5

Não faço ideia se essa sintaxe é específica para o GNU sed.


Trabalho em progresso:

Converta isso em bits:

for HEX in $(tr ":" " " <<< 00:0C:29:FF:FE:0C:47:D5) 
  do 
    printf "%08d " $(bc <<< "ibase=16;obase=2;$HEX") 
  done

deve resultar nos bits 00000000 00001100 00101001 11111111 11111110 00001100 01000111 11010101deixando apenas o lançamento do número 7.

HBruijn
fonte
1
Que tal reverter o 7-bit!
Nidal
Ah, o pouco U / L, bom ponto!
HBruijn
3
#! /usr/bin/env python
import sys
n=[int(x, 16) for x in sys.argv[1].split(":")]
print "fe80::%02x%02x:%02xff:fe%02x:%02x%02x" % tuple([n[0]^2]+n[1:])
Martin Wilck
fonte
0

Você pode criar uma função bash (e colocá-la no seu ~/.bashrc) que usa IFSpara dividir o endereço MAC em 6 grupos separados por dois pontos e montá-los. Você também precisará inverter o sétimo bit mais significativo, ou seja, o bit 1 do primeiro byte:

mac_to_ipv6_ll() {
    IFS=':'; set $1; unset IFS
    echo "fe80::$(printf %02x $((0x$1 ^ 2)))$2:${3}ff:fe$4:$5$6"
}

Exemplo de uso:

$ mac_to_ipv6_ll 12:34:56:78:90:12
fe80::1034:56ff:fe78:9012
rubo77
fonte
0

Devo dar os parabéns ao @ rubo77 acima para obter uma resposta de shell puro (a menos que você conte printf) acima, o que eu estava procurando.

Isso adiciona um pouco de sed a:

(a) elimine quaisquer zeros à esquerda em cada pedaço de 16 bits; e

(b) eliminar quaisquer outros pedaços totalmente zero no início do DIC

... conforme convenções comuns para a brevidade do endereço.

mac_to_eui64() {
 IFS=':'; set $1; unset IFS
 echo "fe80::$(printf %x $((0x$1 ^ 2)))$2:${3}ff:fe$4:$5$6" |
  sed -E 's/:0+/:/g; s/:{3,}/::/; s/:$/:0/'
}

Observe que, se você desejar refazê-lo para outros prefixos (arbitrários), que podem ser usados ​​em EUI-64 em qualquer escopo (embora seja recomendável não usá-lo para endereços globais por razões de privacidade), você precisará de um pouco script sed mais complicado. Isso ocorre porque o fe80::prefixo já contém três blocos de zero (elididos ao dois-pontos) adjacentes ao início do IID. Portanto, mesmo que o primeiro pedaço do IID seja totalmente zero (ou seja, se o MAC começou com 02:00), ele também seria eliminado. O formato EUI-64 deixa apenas mais um pedaço que pode ser zero - o último - que o script acima adiciona novamente como um único zero. Outros prefixos podem exigir que um deixe um único zero entre dois pontos.

Headbank
fonte
Você está certo, obrigado - voltei e deixei a multa do @ rubo77 printfsozinha e fiz as coisas adicionais no sed.
Headbank