MAC Address – Why First Octet Ends with Binary 0

ipip addressipv6mac addressprotocol-theory

I stumbled upon a piece of code on GitHub: https://github.com/adeverteuil/bash-ula-generator/blob/master/gen-ula.sh

# Generate an EUI64 from the MAC address
# as described in RFC 3513
# https://tools.ietf.org/html/rfc3513

first=`echo $mac | cut -c1-1`
second=`echo $mac | cut -c2-2`
macu=`echo $mac | cut -c3-6`
macl=`echo $mac | cut -c7-12`

# reversing u/l bit
case $second in
    [13579bdf])
        die "MAC-address \"${mac}\" is a group MAC address"
        ;;
    0)
        second_rev=2
        ;;
    2)
        second_rev=0
        ;;
    4)
        second_rev=6;
        ;;
    6)
        second_rev=4;
        ;;
    8)
        second_rev=a;
        ;;
    a)
        second_rev=8;
        ;;
    c)
        second_rev=e;
        ;;
    e)
        second_rev=c;
        ;;
    *)
        #impossible
        die "MAC address \"${mac}\" is registered to the IEEE database, "\
            "but the first octet (${first}${second}) is regarded as invalid. "\
            "(probably a bug in this script...)"
esac
eui64="${first}${second_rev}${macu}fffe${macl}"

TLDR: While reversing the 7th bit of the MAC OUI to create an EUI-64, the author assumes that the 8th bit is always binary 0. I immediately check more than 100 clients on my DHCP server and strangely enough, none ends with an odd number on the first octet — they are always something like:

  • dc:0c:5c:c9:53:36
  • 40:9f:38:4b:69:08
  • 18:d7:17:55:61:d1
  • 34:c3:d2:70:ad:be
  • (and so on…)

Why it always end with a binary 0?

Best Answer

You may notice that two least-significant bits of the most-significant byte of a 48-bit MAC address are usually set to 0 (as in all your examples). There are two flags in the most-significant byte of the OUI (Organizationally Unique Identifier, which are the most-significant 24-bits) part of the MAC address:

  • The least-significant bit is the I/G (Individual/Group) flag. Having this bit clear means that the frame is sent to an individual host, and having it set means that it is intended for a group of hosts (broadcast or multicast).
  • The second-least-significant bit is the U/L (Universal/Local) flag. Having this bit clear means that the MAC address is universally assigned by the owner of the OUI (BIA, or Burned-In Address). If you locally assign the MAC address or override the BIA , then you are supposed to set this bit to mean that the MAC address is locally assigned. Unfortunately, many people who locally assign the MAC address do not set this flag.

While reversing the 7th bit of the MAC OUI to create an EUI-64, the author assumes that the 8th bit is always binary 0.

Actually, that is creating a Modified EUI-64. You would never assign a group address (I/G flag set) to an interface or unicast address, and you do set the U/L flag to show that it is a locally administered address. The Modified EUI-64 from 48-bit MAC algorithm (and others) is explained in RFC 4291, IP Version 6 Addressing Architecture, Appendix A: Creating Modified EUI-64 Format Interface Identifiers, which obsoleted RFC 3513, IP Version 6 Addressing Architecture to which your code example refers. Basically, you split the 48-bit MAC address in half, insert fffe in the middle, and set the U/L flag to indicate a locally administered address (see my highlights below, including the note at the end):

Appendix A: Creating Modified EUI-64 Format Interface Identifiers

Depending on the characteristics of a specific link or node, there are a number of approaches for creating Modified EUI-64 format interface identifiers. This appendix describes some of these approaches.

Links or Nodes with IEEE EUI-64 Identifiers

The only change needed to transform an IEEE EUI-64 identifier to an interface identifier is to invert the "u" (universal/local) bit. An example is a globally unique IEEE EUI-64 identifier of the form:

|0              1|1              3|3              4|4              6|
|0              5|6              1|2              7|8              3|
+----------------+----------------+----------------+----------------+
|cccccc0gcccccccc|ccccccccmmmmmmmm|mmmmmmmmmmmmmmmm|mmmmmmmmmmmmmmmm|
+----------------+----------------+----------------+----------------+

where "c" is the bits of the assigned company_id, "0" is the value of the universal/local bit to indicate universal scope, "g" is individual/group bit, and "m" is the bits of the manufacturer- selected extension identifier. The IPv6 interface identifier would be of the form:

|0              1|1              3|3              4|4              6|
|0              5|6              1|2              7|8              3|
+----------------+----------------+----------------+----------------+
|cccccc1gcccccccc|ccccccccmmmmmmmm|mmmmmmmmmmmmmmmm|mmmmmmmmmmmmmmmm|
+----------------+----------------+----------------+----------------+

The only change is inverting the value of the universal/local bit.

Links or Nodes with IEEE 802 48-bit MACs

[EUI64] defines a method to create an IEEE EUI-64 identifier from an IEEE 48-bit MAC identifier. This is to insert two octets, with hexadecimal values of 0xFF and 0xFE (see the Note at the end of appendix), in the middle of the 48-bit MAC (between the company_id and vendor-supplied id). An example is the 48-bit IEEE MAC with Global scope:

|0              1|1              3|3              4|
|0              5|6              1|2              7|
+----------------+----------------+----------------+
|cccccc0gcccccccc|ccccccccmmmmmmmm|mmmmmmmmmmmmmmmm|
+----------------+----------------+----------------+

where "c" is the bits of the assigned company_id, "0" is the value of the universal/local bit to indicate Global scope, "g" is individual/group bit, and "m" is the bits of the manufacturer- selected extension identifier. The interface identifier would be of the form:

|0              1|1              3|3              4|4              6|
|0              5|6              1|2              7|8              3|
+----------------+----------------+----------------+----------------+
|cccccc1gcccccccc|cccccccc11111111|11111110mmmmmmmm|mmmmmmmmmmmmmmmm|
+----------------+----------------+----------------+----------------+

When IEEE 802 48-bit MAC addresses are available (on an interface or a node), an implementation may use them to create interface identifiers due to their availability and uniqueness properties.

Links with Other Kinds of Identifiers

There are a number of types of links that have link-layer interface identifiers other than IEEE EUI-64 or IEEE 802 48-bit MACs. Examples include LocalTalk and Arcnet. The method to create a Modified EUI-64 format identifier is to take the link identifier (e.g., the LocalTalk 8-bit node identifier) and zero fill it to the left. For example, a LocalTalk 8-bit node identifier of hexadecimal value 0x4F results in the following interface identifier:

|0              1|1              3|3              4|4              6|
|0              5|6              1|2              7|8              3|
+----------------+----------------+----------------+----------------+
|0000000000000000|0000000000000000|0000000000000000|0000000001001111|
+----------------+----------------+----------------+----------------+

Note that this results in the universal/local bit set to "0" to indicate local scope.

Links without Identifiers

There are a number of links that do not have any type of built-in identifier. The most common of these are serial links and configured tunnels. Interface identifiers that are unique within a subnet prefix must be chosen.

When no built-in identifier is available on a link, the preferred approach is to use a universal interface identifier from another interface or one that is assigned to the node itself. When using this approach, no other interface connecting the same node to the same subnet prefix may use the same identifier.

If there is no universal interface identifier available for use on the link, the implementation needs to create a local-scope interface identifier. The only requirement is that it be unique within a subnet prefix. There are many possible approaches to select a subnet-prefix-unique interface identifier. These include the following:

  Manual Configuration  
  Node Serial Number  
  Other Node-Specific Token  

The subnet-prefix-unique interface identifier should be generated in a manner such that it does not change after a reboot of a node or if interfaces are added or deleted from the node.

The selection of the appropriate algorithm is link and implementation dependent. The details on forming interface identifiers are defined in the appropriate "IPv6 over " specification. It is strongly recommended that a collision detection algorithm be implemented as part of any automatic algorithm.

Note: [EUI-64] actually defines 0xFF and 0xFF as the bits to be inserted to create an IEEE EUI-64 identifier from an IEEE MAC- 48 identifier. The 0xFF and 0xFE values are used when starting with an IEEE EUI-48 identifier. The incorrect value was used in earlier versions of the specification due to a misunderstanding about the differences between IEEE MAC-48 and EUI-48 identifiers.

This document purposely continues the use of 0xFF and 0xFE because it meets the requirements for IPv6 interface identifiers (i.e., that they must be unique on the link), IEEE EUI-48 and MAC-48 identifiers are syntactically equivalent, and that it doesn't cause any problems in practice.