Module: Ethernet::Devices

Defined in:
lib/ethernet/devices.rb,
lib/ethernet/devices_linux.rb,
lib/ethernet/devices_darwin.rb

Overview

:nodoc: darwin-specific implementation

Class Method Summary collapse

Class Method Details

.allObject

Array containing device names.



7
8
9
# File 'lib/ethernet/devices.rb', line 7

def self.all
  info.keys
end

.ifconf_packspecObject

:nodoc: darwin implementation



79
80
81
# File 'lib/ethernet/devices.rb', line 79

def ifconf_packspec
  raise "Unsupported os #{Ethernet::Provisioning::OS}"
end

.ifreq_sizeObject

:nodoc: darwin implementation



85
86
87
# File 'lib/ethernet/devices.rb', line 85

def ifreq_size
  raise "Unsupported os #{Ethernet::Provisioning::OS}"
end

.infoObject

Hash mapping device names to information about devices.



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/ethernet/devices.rb', line 28

def self.info
  # array of struct ifreq in /usr/include/net/if.h
  buffer_size = ifreq_size * 128
  buffer_ptr = FFI::MemoryPointer.new :uchar, buffer_size, 0
  # struct ifconf in /usr/include/net/if.h
  ifconf = [buffer_size, buffer_ptr.address].pack ifconf_packspec
  ioctl_socket.ioctl siocgifconf_ioctl, ifconf
  
  output_size = ifconf.unpack('l').first
  offset = 0
  devices = {}
  while offset < output_size
    name = (buffer_ptr + offset).read_string_to_null
    devices[name] ||= {}
    # struct sockaddr
    addr_length, addr_family = *(buffer_ptr + offset + 16).read_string(2).
                                                           unpack('CC')
    addr_length = ifreq_size - 16 if addr_length < ifreq_size - 16
    if addr_family == ll_address_family
      # struct sockaddr_dl in /usr/include/net/if_dl.h
      devices[name][:index], blah, skip, length =
          *(buffer_ptr + offset + 18).read_string(4).unpack('SCCC')
      devices[name][:mac] =
          (buffer_ptr + offset + 24 + skip).read_string(length)
    end
    
    offset += 16 + addr_length
  end
  
  if devices.all? { |k, v| v[:mac].nil? }
    # Linux only provides IP addresses in SIOCGIFCONF.
    devices.keys.each do |device|
      devices[device][:mac] ||= mac device
      devices[device][:index] ||= interface_index device
    end
  end
  devices.delete_if { |k, v| v[:mac].nil? || v[:mac].empty? }
  
  devices
end

.interface_index(eth_device) ⇒ Object

:nodoc: linux implementation



23
24
25
# File 'lib/ethernet/devices.rb', line 23

def self.interface_index(eth_device)
  info[eth_device][:index]
end

.ioctl_socketObject

Socket that is solely used for issuing ioctls.



97
98
99
# File 'lib/ethernet/devices.rb', line 97

def ioctl_socket
  Socket.new(Socket::AF_INET, Socket::SOCK_DGRAM, 0)
end

.ll_address_familyObject

:nodoc: darwin implementation



91
92
93
# File 'lib/ethernet/devices.rb', line 91

def ll_address_family
  raise "Unsupported os #{Ethernet::Provisioning::OS}"
end

.mac(eth_device) ⇒ Object

:nodoc: linux implementation



15
16
17
# File 'lib/ethernet/devices.rb', line 15

def self.mac(eth_device)
  info[eth_device][:mac]
end

.siocgifconf_ioctlObject

:nodoc: darwin implementation



71
72
73
# File 'lib/ethernet/devices.rb', line 71

def siocgifconf_ioctl
  raise "Unsupported os #{Ethernet::Provisioning::OS}"
end