53 lines
1.2 KiB
Ruby
53 lines
1.2 KiB
Ruby
# -*- coding: binary -*-
|
|
require 'network_interface'
|
|
|
|
module Msf
|
|
|
|
###
|
|
#
|
|
# Local network address option.
|
|
#
|
|
###
|
|
class OptAddressLocal < OptAddress
|
|
def interfaces
|
|
begin
|
|
NetworkInterface.interfaces || []
|
|
rescue NetworkInterface::Error => e
|
|
elog(e)
|
|
[]
|
|
end
|
|
end
|
|
|
|
def normalize(value)
|
|
return unless value.kind_of?(String)
|
|
return value unless interfaces.include?(value)
|
|
|
|
addrs = NetworkInterface.addresses(value).values.flatten
|
|
|
|
# Strip interface name from address (see getifaddrs(3))
|
|
addrs = addrs.map { |x| x['addr'].split('%').first }.select do |addr|
|
|
begin
|
|
IPAddr.new(addr)
|
|
rescue IPAddr::Error
|
|
false
|
|
end
|
|
end
|
|
|
|
# Sort for deterministic normalization; preference ipv4 addresses followed by their value
|
|
sorted_addrs = addrs.sort_by { |addr| ip_addr = IPAddr.new(addr); [ip_addr.ipv4? ? 0 : 1, ip_addr.to_i] }
|
|
|
|
sorted_addrs.any? ? sorted_addrs.first : ''
|
|
end
|
|
|
|
def valid?(value, check_empty: true)
|
|
return false if check_empty && empty_required_value?(value)
|
|
return false unless value.kind_of?(String) || value.kind_of?(NilClass)
|
|
|
|
return true if interfaces.include?(value)
|
|
|
|
super
|
|
end
|
|
end
|
|
|
|
end
|