(Testing in ether_shell because my ethernet still can't pass rspec.)
For the 'system/getifaddrs' require, have to let user install it before they can use it, so do:
1. Add into the Gemfile, like
2 # Add dependencies required to use your gem here. 3 # Example: 4 # gem "activesupport", ">= 2.3.5" 5 gem "system-getifaddrs", "~> 0.1.1"2. Do NOT add gem.add_runtime_dependency 'rcov', '>= 0.1.1' to Rakefile because it's automatic now
3. bundle
4. sudo rake install
Add in lib/ethernet/raw_socket.rb:
require 'system/getifaddrs' # for listing ... # returns a symbols array of all network devices def self.list_all_devices() case RUBY_PLATFORM when /linux/ #TODO: test to see if works on MacOS as well devicehash = System.get_ifaddrs # {:eth0=>{:inet_addr=>"18.248.7.89", :netmask=>"18.248.7.89"}, :vmnet1=>{:inet_addr=>"172.16.76.1", :netmask=>"172.16.76.1"}} devicehash.keys end end # returns a hash of all network devices => MAC Address def self.list_all_devices_macaddr() case RUBY_PLATFORM when /linux/ devices = self.list_all_devices device_macaddrs = {} devices.each do |eth_device| device_macaddrs[eth_device] = self.mac(eth_device.to_s).unpack('H*')[0] end device_macaddrs end end
Add in spec/ethernet/raw_socket_spec.rb
describe 'testing listing all network devices' do it 'should list the devices' do device_macaddrs = Ethernet::RawSocket.list_all_devices_macaddr() device_macaddrs.each do |key, value| puts "\nDevice is: " puts key.to_s puts "MAC Addrs: " puts value puts "\n" end end end
Results:
$ sudo rspec raw_socket_spec.rb ..... Device is: vmnet1 MAC Addrs: 005056c00001 Device is: vmnet8 MAC Addrs: 005056c00008 Device is: lo MAC Addrs: 000000000000 Device is: eth0 MAC Addrs: 002170925bc5 . Finished in 0.11353 seconds 6 examples, 0 failures
Details of how I found this solution, very boring
I could run ether_shell's specs. Specifically, sudo rspec raw_socket_spec.rb, which currently has eth0 as the device
Now I want to see if the outputting mac address function works.
In raw_socket.rb, .mac() is the function that gets the mac address of a device:
I changed it so that it prints out the mac: (line numbers don't match)
$ sudo rspec raw_socket_spec.rb
device name:
eth0
mac address output:
002170925bc5
-----------
.
device name:
eth0
mac address output:
002170925bc5
-----------
..
device name:
eth0
mac address output:
002170925bc5
-----------
..
Finished in 0.30495 seconds
5 examples, 0 failures
yup, the mac address of my eth0 is indeed that. (matched HWaddr in ifconfig -a of eth0)
the ".unpack('H*')[0]" part changes the mac address into hex, without it, it would look like:
!p�[
hmmm.... so let's see if it gets the right mac address if I change the device to vmnet1
so, raw_socket_spec.rb:
$ sudo rspec raw_socket_spec.rb
device name:
vmnet1
mac address output:
005056c00001
-----------
.
device name:
vmnet1
mac address output:
005056c00001
-----------
..
device name:
vmnet1
mac address output:
005056c00001
-----------
a match! yipee!!! (the rspec hung, but that we don't care)
Also worked for wlan0, even though I'm not plugged in to it
device name:
wlan0
mac address output:
001c26640fac
-----------
============================================
So now, I need just get the list of names and then run .mac() for each of them.
I need to look at the code for systemgetifaddr
man 3 getifaddrs
http://comments.gmane.org/gmane.os.cygwin/123705 ioctl vs getifaddrs
The rspec of https://github.com/bbcoimbra/system-getifaddrs/blob/master/spec/system-ifaddrs_spec.rb compares it to ifconfig's result
added to raw_socket.rb:
added to raw_socket_spec.rb:
good results:
now I have to make it into 2 functions, one the lists the devices, one that lists their mac addresses (see way top of blog)
3 describe 'RawSocket' do 4 let(:eth_device) { 'eth0' }
Now I want to see if the outputting mac address function works.
In raw_socket.rb, .mac() is the function that gets the mac address of a device:
28 # The MAC address for an Ethernet card. 29 # 30 # Args: 31 # eth_device:: device name for the Ethernet card, e.g. 'eth0' 32 def self.mac(eth_device) 33 case RUBY_PLATFORM 34 when /linux/ 35 # /usr/include/net/if.h, structure ifreq 36 ifreq = [eth_device].pack 'a32' 37 # 0x8927 is SIOCGIFHWADDR in /usr/include/bits/ioctls.h 38 socket.ioctl 0x8927, ifreq 39 ifreq[18, 6] #in scratchpad's raw_ethernet, then says .unpack('H*').first 40 else 41 raise "Unsupported platform #{RUBY_PLATFORM}" 42 end 43 end
I changed it so that it prints out the mac: (line numbers don't match)
28 # /usr/include/net/if.h, structure ifreq 29 ifreq = [eth_device].pack 'a32' 30 puts "\ndevice name: " 31 puts ifreq 32 # 0x8927 is SIOCGIFHWADDR in /usr/include/bits/ioctls.h 33 socket.ioctl 0x8927, ifreq 34 puts "mac address output: " 35 puts ifreq[18, 6].unpack('H*')[0] 36 puts "-----------" 37 ifreq[18, 6]
$ sudo rspec raw_socket_spec.rb
device name:
eth0
mac address output:
002170925bc5
-----------
.
device name:
eth0
mac address output:
002170925bc5
-----------
..
device name:
eth0
mac address output:
002170925bc5
-----------
..
Finished in 0.30495 seconds
5 examples, 0 failures
yup, the mac address of my eth0 is indeed that. (matched HWaddr in ifconfig -a of eth0)
the ".unpack('H*')[0]" part changes the mac address into hex, without it, it would look like:
!p�[
hmmm.... so let's see if it gets the right mac address if I change the device to vmnet1
so, raw_socket_spec.rb:
3 describe 'RawSocket' do 4 let(:eth_device) { 'vmnet1' }
$ sudo rspec raw_socket_spec.rb
device name:
vmnet1
mac address output:
005056c00001
-----------
.
device name:
vmnet1
mac address output:
005056c00001
-----------
..
device name:
vmnet1
mac address output:
005056c00001
-----------
a match! yipee!!! (the rspec hung, but that we don't care)
Also worked for wlan0, even though I'm not plugged in to it
device name:
wlan0
mac address output:
001c26640fac
-----------
============================================
So now, I need just get the list of names and then run .mac() for each of them.
I need to look at the code for systemgetifaddr
man 3 getifaddrs
http://comments.gmane.org/gmane.os.cygwin/123705 ioctl vs getifaddrs
The rspec of https://github.com/bbcoimbra/system-getifaddrs/blob/master/spec/system-ifaddrs_spec.rb compares it to ifconfig's result
added to raw_socket.rb:
2 require 'rubygems' # for listing 3 require 'system/getifaddrs' # for listing ... 45 # listing all network devices's MAC addresses 46 def self.list_all_devices() 47 case RUBY_PLATFORM 48 when /linux/ #test to see if works on MacOS as well 49 devicehash = System.get_ifaddrs # {:eth0=>{:inet_addr=>"18.248.7.89", :netmask=>"18. 248.7.89"}, :vmnet1=>{:inet_addr=>"172.16.76.1", :netmask=>"172.16.76.1"}} 50 devicehash.each_key do |key| 51 puts self.mac(key.to_s).unpack('H*')[0] 52 puts " - - - - -" 53 end 54 end 55 end
added to raw_socket_spec.rb:
42 describe 'testing listing all network devices' do 43 it 'should list the devices' do 44 EtherShell::RawSocket.list_all_devices().should_not be_empty 45 end 46 end
good results:
$ sudo rspec raw_socket_spec.rb device name: eth0 mac address output: 002170925bc5 ----------- . device name: eth0 mac address output: 002170925bc5 ----------- .. device name: eth0 mac address output: 002170925bc5 ----------- .. device name: vmnet1 mac address output: 005056c00001 ----------- 005056c00001 - - - - - device name: vmnet8 mac address output: 005056c00008 ----------- 005056c00008 - - - - - device name: lo mac address output: 000000000000 ----------- 000000000000 - - - - - device name: eth0 mac address output: 002170925bc5 ----------- 002170925bc5 - - - - - . Finished in 0.21653 seconds 6 examples, 0 failures
now I have to make it into 2 functions, one the lists the devices, one that lists their mac addresses (see way top of blog)
No comments:
Post a Comment