Creating a sequence of IP addresses if given a starting address - ruby

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

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"

Getting domain host name in ruby

Is there a possible way to get the domain's hostname in ruby?
For example:
$ host api.heroku.com
api.heroku.com is an alias for api-default.herokussl.com.
api-default.herokussl.com is an alias for elb027033-298234319.us-east-1.elb.amazonaws.com.
elb027033-298234319.us-east-1.elb.amazonaws.com has address 23.23.76.65
elb027033-298234319.us-east-1.elb.amazonaws.com has address 23.21.240.208
elb027033-298234319.us-east-1.elb.amazonaws.com has address 107.22.242.236
host would be the best example, because it'll also show if the domain/subdomain is pointing to another host like amazonAWS or etc.
not as useful as executing host domain.com command from ruby
I beg to differ... (but it does involve knowing what data you want, and how DNS works).
require 'resolv'
def host(address)
Resolv::DNS.open do |dns|
loop do
ress = dns.getresources address, Resolv::DNS::Resource::IN::CNAME
break if ress.empty?
canonical_name = ress.first.name.to_s
puts "#{address} is an alias for #{canonical_name}"
address = canonical_name
end
ress = dns.getresources address, Resolv::DNS::Resource::IN::A
addresses = ress.each do |r|
puts "#{address} has address #{r.address.to_s}"
end
end
return
end
host("api.heroku.com")

Extracting individual IP addresses

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]

Ruby - Send message to multiple IP addresses

How would I go about sending one message to multiple receivers?
This is essentially what I would like to do:
require 'socket'
ip = ['IP 1', 'IP 2']
port = 18000
loop {
message = gets.chomp()
conn = TCPSocket.open(ip, port)
conn.write(message)
conn.close_write
}
Try to iterate over the ips array:
ips = ['IP 1', 'IP 2']
port = 18000
loop do
message = gets.chomp()
ips.each do |ip|
conn = TCPSocket.open(ip, port)
conn.write(message)
conn.close_write
end
end

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