10

We know that we can use the MAC address to create an interface identifier, e.g. for a link-local IPv6 address which should be unique in the Network.

The image shows the way to do this:

Create interface identifier from MAC address

My questions are:

  • How can I create an IPv6 address from a MAC using awk or sed?
  • OR is there any command that gives me the link-local IPv6 address for a specific MAC (something like that createIPv6 myMAC)?
  • I rephrased your question a bit (pending review). IPv6 addresses are not extracted from MAC addresses, but created. And here you deal only with the interface identifier part (the last 64 bit) of an IPv6 address. But I'm not sure: Do you only want the interface identifier or a whole IPv6 address? Please re-edit, if I did not understand you correctly. – Dubu Jun 12 '14 at 7:34
  • @Dubu, Thanks for editing, I want the whole IPv6 address. – Networker Jun 12 '14 at 11:13
10

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.

4

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.

  • 1
    what about reverse the 7-th bit ! – Networker Jun 11 '14 at 22:52
  • Ah the U/L bit, good point! – HBruijn Jun 11 '14 at 23:04
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:])
0

You can create a bash function (and place it in your ~/.bashrc) that uses IFS to split the MAC address into 6 colon-separated groups and assembles them. You'll also need to flip the 7th most significant bit, i.e. bit 1 of the first byte:

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

Usage example:

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.