lib/ronin/cli/commands/ip.rb in ronin-2.0.5 vs lib/ronin/cli/commands/ip.rb in ronin-2.1.0.rc1

- old
+ new

@@ -17,10 +17,11 @@ # require 'ronin/cli/value_processor_command' require 'ronin/support/network/ip' require 'uri' +require 'ipaddr' module Ronin class CLI module Commands # @@ -38,10 +39,14 @@ # -r, --reverse Prints the IP address in reverse name format # -X, --hex Converts the IP address to hexadecimal format # -D, --decimal Converts the IP address to decimal format # -O, --octal Converts the IP address to octal format # -B, --binary Converts the IP address to binary format + # --hex-octet Converts the IP address to hexadecimal format by octet + # --octal-octet Converts the IP address to octal format by octet + # --ipv6-compat Converts the IPv4 address to an IPv6 compatible address + # --ipv6-expanded Expands a shortened or compressed IPv6 address # -C, --cidr NETMASK Converts the IP address into a CIDR range # -H, --host Converts the IP address to a host name # -p, --port PORT Appends the port number to each IP # -U, --uri Converts the IP address into a URI # --uri-scheme SCHEME The scheme for the URI (Default: http) @@ -87,10 +92,20 @@ desc: 'Converts the IP address to octal format' option :binary, short: '-B', desc: 'Converts the IP address to binary format' + option :hex_octet, + desc: 'Converts the IP address to hexadecimal format by octet' + + option :octal_octet, + desc: 'Converts the IP address to octal format by octet' + + option :ipv6_compat, desc: 'Converts the IPv4 address to an IPv6 compatible address' + + option :ipv6_expanded, desc: 'Expands a shortened or compressed IPv6 address' + option :cidr, short: '-C', value: { type: String, usage: 'NETMASK' }, @@ -223,22 +238,108 @@ # # @return [String] # The formatted IP address. # def format_ip(ip) + if ip.ipv4? + format_ipv4(ip) + else + format_ipv6(ip) + end + end + + private + + # + # Formats an IPv4 address. + # + # @param [Ronin::Support::Network::IP] ip + # The IP address to format. + # + # @return [String] + # The formatted IP address. + # + def format_ipv4(ip) if options[:hex] "0x%x" % ip.to_i + elsif options[:hex_octet] + ipv4_hex_octet(ip) elsif options[:decimal] "%u" % ip.to_i elsif options[:octal] "0%o" % ip.to_i + elsif options[:octal_octet] + ip.to_s.split(".").map { |octet| "0%o" % octet.to_i }.join(".") elsif options[:binary] "%b" % ip.to_i + elsif options[:ipv6_compat] + ip.ipv4_mapped.to_s + elsif options[:ipv6_expanded] + print_error "called with --ipv6-expanded for #{ip}" + exit(1) else ip.to_s end end + # + # Formats an IPv6 address. + # + # @param [Ronin::Support::Network::IP] ip + # The IP address to format. + # + # @return [String] + # The formatted IP address. + # + def format_ipv6(ip) + if options[:decimal] + "%u" % ip.to_i + elsif options[:hex] + "0x%x" % ip.to_i + elsif options[:octal] + "0%o" % ip.to_i + elsif options[:octal_octet] + print_error "called with --octal-octet for #{ip}" + exit(1) + elsif options[:hex_octet] + if ip.ipv4_mapped? + "::ffff:#{ipv4_hex_octet(ip.ipv4)}" + else + print_error "called with --hex-octet for #{ip}" + exit(1) + end + elsif options[:binary] + "%b" % ip.to_i + elsif options[:ipv6_expanded] + ip.canonical + elsif options[:ipv6_compat] + print_error "called with --ipv6-compat for #{ip}" + exit(1) + else + ip.to_s + end + end + + # + # Converts the octets of an IP address to hex + # + # @param [Ronin::Support::Network::IP] ip + # The IP address to convert. + # + # @return [String] + # The formatted IP address. + # + def ipv4_hex_octet(ip) + ip_uint = ip.to_i + + format( + "%<octet1>x.%<octet2>x.%<octet3>x.%<octet4>x", + octet1: (ip_uint & 0xff000000) >> 24, + octet2: (ip_uint & 0xff0000) >> 16, + octet3: (ip_uint & 0xff00) >> 8, + octet4: (ip_uint & 0xff) + ) + end end end end end