# frozen_string_literal: true # # Copyright (c) 2006-2023 Hal Brodigan (postmodern.mod3 at gmail.com) # # Ronin is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Ronin is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Ronin. If not, see . # require 'ronin/cli/value_processor_command' require 'ronin/support/network/ip' require 'uri' module Ronin class CLI module Commands # # Queries or processes IP addresses. # # ## Usage # # ronin ip [options] [IP ... | --public | --local] # # ## Options # # -f, --file FILE Optional file to read values from # -P, --public Gets the machine's public IP address # -L, --local Gets the machine's local IP address # -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 # -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) # --uri-port PORT The port for the URI # --uri-path /PATH The path for the URI (Default: /) # --uri-query STRING The query string for the URI # --http Converts the IP address into a http:// URI # --https Converts the IP address into a https:// URI # -h, --help Print help information # # ## Arguments # # [IP ...] The IP address(es) to process # # ## Examples # # ronin ip --public # ronin ip --local # ronin ip --decimal 1.2.3.4 # ronin ip --cidr 20 1.2.3.4 # ronin ip --host 192.30.255.113 # class Ip < ValueProcessorCommand usage '[options] {IP ... | --public | --local}' option :public, short: '-P', desc: "Gets the machine's public IP address" option :local, short: '-L', desc: "Gets the machine's local IP address" option :reverse, short: '-r', desc: 'Prints the IP address in reverse name format' option :hex, short: '-X', desc: 'Converts the IP address to hexadecimal format' option :decimal, short: '-D', desc: 'Converts the IP address to decimal format' option :octal, short: '-O', desc: 'Converts the IP address to octal format' option :binary, short: '-B', desc: 'Converts the IP address to binary format' option :cidr, short: '-C', value: { type: String, usage: 'NETMASK' }, desc: 'Converts the IP address into a CIDR range' option :host, short: '-H', desc: 'Converts the IP address to a host name' option :port, short: '-p', value: { type: Integer, usage: 'PORT' }, desc: 'Appends the port number to each IP' option :uri, short: '-U', desc: 'Converts the IP address into a URI' option :uri_scheme, value: { type: String, default: 'http', usage: 'SCHEME' }, desc: 'The scheme for the URI' option :uri_port, value: { type: Integer, usage: 'PORT' }, desc: 'The port for the URI' option :uri_path, value: { type: %r{\A/.+}, default: '/', usage: '/PATH' }, desc: 'The path for the URI' option :uri_query, value: { type: String, usage: 'STRING' }, desc: 'The query string for the URI' option :http, desc: 'Converts the IP address into a http:// URI' do options[:uri] = true options[:uri_scheme] = 'http' end option :https, desc: 'Converts the IP address into a https:// URI' do options[:uri] = true options[:uri_scheme] = 'https' end argument :ip, required: false, repeats: true, desc: 'The IP address(es) to process' description 'Queries or processes IP addresses' examples [ '--public', '--local', '--decimal 1.2.3.4', '--cidr 20 1.2.3.4', '--host 192.30.255.113' ] man_page 'ronin-ip.1' # # Runs the `ronin ip` command. # # @param [Array] ips # Additional IP arguments to process. # def run(*ips) if options[:public] if (address = Support::Network::IP.public_address) puts address else print_error 'failed to lookup public IP address using https://ipinfo.io/ip' exit(1) end elsif options[:local] puts Support::Network::IP.local_address else super(*ips) end end # # Processes an individual IP address. # # @param [String] ip # The IP address string to process. # def process_value(ip) ip = Support::Network::IP.new(ip) if options[:reverse] puts ip.reverse elsif options[:cidr] ip = Support::Network::IP.new("#{ip}/#{options[:cidr]}") puts "#{ip}/#{ip.prefix}" elsif options[:host] if (host = ip.host) puts host end elsif options[:port] puts "#{format_ip(ip)}:#{options[:port]}" elsif options[:uri] puts URI::Generic.build( scheme: options[:uri_scheme], host: format_ip(ip), port: options[:uri_port], path: options[:uri_path], query: options[:uri_query] ) else puts format_ip(ip) end end # # Formats an IP address. # # @param [Ronin::Support::Network::IP] ip # The IP address to format. # # @return [String] # The formatted IP address. # def format_ip(ip) if options[:hex] "0x%x" % ip.to_i elsif options[:decimal] "%u" % ip.to_i elsif options[:octal] "0%o" % ip.to_i elsif options[:binary] "%b" % ip.to_i else ip.to_s end end end end end end