Extracting individual IP addresses - ruby

How can I extract each individual IP address from the array below?
strList = ["10.5.5.5 - 10.5.5.8"]
The end result should look like this:
newList = ["10.5.5.5","10.5.5.6","10.5.5.7","10.5.5.8"]
Do you guys have any ideas?

You can do that as follows:
require 'ipaddr'
(IPAddr.new("10.5.5.5")..IPAddr.new("10.5.5.8")).map(&:to_s)
#=> ["10.5.5.5", "10.5.5.6", "10.5.5.7", "10.5.5.8]

Related

how do I convert int32 IP address into octets in ruby?

I'm looking for the opposite to this:
require 'ipaddr'
ip = IPAddr.new "10.0.2.15"
ip.to_i # 167772687
I need to pass something like 167772687, and want to get back "10.0.2.15".
This:
ip = IPAddr.new 167772687
returns the error:
IPAddr::AddressFamilyError: address family must be specified
How to I specify that I'm passing int32?
OK, found the answer:
require 'ipaddr'
ip = IPAddr.new(167772687, family = Socket::AF_INET)
ip.to_s # "10.0.2.15"

search to return list of nodes ip in specific format in chef

I need to do a search in a chef recipe that returns the IP's of all nodes in this specific format
'IP','IP',etc
so far by searching I've come up with this but the output is not exactly in the format that I want and I don't know how to change it.
ip = Array.new
search(:node, "name:chef-node*") do |n|
n["network"]["interfaces"]["eth1"]["addresses"].each_pair do |address,value|
ip << address if value.has_key?("broadcast")
end if n["network"]["interfaces"]["eth1"]
end
the output is like this:
["10.22.33.33", "10.22.33.38", "10.21.33.24"]
and I need it like this:
'10.210.39.231','10.209.161.18','10.210.66.240'
How would I achieve that?
ip = ["10.22.33.33", "10.22.33.38", "10.21.33.24"]
ip.map { |x| "'#{x}'" }.join(',')
# => "'10.22.33.33','10.22.33.38','10.21.33.24'"
You have a nice Array or IPs. Just use method join over it.
ip = ["10.22.33.33", "10.22.33.38", "10.21.33.24"]
ip.join(",")

Ruby retrieve data from file after specific label

How can I get specific data from a file in ruby? I want to get some 10. ip addresses from a file set up like this...
Whatever: xathun
ip_address: 10.2.232.6
etc: aouoeu
more: snthuh
I want to push the ip addresses into an array.
I can pull 10. addresses out of text. I was hoping for a more accurate way to do it as in only the data after the 'ip_address:' label in case there is unwanted matching data.
s_text = File.open("test.txt",'r').read
ip_addresses = s_text.scan(/\d+.\d+.\d+.\d+/)
puts ip_addresses.inspect #=> ["10.2.232.6"]
Here's a simple enough solution.
open('<textfile path>') { |f| puts f.grep(/10\./) }
If the file is setup like that throughout you can do:
arr = []
File.open("text").each_line do |line|
parts = line.split(":")
arr << parts[1].strip if parts[0] == "ip_address"
end
adding to array as you go through once, one line at a time:
ip_data.txt
Whatever: xathun
ip_address: 10.2.232.6
etc: aouoeu
more: snthuh
Whatever: badone
ip_address: 66.8.103.3
etc: huh
more: noooo
Whatever: blah
ip_address: 10.9.244.13
etc: hello
more: goodbye
code
found_tens = []
File.open('ip_data.txt') {|f|
f.each {|line|
line = line.chomp
next if line.empty?
found_tens << $1 if line =~ /^ip_address:\s+(10\.\d+\.\d+\.\d+)/
}
}
p found_tens #["10.2.232.6", "10.9.244.13"]

Creating a sequence of IP addresses if given a starting address

I need to write code to ping a sequence of 20 IP addresses if given a starting IP address (e.g 192.168.0.1). Each successive IP address should be one digit larger than the previous.
That's what IPAddr#succ is for:
require 'ipaddr'
ipaddr = IPAddr.new('192.168.0.1')
20.times do
ping ipaddr
ipaddr = ipaddr.succ
end
ip = "192.168.0.1"
ips = []
(0..20).each do |n|
temp = ip.split('.').map(&:to_i)
temp[3] = temp[3] + n
ips << temp.join('.')
end
puts ips

Reverse DNS in Ruby?

I'm in an environment with a lot of computers that haven't been
properly inventoried. Basically, no one knows which IP goes with which
mac address and which hostname. So I wrote the following:
# This script goes down the entire IP range and attempts to
# retrieve the Hostname and mac address and outputs them
# into a file. Yay!
require "socket"
TwoOctets = "10.26"
def computer_exists?(computerip)
system("ping -c 1 -W 1 #{computerip}")
end
def append_to_file(line)
file = File.open("output.txt", "a")
file.puts(line)
file.close
end
def getInfo(current_ip)
begin
if computer_exists?(current_ip)
arp_output = `arp -v #{current_ip}`
mac_addr = arp_output.to_s.match(/..:..:..:..:..:../)
host_name = Socket.gethostbyname(current_ip)
append_to_file("#{host_name[0]} - #{current_ip} - #{mac_addr}\n")
end
rescue SocketError => mySocketError
append_to_file("unknown - #{current_ip} - #{mac_addr}")
end
end
(6..8).each do |i|
case i
when 6
for j in (1..190)
current_ip = "#{TwoOctets}.#{i}.#{j}"
getInfo(current_ip)
end
when 7
for j in (1..255)
current_ip = "#{TwoOctets}.#{i}.#{j}"
getInfo(current_ip)
end
when 8
for j in (1..52)
current_ip = "#{TwoOctets}.#{i}.#{j}"
getInfo(current_ip)
end
end
end
Everything works except it does not find a Reverse DNS.
Sample output that I'm getting is this:
10.26.6.12 - 10.26.6.12 - 00:11:11:9B:13:9F
10.26.6.17 - 10.26.6.17 - 08:00:69:9A:97:C3
10.26.6.18 - 10.26.6.18 - 08:00:69:93:2C:E2
If I do nslookup 10.26.6.12 then I get the correct reverse DNS so
that shows that my machine is seeing the DNS server.
I have tried Socket.gethostbyname, gethostbyaddr, but it doesn't work.
Any guidance will be much appreciated.
Today I also needed reverse DNS lookup and I've found very simple standard solution:
require 'resolv'
host_name = Resolv.getname(ip_address_here)
It seems it uses timeout which helps in rough cases.
I would check out getaddrinfo. If you replace the line:
host_name = Socket.gethostbyname(current_ip)
with:
host_name = Socket.getaddrinfo(current_ip, 0, Socket::AF_UNSPEC, Socket::SOCK_STREAM, nil, Socket::AI_CANONNAME)[0][1]
The getaddrinfo function returns an array of arrays. You can read more about it at:
Ruby Socket Docs
This also works:
host_name = Socket.getaddrinfo(current_ip,nil)
append_to_file("#{host_name[0][2]} - #{current_ip} - #{mac_addr}\n")
I'm not sure why gethostbyaddr didn't also work.

Resources