Stories
Slash Boxes
Comments

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)) {