Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

ddick (5726)

ddick
  (email not shown publicly)

I'm based out of Melbourne, Australia. I attend the excellent melbourne.pm.org meetings whenever i get the chance, which is not often enough.

Journal of ddick (5726)

Thursday July 26, 2007
01:28 AM

x/platform mac address retrieval?

[ #33886 ]
How to get a mac address from linux/solaris/aix/hpux/MSWin32? don't think this would be useful enough to send to cpan.org... but for future reference...

#! /usr/bin/perl -w

use strict;
use FileHandle();

MAIN: {
  my ($macAddress);
  if (($^O eq 'linux') || ($^O eq 'solaris') || ($^O eq 'hpux') || ($^O eq 'aix')) {

    $ENV{PATH} = '/sbin:/usr/sbin:/bin:/usr/bin';
    delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};

    my ($ifconfig) = new FileHandle();
    if (my $pid = $ifconfig->open('-|')) {
      my ($buffer);
      unless (defined $ifconfig->read($buffer, 8192)) {
        die("Failed to read from ifconfig:$!");
      }
      if (($^O eq 'linux') || ($^O eq 'solaris')) {
        # linux preceeded by HWaddr, solaris by ether
        if ($buffer =~ /(?:HWaddr +|ether +)([0-9A-Fa-f]{1,2}):([0-9A-Fa-f]{1,2}):([0-9A-Fa-f]{1,2}):([0-9A-Fa-f]{1,2}):([ 0-9A-Fa-f]{1,2}):([0-9A-Fa-f]{1,2})/) {
          $macAddress = formatMac($1, $2, $3, $4, $5, $6);
        }
      } elsif ($^O eq 'hpux') {
        if ($buffer =~ /^0x([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f] {2})([0-9A-Fa-f]{2}) +$/) {
          $macAddress = formatMac($1, $2, $3, $4, $5, $6);
        }
      } elsif ($^O eq 'aix') {
        if ($buffer =~ / +([0-9A-Fa-f]{1,2})\.([0-9A-Fa-f]{1,2})\.([0-9A-Fa-f]{1,2})\.([0-9A-Fa-f]{1,2})\ .([0-9A-Fa-f]{1,2})\.([0-9A-Fa-f]{1,2}) +/) {
          $macAddress = formatMac($1, $2, $3, $4, $5, $6);
        }
      }
      unless ($ifconfig->close()) {
        if (($^O eq 'linux') || ($^O eq 'solaris')) {
          die("Failed to successfully execute 'ifconfig -a':$!");
        } elsif ($^O eq 'hpux') {
          die("Failed to successfully execute 'lanscan -a':$!");
        } elsif ($^O eq 'aix') {
          die("Failed to successfully execute 'netstat -ia':$!");
        } else {
          die("Unknown failure when determining mac address for '$^O'");
        }
      }
    } elsif (defined $pid) {
      eval {
        if (($^O eq 'linux') || ($^O eq 'solaris')) {
          unless (exec({ 'ifconfig' } 'ifconfig', '-a')) {
            die("Failed to execute 'ifconfig -a':$!");
          }
        } elsif ($^O eq 'hpux') {
          unless (exec({ 'lanscan' } 'lanscan', '-a')) {
            die("Failed to execute 'lanscan -a':$!");
          }
        } elsif ($^O eq 'aix') {
          unless (exec({ 'netstat' } 'netstat', '-ia')) {
            die("Failed to execute 'netstat -ia':$!");
          }
        } else {
          die("Failed to find a command to produce the mac address for '$^O'");
        }
      };
      print STDERR $@;
      exit(1);
    } else {
      die("Failed to fork:$!");
    }
  } elsif ($^O eq 'MSWin32') {
    my ($ipconfig) = new FileHandle("ipconfig /all |");
    unless ($ipconfig) {
      die("Failed to 'ipconfig /all':$!");
    }
    my ($buffer);
    unless (defined $ipconfig->read($buffer, 8192)) {
      die("Failed to read from ipconfig:$!");
    }
    if ($buffer =~ /^ +Physical Address(?:\. )+: ([0-9A-Fa-f]{1,2})\-([0-9A-Fa-f]{1,2})\-([0-9A-Fa-f]{1,2})\-([0-9A-Fa-f]{1,2})\- ([0-9A-Fa-f]{1,2})\-([0-9A-Fa-f]{1,2})/m) {
      $macAddress = formatMac($1, $2, $3, $4, $5, $6);
    }
    unless ($ipconfig->close()) {
      die("Failed to close 'ipconfig /all':$!");
    }
  } else {
    die("'$^O' cannot be recognised");
  }
  print "mac address is $macAddress\n";
}

sub formatMac {
  my (@octets) = @_;
  return join(':', map { sprintf('%.2X', hex($_)) } @_);
}

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • This is a really good start, but what I'd really like to have is a hash of interfaces and their MACs. Right now I have at least two MACs on my laptop: wireless card and cabled-ethernet.
    • Yeah, this started as a way to uniquely identify a computer... GUID/MessageID sort of thingy
    • #! /usr/bin/perl -w

      use strict;
      use FileHandle();

      MAIN: {
        my ($mac_address) = {};
        if (($^O eq 'linux') || ($^O eq 'solaris') || ($^O eq 'hpux') || ($^O eq 'aix')) {

          $ENV{PATH} = '/sbin:/usr/sbin:/bin:/usr/bin';
          delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};

          my ($ifconfig) = new FileHandle();
          if (my $pid = $ifconfig->open('-|')) {
            my ($buffer);
            unless (defined $ifconfig->read($buffer, 8192)) {