The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NetAddr::MAC - Handles hardware MAC Addresses (EUI-48 and EUI-64)

VERSION

version 0.94

SYNOPSIS

    use NetAddr::MAC;

    my $mac = NetAddr::MAC->new( '00:11:22:aa:bb:cc' );
    my $mac = NetAddr::MAC->new( mac => '0011.22AA.BBCC' );

    print "MAC provided at object creation was: ", $mac->original;

    print "EUI48\n" if $mac->is_eui48;
    print "EUI64\n" if $mac->is_eui64;

    print "Unicast\n" if $mac->is_unicast;
    print "Multicast\n" if $mac->is_multicast;
    print "Broadcast\n" if $mac->is_broadcast;

    print "Locally Administerd\n" if $mac->is_local;
    print "Universally Administered\n" if $mac->is_universal;

    print 'Basic Format: ',$mac->as_basic,"\n";
    print 'Bpr Format: ',  $mac->as_bpr,"\n";
    print 'Cisco Format: ',$mac->as_cisco,"\n";
    print 'IEEE Format: ', $mac->as_ieee,"\n";
    print 'IPv6 Address: ',$mac->as_ipv6_suffix,"\n";
    print 'Microsoft Format: ',$mac->as_microsoft,"\n";
    print 'Single Dash Format: ',$mac->as_singledash,"\n";
    print 'Sun Format: ',  $mac->as_sun,"\n";
    print 'Token Ring Format: ', $mac->as_tokenring,"\n";


    use NetAddr::MAC qw( :all );

    my $mac = q/00.11.22.33.44.55/;

    print "EUI48\n" if mac_is_eui48($mac);
    print "EUI64\n" if mac_is_eui64($mac);

    print "Unicast\n" if mac_is_unicast($mac);
    print "Multicast\n" if mac_is_multicast($mac);
    print "Broadcast\n" if mac_is_broadcast($mac);

    print "Locally Administerd\n" if mac_is_local($mac);
    print "Universally Administered\n" if mac_is_universal($mac);

    print 'Basic Format: ',mac_as_basic($mac),"\n";
    print 'Bpr Format: ',  mac_as_bpr($mac),"\n";
    print 'Cisco Format: ',mac_as_cisco($mac),"\n";
    print 'IEEE Format: ', mac_as_ieee($mac),"\n";
    print 'IPv6 Address: ',mac_as_ipv6_suffix($mac),"\n";
    print 'Microsoft Format: ',mac_as_microsoft($mac),"\n";
    print 'Single Dash Format: ', mac_as_singledash($mac),"\n";
    print 'Sun Format: ',  mac_as_sun($mac),"\n";
    print 'Token Ring Format: ',mac_as_tokenring($mac),"\n";

DESCRIPTION

This module provides an interface to deal with Media Access Control (or MAC) addresses. These are the addresses that uniquely identify a device on various layer 2 networks. Although the most common case is hardware addresses on Ethernet network cards, there are a variety of devices that use this system of addressing.

This module supports both EUI-48 and EUI-64 addresses and implements an OO and a functional interface.

Some networks that use EUI-48 (or MAC-48) addresses include:

    Ethernet
    802.11 wireless networks
    Bluetooth
    IEEE 802.5 token ring
    FDDI
    ATM

Some networks that use EUI-64 addresses include:

    Firewire
    IPv6 (sort of)
    ZigBee / 802.15.4 wireless personal-area networks

OO METHODS

NetAddr::MAC->new( mac => $mac )

Creates and returns a new NetAddr::MAC object. The MAC value is required.

NetAddr::MAC->new( mac => $mac, %options )

As above, but %options may include any or none of the following

  • die_on_error

    If set to true, errors will result in a die (croak) rather than populating $errstr

    Take care when using the mac_is_* functions! they will return false in both the case of an error and according to the properties of the MAC address. You will therefore need to enable die_on_error or check $errstr when false is returned.

  • priority

    This is the bridge priority as an integer, which can also be set by providing a mac address in the following format, where 60 is the priority.

     60#0011.22aa.bbcc

    This is a cisco thing, so typically the above is the format you would see. But we are flexible enough to handle formats like...

     60#00:11:22:aa:bb:cc
     60#001122aabbcc
     60#00-11-22-aa-bb-cc
     etc.

    If priority is provided as an option and as part of the mac address string, an error will occur only if they differ.

    Priority defaults to 0 if not provided.

NetAddr::MAC->new( $mac )

Simplified creation method

NetAddr::MAC->new( $mac, %options )

As above but with %options

original

returns the original mac string as used when creating the MAC object

oui

returns the mac address's Organizationally Unique Identifier (OUI) with dashes in Hexadecimal / Canonical format:

 AC-DE-48

errstr

returns the error (if one occured).

This is intended for use with the object. Its not exported at all.

Note: this method is used once the NetAddr::MAC object is successfully created. For now the to_eui48 method is the only method that will return an error once the object is created.

When creating objects, you will need to catch errors with either the or function, or the eval way.

OO PROPERTY METHODS

is_eui48

returns true if mac address is determined to be of the EUI48 standard

is_eui64

returns true if mac address is determined to be of the EUI64 standard

is_multicast

returns true if mac address is determined to be a multicast address

is_broadcast

returns true if mac address is determined to be a broadcast address

is_vrrp

returns true if mac address is determined to be a Virtual Router Redundancy (VRRP) address

ie. 00-00-5E-00-01-XX

always returns false for eui64.

I'm not quite sure what to do with 01-00-5E-00-00-12, suggestions welcomed.

is_hsrp

returns true if mac address is determined to be a Hot Standby Router (HSRP) address

ie. 00-00-0C-07-AC-XX

always returns false for eui64.

is_hsrp2

returns true if mac address is determined to be a Hot Standby Router Version 2 (HSRPv2) address

ie. 00-00-0C-9F-FX-XX

always returns false for eui64.

is_msnlb

returns true if mac address is determined to be a MS Network Load Balancing MAC address

ie. 02-BF-1-2-3-4 for unicast or 03-BF-1-2-3-4 for multicast

where 1-2-3-4 is the clusters primary IP address

for outbound packets, clusters members will send from 02-n-1-2-3-4 where n is the node priorty. this function does NOT return true for those adddresses.

always returns false for eui64.

is_unicast

returns true if mac address is determined to be a unicast address

is_local

returns true if mac address is determined to be locally administered

is_universal

returns true if mac address is determined to be universally administered

OO NORMALIZATION METHODS

as_basic

returns the mac address normalized as a hexidecimal string that is 0 padded and without delimiters

 001122aabbcc

as_bridge_id

returns mac address with the priority, a hash, then the mac address normalized with as_cisco

 45#0011.22aa.bbcc

as_bpr

returns the mac address normalized as a hexidecimal string that is 0 padded with : delimiters and with 1,length leading where length is the number of hex pairs (ie 6 for EUI48)

 1,6,00:11:22:aa:bb:cc

as_cisco

returns the mac address normalized as a hexidecimal string that is 0 padded and with . delimiting every 2nd octet (ie after every 4th character)

 0011.22aa.bbcc

as_ieee

returns the mac address normalized as a hexidecimal string that is 0 padded and with : delimiting every octet (ie after every 2nd character)

 00:34:56:78:9a:bc

as_ipv6_suffix

returns the EUI-64 address in the format used for an IPv6 autoconf address suffix

as_microsoft

returns the mac address normalized as a hexidecimal string that is 0 padded and with - delimiting every octet (ie after every 2nd character)

 00-34-56-78-9a-bc

as_pgsql

returns the mac address normalized as a hexidecimal string that is 0 padded and has a : in the middle of the hex string. this appears in the pgsql documentation along with the single dash version

 001122:334455

as_singledash

returns the mac address normalized as a hexidecimal string that is 0 padded and has a dash in the middle of the hex string. this appears in the pgsql documentation.

 001122-334455

as_sun

returns the mac address normalized as a hexidecimal string that is not padded and with - delimiting every octet (ie after every 2nd character)

 0-34-56-78-9a-bc

as_tokenring

returns the mac address normalized as a hexidecimal string that is 0 padded and with - delimiting every octet (ie after every 2nd character) and each octect is bit-reversed order. So 10 00 5A 4D BC 96 becomes 08 00 5A B2 3D 69.

 00-2d-6a-1e-59-3d

to_eui48

converts to EUI-48 (if the eui-64 was derived from eui-48)

this function will fail if the mac was not derived from eui-48. you will need to catch it and inspect the error message.

to_eui64

converts to EUI-64, or in other words encapsulates EUI-48 to become EUI-64 if needed

PROCEDURAL PROPERTY FUNCTIONS

mac_is_eui48($mac)

returns true if mac address in $mac is determined to be of the EUI48 standard

mac_is_eui64($mac)

returns true if mac address in $mac is determined to be of the EUI64 standard

mac_is_multicast($mac)

returns true if mac address in $mac is determined to be a multicast address

mac_is_broadcast($mac)

returns true if mac address in $mac is determined to be a broadcast address

mac_is_unicast($mac)

returns true if mac address in $mac is determined to be a unicast address

mac_is_vrrp($mac)

returns true if mac address is $mac is determined to be a Virtual Router Redundancy (VRRP) address

ie. 00-00-5E-00-01-XX

mac_is_hsrp($mac)

returns true if mac address is $mac is determined to be a Hot Standby Router (HSRP) address

ie. 00-00-0C-07-AC-XX

mac_is_hsrp2($mac)

returns true if mac address is $mac is determined to be a Hot Standby Router Version 2 (HSRPv2) address

ie. 00-00-0C-9F-FX-XX

mac_is_msnlb($mac)

returns true if mac address is $mac is determined to be a MS Network Load Balancing address

ie. 02-BF-XX-XX-XX-XX or 03-BF-XX-XX-XX-XX

mac_is_local($mac)

returns true if mac address in $mac is determined to be locally administered

mac_is_universal($mac)

returns true if mac address in $mac is determined to be universally administered

PROCEDURAL NORMALIZATION METHODS

mac_as_basic($mac)

returns the mac address in $mac normalized as a hexidecimal string that is 0 padded and without delimiters

 001122aabbcc

mac_as_bpr($mac)

returns the mac address in $mac normalized as a hexidecimal string that is 0 padded, with : delimiting and 1,length leading. length is the number of hex pairs (6 for EUI48)

 1,6,00:11:22:aa:bb:cc

mac_as_cisco($mac)

returns the mac address in $mac normalized as a hexidecimal string that is 0 padded and with . delimiting every 2nd octet (ie after every 4th character)

 0011.22aa.bbcc

mac_as_ieee($mac)

returns the mac address in $mac normalized as a hexidecimal string that is 0 padded and with : delimiting every octet (ie after every 2nd character)

 00:34:56:78:9a:bc

mac_as_ipv6_suffix($mac)

returns the mac address in $mac in the format used for an IPv6 autoconf address suffix

will convert from eui48 or eui64 if needed

mac_as_microsoft($mac)

returns the mac address in $mac normalized as a hexidecimal string that is 0 padded and with - delimiting every octet (ie after every 2nd character)

 00-34-56-78-9a-bc

mac_as_pgsql($mac)

returns the mac address in $mac normalized as a hexidecimal string that is 0 padded and a single : delimiter in the middle. this format appears in their documenation, along with single dash version

 003456:789abc

mac_as_singledash($mac)

returns the mac address in $mac normalized as a hexidecimal string that is 0 padded and has a dash in the middle of the hex string. this appears in the pgsql documenation

 001122-334455

mac_as_sun($mac)

returns the mac address in $mac normalized as a hexidecimal string that is not padded and with - delimiting every octet (ie after every 2nd character)

 0-34-56-78-9a-bc

mac_as_tokenring($mac)

returns the mac address in $mac normalized as a hexidecimal string that is 0 padded and with - delimiting every octet (ie after every 2nd character) and each octect is bit-reversed order. So 10 00 5A 4D BC 96 becomes 08 00 5A B2 3D 69.

 00-2d-6a-1e-59-3d

ERROR HANDLING

Prior to 0.8 every error resulted in a die (croak) which needed to be caught. As I have used this module more, having to catch them all the time is tiresome. So from 0.8 onwards, errors result in an undef and something being set.

For objects, this something is accessible via $self->errstr otherwise ther error is in $NetAddr::MAC::errstr;

If you would like to have die (croak) instead, you can either set the global $NetAddr::MAC::die_on_error or set the die_on_error option when creating an object. When creating objects, the provided option takes priority over the global. So if you set the global, then all objects will die - unless you specify otherwise.

Global examples

Normal behaviour...

  use NetAddr::MAC qw/mac_as_basic/;
  $mac = mac_as_basic('aaaa.bbbb.cccc')
      or die $NetAddr::MAC::errstr;

If you want to catch exceptions (die/croak's)...

  use NetAddr::MAC qw/mac_as_basic/;
  $NetAddr::MAC::die_on_error = 1; # (or ++ if you like)

  eval { # or use Try::Tiny etc.
      $mac = mac_as_basic('aaaa.bbbb.cccc');
  };
  if ($@) {
      # something bad happened, so handle it
  }
  # all good, so do something

Object examples

Normal behaviour...

  use NetAddr::MAC;
  my $obj = NetAddr::MAC->new( mac => 'aabbcc112233')
      or die $NetAddr::MAC::errstr;

  $mac = $obj->to_eui48
      or die $obj->errstr;

If you want to catch exceptions (die/croak's)...

  use NetAddr::MAC;
  my $obj = NetAddr::MAC->new( mac => 'aabbcc112233', die_on_error => 1 );

  eval { # or use Try::Tiny etc.
      $mac = $obj->to_eui48
  };
  if ($@) {
      # something bad happened, so handle it
  }
  # all good, so do something

Or do it globally

  use NetAddr::MAC;
  $NetAddr::MAC::die_on_error = 1; # (or ++ if you like)
  my $obj = NetAddr::MAC->new( mac => 'aabbcc112233');

  eval { # or use Try::Tiny etc.
      $mac = $obj->to_eui48
  };
  if ($@) {
      # something bad happened, so handle it

  }

CREDITS

Stolen lots of ideas and some pod content from Device::MAC and Net::MAC

TODO

 - moare tests!
 - find bugs, squash them
 - merge in your changes!

SUPPORT

Please use the RT system on CPAN to lodge bugs.

Many young people like to use Github, so by all means send me pull requests at

  https://github.com/djzort/NetAddr-MAC

AUTHOR

Dean Hamstead <dean@bytefoundry.com.au>

LICENSE

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

MOTIVATION

There are lots of systems at my (then) place of work which handle MAC addresses. There was lots of code validating and normalising them all over the place - most of it was quirky and sloppy. So I set about creating a reusable module to add to our SOE install so that MAC address handling would become consistent, reliable, powerful and trivial.

Generally speaking this module fulfills that goal. It's very convenient to be able to use MAC addresses in any format throughout those systems.

There are several other MAC address modules on CPAN. I didn't like the interface on one, the other dragged in Moose. So I created this module, taking the ideas I liked from the other two modules and adding in extra bits that I needed (and a few features just for completeness) whilst avoiding dependancies and avoiding anything that doesnt work on perl 5.6

I hope that the result is useful to others, the concept is to be able to create an object representing a MAC address based on a string that only very vaguely resembles a MAC address. From there, to be able to output normalised string representations of the mac address in a variety of common formats.

A templating function is deliberately omitted, as very niche outputs can easily be derived from the 'basic' format.

Feel free to send patches for features you add, I appreciate those who have done so far and endeavour to incoporate new patches ASAP.