How to use shell to derive an IPv6 address from a MAC address?

If you want to create a whole IPv6 address from a MAC (and a given prefix), you could use the excellent ipv6calc tool by Peter Bieringer.

The following command creates a link-local IPv6 address (fe80:: prefix) from a MAC address:

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

You can leave most of the options away and let the command guess what to do:

$ 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

For Debian distros, ipv6calc is in the main repository.


From the IPv6 Wikipedia entry a more textual description:

A 64-bit interface identifier is most commonly derived from its 48-bit MAC address.

A MAC address 00:0C:29:0C:47:D5 is turned into a 64-bit EUI-64 by inserting FF:FE in the middle: 00:0C:29:FF:FE:0C:47:D5.

So replacing the third : with :FF:FE: should do the trick:

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

No idea if that syntax is specific to GNU sed.


Work in progress:

Convert that to bits:

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

should result in the bits 00000000 00001100 00101001 11111111 11111110 00001100 01000111 11010101 leaving only the flipping of bit number 7.


#! /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:])