Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

WIN32: Permanent & Current MAC Addresses

by cmv (Chaplain)
on Sep 24, 2007 at 19:47 UTC ( [id://640798]=sourcecode: print w/replies, xml ) Need Help??
Category: Networking Code
Author/Contact Info cmv
Description: Folks-

This is a script that will query all the available windows network device drivers for their current and permanent MAC addresses. The permanent address should be what the device driver reads from the device firmware, and so I don't believe is easily spoof-able. If that's not the case, please post here.

I got lots of help on this; thanks to everyone, and specifically:
pKai - For introducing me to wmic Re: WindowsRegistry{ServiceName} V.S. wmic{ServiceName}
almut - For his great ioctl code Re: Getting MAC Address(s) on Windows PCs

The MAC addresses reported by the driver are saved as $node{macPerm} and $node{macCurr} along with all the other information about the device.

Hope it comes in handy...

-Craig

UPDATE:
Oct-01-2007: Checking $nBytes from DeviceIoControl - avoids returning meaningless buffer stuff
Oct-02-2007: Providing correct size of packed OID query

use strict;

use Win32API::File qw(CreateFile DeviceIoControl :FILE_SHARE_ :Misc);
use Data::Dumper;

sub IOCTL_NDIS_QUERY_GLOBAL_STATS () { 0x17 << 16 | 2 };
sub OID_802_3_PERMANENT_ADDRESS   () { 0x01010101 };
sub OID_802_3_CURRENT_ADDRESS     () { 0x01010102 };

# This routine graciously provided by PerlMonk almut
# http://www.perlmonks.org/?node_id=580097
# http://www.perlmonks.org/?node_id=639099
sub NDIS_Query
{
    my ($handle, $oid) = @_;

    my $nBytes = 0;
    my $buf = "\0"x10;
    my $oidp = pack("L", $oid);

    DeviceIoControl($handle,
        IOCTL_NDIS_QUERY_GLOBAL_STATS(),
        $oidp, length($oidp),
        $buf, length($buf),
        $nBytes,
        [] );

    if($nBytes <= 0 ){return()}
    else {
        return join "-", unpack("(a2)*", unpack("H*", $buf) );
    }
}

# Get nic info via wmic (not available on all versions of windows)...
my @devs = split(/^\s*\cM\n/m, `wmic nicconfig list /format:value`);
shift(@devs);                    # Remove initial blank line

# Iterate through each device...
foreach my $d (@devs) {
    $d =~ s/\cM//g;                             # Grrrr, rotten window
+s
    my %node = split(/[=\n]/, $d);        # Hashify information

    # Make device to do the ioctl on...
    my $fname = '//./' . $node{SettingID};
    #print "f=$fname\n";
    my $fd = CreateFile($fname,
        0, FILE_SHARE_READ(), [], OPEN_EXISTING(), 0, []) || next;

    # Add info to current node...
    $node{macPerm}=NDIS_Query($fd, OID_802_3_PERMANENT_ADDRESS());
    $node{macCurr}=NDIS_Query($fd, OID_802_3_CURRENT_ADDRESS());

print Dumper(\%node);
}

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: sourcecode [id://640798]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (5)
As of 2024-04-19 07:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found