Bash Function to Canonicalize MAC Addresses

I was playing with some network related stuff this evening and needed to rewrite MAC addresses to the canonical form. That is, something like this 00-02-DE-AD-BE-EF. Why, you ask? Well every piece of software seems to have their own ideas on how to represent these magical 48 bit integers. For instance, you’ll often see something like 01:02:03:C0:FF:EE, which might also be written in shorthand as 1:2:3:c0:ff:ee or as a (pretty Cisco specific) perversion like 0102.03c0:ffee.

Indeed, a lot of variation…which makes parsing, a bit hellish.

Well I had written a pretty elegant parser in Perl before, that thing groks almost anything that you can throw at it. But today I wanted to implement this in hesschlib, hesschlib is my somewhat private library of practical Bash functions.

One of the rules I made for hesschlib is that things should be done in Bash whenever possible. So I kludged up a small Bash function that does a pretty good job in rewriting most forms of MAC addresses that came to mind to the canonical form. Here it is:

# canonicalize MAC addresses (does grok most forms)
function maccanon {
    canon=''; for octet in ${1//[\.:-]/ }; do
        [ ${#octet} -eq 4 ] && octet="${octet:0:2} ${octet:2:2}" ;
        [ ${#octet} -eq 1 ] && octet="0${octet}"; canon=${canon}${canon:+ }${octet};
    done; echo ${canon// /-};

Which is a one-liner in hesschlib of course, but broken up a bit here to make it more legible.

And finally, here’s an example of maccanon in action:

hessch@turing:~$ for mac in 00:02:DE:AD:BE:EF 1:2:3:c0:ff:ee 0102.03c0:ffee
> do
> maccanon ${mac}
> done