Version 1 of How to discover my active MAC Addresses?

Updated 2014-12-08 23:11:02 by EF

To find the list of active MAC Addresses, the following can be useful. In that context, active means bound to a working IP address. The script below has been tested on Linux, Windows and Mac. On the Linux and Mac platforms, there might be a number of virtual interfaces, these are filtered away using the patterns. This idea could also be imported into the Windows implementation.

proc mac.windows {} {
    set macs {}

    set cmd [concat [auto_execok ipconfig] /all]
    set section {}
    if { [catch {eval [linsert $cmd 0 exec]} res] == 0 } {
        foreach l [split $res "\n\r"] {
            if { [string trim $l] ne "" } {
                if { ![string is space [string index $l 0]] } {
                    if { [llength $section] > 0 } {
                        set mac ""
                        set ip4 ""
                        foreach s $section {
                            if { [regexp {([0-9a-fA-F][0-9a-fA-F][\-:]){5}[0-9a-fA-F][0-9a-fA-F]$} $s m] } {
                                set mac $m
                            }
                            if { [regexp -nocase -- {.*ipv4.*?:\s*((\d{1,3}.){3}\d{1,3})} $s m i] } {
                                set ip4 $i
                            }
                            if { $ip4 ne "" && $mac ne "" } {
                                lappend macs $mac
                                break
                            }
                        }
                    }
                    set section {}
                } else {
                    lappend section [string trim $l]
                }
            }
        }
    }
    return $macs
}


proc mac.unix { {ptns {"eth*" "wlan*" "en*"}}} {
    set macs {}

    set cmd [concat [auto_execok ifconfig] -a]
    set section {}
    if { [catch {eval [linsert $cmd 0 exec]} res] == 0 } {
        foreach l [split $res "\n\r"] {
            if { [string trim $l] ne "" } {
                if { ![string is space [string index $l 0]] } {
                    set mac [mac.unix.section $ptns $section]
                    if { $mac ne "" } {
                        lappend macs $mac
                    }
                    set section $l
                } else {
                    lappend section [string trim $l]
                }
            }
        }
        set mac [mac.unix.section $ptns $section]
        if { $mac ne "" } {
            lappend macs $mac
        }
    }
    return $macs
}

proc mac.unix { {ptns {"eth*" "wlan*" "en*"}}} {
    set macs {}

    set cmd [concat [auto_execok ifconfig] -a]
    set section {}
    if { [catch {eval [linsert $cmd 0 exec]} res] == 0 } {
        foreach l [split $res "\n\r"] {
            if { [string trim $l] ne "" } {
                if { ![string is space [string index $l 0]] } {
                        set mac [mac.unix.section $ptns $section]
                        if { $mac ne "" } {
                        lappend macs $mac
                        }
                    set section $l
                } else {
                    lappend section [string trim $l]
                }
            }
        }
                        set mac [mac.unix.section $ptns $section]
                        if { $mac ne "" } {
                        lappend macs $mac
                        }
    }
    return $macs
}

proc mac {} {
    global tcl_platform

    if { $tcl_platform(platform) eq "windows" } {
        return [mac.windows]
    } else {
        return [mac.unix]
    }
}
puts "[mac]"