Module: Mac

Defined in:
lib/macaddr.rb

Constant Summary collapse

VERSION =
'1.7.1'
INTERFACE_PACKET_FAMILY =

:nodoc:

link || packet
RE =
%r/(?:[^:\-]|\A)(?:[0-9A-F][0-9A-F][:\-]){5}[0-9A-F][0-9A-F](?:[^:\-]|\Z)/io

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.mac_addressObject

Accessor for the system's first MAC address, requires a call to #address first


50
51
52
# File 'lib/macaddr.rb', line 50

def mac_address
  @mac_address
end

Class Method Details

.addressObject Also known as: addr

Discovers and returns the system's MAC addresses. Returns the first MAC address, and includes an accessor #list for the remaining addresses:

Mac.addr # => first address
Mac.addr.list # => all addresses

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/macaddr.rb', line 59

def address
  return @mac_address if defined? @mac_address and @mac_address

  @mac_address = from_getifaddrs
  return @mac_address if @mac_address

  cmds = '/sbin/ifconfig', '/bin/ifconfig', 'ifconfig', 'ipconfig /all', 'cat /sys/class/net/*/address'

  output = nil
  cmds.each do |cmd|
    _, stdout, _ = systemu(cmd) rescue next
    next unless stdout and stdout.size > 0
    output = stdout and break
  end
  raise "all of #{ cmds.join ' ' } failed" unless output

  @mac_address = parse(output)
end

.dependenciesObject


33
34
35
36
37
# File 'lib/macaddr.rb', line 33

def Mac.dependencies
  {
    'systemu' => [ 'systemu' , '~> 2.6.2' ]
  }
end

.descriptionObject


39
40
41
# File 'lib/macaddr.rb', line 39

def Mac.description
  'cross platform mac address determination for ruby'
end

.from_getifaddrsObject


82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/macaddr.rb', line 82

def from_getifaddrs
  return unless Socket.respond_to? :getifaddrs

  interfaces = Socket.getifaddrs.select do |addr|
    addr.addr.pfamily == INTERFACE_PACKET_FAMILY
  end

  mac, =
    if Socket.const_defined? :PF_LINK then
      interfaces.map do |addr|
        addr.addr.getnameinfo
      end.find do |m,|
        !m.empty?
      end
    elsif Socket.const_defined? :PF_PACKET then
      interfaces.map do |addr|
        addr.addr.inspect_sockaddr[/hwaddr=([\h:]+)/, 1]
      end.find do |mac_addr|
        mac_addr != '00:00:00:00:00:00'
      end
    end

  @mac_address = mac if mac
end

.parse(output) ⇒ Object


107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/macaddr.rb', line 107

def parse(output)
  lines = output.split(/\n/)

  candidates = lines.select{|line| line =~ RE}
  raise 'no mac address candidates' unless candidates.first
  candidates.map!{|c| c[RE].strip}

  maddr = candidates.first
  raise 'no mac address found' unless maddr

  maddr.strip!
  maddr.instance_eval{ @list = candidates; def list() @list end }
  maddr
end

.versionObject


29
30
31
# File 'lib/macaddr.rb', line 29

def Mac.version
  ::Mac::VERSION
end