aggregator.rb
Heads up: This description was created by AI and might not be 100% accurate.
This Ruby code snippet demonstrates functions for summarizing IP addresses into CIDR blocks, converting CIDR blocks to ACL entries, and generating netmasks from mask values. It utilizes the IPAddr class for IP address manipulation and range calculations. The code includes functions like summarize_ips, cidrs_to_acl, mask_to_netmask, cidr_to_acl, largest_block, and range_to_cidrs to achieve this.
Ruby code snippet
def summarize_ips(ip_list, min_mask: 0)
ips = ip_list.uniq.map { IPAddr.new(_1) }.sort_by(&:to_i)
ips.chunk_while { |a, b| b.to_i == a.to_i + 1 }
.flat_map { |c| range_to_cidrs(c.first, c.last, min_mask: min_mask) }
end
#=> :summarize_ips
def cidrs_to_acl(entries)
entries.map { |e| cidr_to_acl(e) }
end
#=> :cidrs_to_acl
def mask_to_netmask(mask)
[(0xffffffff << (32 - mask)) & 0xffffffff]
.pack('N').unpack('C4').join('.')
end
#=> :mask_to_netmask
def cidr_to_acl(entry)
ip, mask = entry
return "host #{ip}" if mask == 32
"#{ip} #{mask_to_netmask(mask)}"
end
#=> :cidr_to_acl
def largest_block(start_ip, end_ip, min_mask)
mask = 32
best = [start_ip.to_s, 32]
while mask >= min_mask
block = IPAddr.new("#{start_ip}/#{mask}")
break unless block.to_range.first == start_ip
break if block.to_range.last > end_ip
best = [start_ip.to_s, mask]
mask -= 1
end
best
end
#=> :largest_block
def range_to_cidrs(start_ip, end_ip, min_mask:)
res = []
cur = start_ip
while cur <= end_ip
ip_str, mask = largest_block(cur, end_ip, min_mask)
res << [ip_str, mask]
block = IPAddr.new("#{cur}/#{mask}")
cur = IPAddr.new(block.to_range.last.to_i + 1, Socket::AF_INET)
end
res
end
#=> :range_to_cidrs
ips = ['192.168.1.0', '192.168.1.1']
#=> ["192.168.1.0", "192.168.1.1"]
raw = summarize_ips(ips)
#=> [["192.168.1.0", 31]]
cidrs_to_acl(raw)
#=> ["192.168.1.0 255.255.255.254"]
Executed with Ruby 3.4.8.