Created
August 23, 2012 13:31
-
-
Save tommybotten/3436634 to your computer and use it in GitHub Desktop.
Example to replace string search in facter in favor of system calls
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/ruby | |
require 'socket' | |
# From bits/ioctls.h | |
SIOCGIFNETMASK = 0x891b # Netmask address | |
SIOCGIFHWADDR = 0x8927 # hardware address | |
SIOCGIFADDR = 0x8915 # PA address | |
SIOCGIFCONF = 0x8912 # iface list | |
class Interface | |
#def self.list | |
# sock = UDPSocket.new | |
# | |
# # Query to get size of the interface buffer | |
# buf = [0,0].pack('lQ') | |
# sock.ioctl(SIOCGIFCONF, buf) | |
# buf_size = buf.unpack('l').first | |
# | |
# # Generate a return buffer (must be a smarter way) | |
# data = '' | |
# for i in 1..buf_size | |
# data = data + "\0" | |
# end | |
# | |
# # Get interface data | |
# buf = [buf_size,data].pack("la#{buf_size}") | |
# sock.ioctl(SIOCGIFCONF, buf); | |
# sock.close | |
# | |
# # Unpack interface information (data part is an array of struct ifreq with the first | |
# # member is char ifrn_name[IFNAMSIZ] (16) and sizeof(struct ifreq) = 40) | |
# return buf | |
#end | |
def self.list | |
sock = UDPSocket.new | |
# Query to get size of the interface buffer | |
buf = [0,0].pack('lQ') | |
sock.ioctl(SIOCGIFCONF, buf) | |
buf_size = buf.unpack('l').first | |
# Generate a return buffer (must be a smarter way) | |
data = '' | |
for i in 1..buf_size | |
data = data + " " | |
end | |
# Get interface data | |
buf = [buf_size, data].pack("lP#{buf_size}") | |
sock.ioctl(SIOCGIFCONF, buf) | |
sock.close | |
# Unpack interface information (data part is an array of struct ifreq with the first | |
# member is char ifrn_name[IFNAMSIZ] (16) and sizeof(struct ifreq) = 40) | |
names = [] | |
off = 0 | |
while off < buf_size | |
name = data[off..off+16].unpack('a16').first | |
print("Name #{name}\n") | |
names << name | |
off += 40 | |
end | |
return names | |
end | |
def self.hw_address(iface) | |
sock = UDPSocket.new | |
buf = [iface,""].pack('a16h16') | |
sock.ioctl(SIOCGIFHWADDR, buf); | |
sock.close | |
return buf[18..24].unpack("H2H2H2H2H2H2").join(":") | |
end | |
def self.netmask(iface) | |
sock = UDPSocket.new | |
buf = [iface,""].pack('a16h16') | |
sock.ioctl(SIOCGIFNETMASK, buf); | |
sock.close | |
return buf[20..23].unpack("CCCC").join(".") | |
end | |
def self.ip_address(iface) | |
sock = UDPSocket.new | |
buf = [iface,""].pack('a16h16') | |
sock.ioctl(SIOCGIFADDR, buf); | |
sock.close | |
buf[20..24].unpack("CCCC").join(".") | |
end | |
def self.list_all_ips | |
# Slow for some reason. 5ms for each iteration. | |
return Socket::getaddrinfo(Socket.gethostname, '', Socket::AF_INET).map { |x| x[3] }.uniq | |
end | |
end | |
puts Interface.list |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Perhaps
data = ' ' * buf_size
would do for the "must be a smarter way" section.