Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ INSTALL
gem install macaddr

HISTORY
New:
2.0.0:
- Add Mac.addresses to list all MAC addresses
- Remove Mac.address.list method
- Set minimum Ruby version as 2.1.0
1.7.x:
- added a Gemfile for easier testing/dev with Bundler
- added an example .rvmrc file that will setup for ruby 1.9.3
- updated systemu gem to ~>2.4.0 to work with ruby 1.9.3
Expand All @@ -34,5 +38,12 @@ SYNOPSIS

require 'macaddr'

Mac.addr #=> first mac addr on your system
Mac.addr.list #=> all mac addrs on your system
# First mac addr on your system
Mac.addr
# or
Mac.address

# All mac addrs on your system
Mac.addrs
# or
Mac.addresses
89 changes: 40 additions & 49 deletions lib/macaddr.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#
# To return an array of all MAC addresses:
#
# Mac.address.list
# Mac.addresses
#

begin
Expand All @@ -24,7 +24,7 @@
require 'socket'

module Mac
VERSION = '1.7.1'
VERSION = '2.0.0'

def Mac.version
::Mac::VERSION
Expand Down Expand Up @@ -54,75 +54,66 @@ class << self
# MAC address, and includes an accessor #list for the remaining addresses:
#
# Mac.addr # => first address
# Mac.addr.list # => all addresses
# Mac.addrs # => all addresses

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 ||= addresses.first
end

@mac_address = parse(output)
def addresses
@mac_addresses ||= from_getifaddrs || from_system
end

link = Socket::PF_LINK if Socket.const_defined? :PF_LINK
packet = Socket::PF_PACKET if Socket.const_defined? :PF_PACKET
INTERFACE_PACKET_FAMILY = link || packet # :nodoc:

##
# Shorter alias for #address

alias_method "addr", "address"
alias_method "addrs", "addresses"

private

def from_getifaddrs
return unless Socket.respond_to? :getifaddrs

interfaces = Socket.getifaddrs.select do |addr|
addr.addr.pfamily == INTERFACE_PACKET_FAMILY
addr.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
if Socket.const_defined? :PF_LINK then
interfaces.map do |addr|
addr.addr.getnameinfo
end.flatten.select do |m|
!m.empty?
end

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

def parse(output)
lines = output.split(/\n/)
def from_system
cmds = '/sbin/ifconfig', '/bin/ifconfig', 'ifconfig', 'ipconfig /all', 'cat /sys/class/net/*/address'

candidates = lines.select{|line| line =~ RE}
raise 'no mac address candidates' unless candidates.first
candidates.map!{|c| c[RE].strip}
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

maddr = candidates.first
raise 'no mac address found' unless maddr
lines = output.split(/\n/)

maddr.strip!
maddr.instance_eval{ @list = candidates; def list() @list end }
maddr
macs = lines.select{|line| line =~ RE}
macs.map!{|c| c[RE].strip}
end

##
# Shorter alias for #address

alias_method "addr", "address"
end

RE = %r/(?:[^:\-]|\A)(?:[0-9A-F][0-9A-F][:\-]){5}[0-9A-F][0-9A-F](?:[^:\-]|\Z)/io
Expand Down
3 changes: 2 additions & 1 deletion macaddr.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@

Gem::Specification::new do |spec|
spec.name = "macaddr"
spec.version = "1.7.0"
spec.version = "2.0.0"
spec.platform = Gem::Platform::RUBY
spec.summary = "macaddr"
spec.description = "cross platform mac address determination for ruby"
spec.license = "Ruby"
spec.required_ruby_version = ">= 2.1.0"

spec.files =
["Gemfile",
Expand Down