mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-07 13:41:15 -07:00
314 lines
9.3 KiB
Python
314 lines
9.3 KiB
Python
# Copyright (c) 2013-2020 Philip Hane
|
|
# All rights reserved.
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without
|
|
# modification, are permitted provided that the following conditions are met:
|
|
#
|
|
# 1. Redistributions of source code must retain the above copyright notice,
|
|
# this list of conditions and the following disclaimer.
|
|
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
# this list of conditions and the following disclaimer in the documentation
|
|
# and/or other materials provided with the distribution.
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
# POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
# CLI python script interface for ipwhois.utils lookups.
|
|
|
|
import argparse
|
|
from collections import OrderedDict
|
|
import json
|
|
from ipwhois.utils import (ipv4_lstrip_zeros, calculate_cidr, get_countries,
|
|
ipv4_is_defined, ipv6_is_defined,
|
|
ipv4_generate_random, ipv6_generate_random,
|
|
unique_everseen, unique_addresses)
|
|
|
|
# CLI ANSI rendering
|
|
ANSI = {
|
|
'end': '\033[0m',
|
|
'b': '\033[1m',
|
|
'ul': '\033[4m',
|
|
'red': '\033[31m',
|
|
'green': '\033[32m',
|
|
'yellow': '\033[33m',
|
|
'cyan': '\033[36m'
|
|
}
|
|
|
|
# Setup the arg parser.
|
|
parser = argparse.ArgumentParser(
|
|
description='ipwhois utilities CLI interface'
|
|
)
|
|
parser.add_argument(
|
|
'--ipv4_lstrip_zeros',
|
|
type=str,
|
|
nargs=1,
|
|
metavar='"IP ADDRESS"',
|
|
help='Strip leading zeros in each octet of an IPv4 address.'
|
|
)
|
|
parser.add_argument(
|
|
'--calculate_cidr',
|
|
type=str,
|
|
nargs=2,
|
|
metavar='"IP ADDRESS"',
|
|
help='Calculate a CIDR range(s) from a start and end IP address.'
|
|
)
|
|
parser.add_argument(
|
|
'--get_countries',
|
|
action='store_true',
|
|
help='Output a dictionary containing ISO_3166-1 country codes to names.'
|
|
)
|
|
parser.add_argument(
|
|
'--get_country',
|
|
type=str,
|
|
nargs=1,
|
|
metavar='"COUNTRY CODE"',
|
|
help='Output the ISO_3166-1 name for a country code.'
|
|
)
|
|
parser.add_argument(
|
|
'--ipv4_is_defined',
|
|
type=str,
|
|
nargs=1,
|
|
metavar='"IP ADDRESS"',
|
|
help='Check if an IPv4 address is defined (in a reserved address range).'
|
|
)
|
|
parser.add_argument(
|
|
'--ipv6_is_defined',
|
|
type=str,
|
|
nargs=1,
|
|
metavar='"IP ADDRESS"',
|
|
help='Check if an IPv6 address is defined (in a reserved address range).'
|
|
)
|
|
parser.add_argument(
|
|
'--ipv4_generate_random',
|
|
type=int,
|
|
nargs=1,
|
|
metavar='TOTAL',
|
|
help='Generate random, unique IPv4 addresses that are not defined (can be '
|
|
'looked up using ipwhois).'
|
|
)
|
|
parser.add_argument(
|
|
'--ipv6_generate_random',
|
|
type=int,
|
|
nargs=1,
|
|
metavar='TOTAL',
|
|
help='Generate random, unique IPv6 addresses that are not defined (can be '
|
|
'looked up using ipwhois).'
|
|
)
|
|
parser.add_argument(
|
|
'--unique_everseen',
|
|
type=json.loads,
|
|
nargs=1,
|
|
metavar='"ITERABLE"',
|
|
help='List unique elements from input iterable, preserving the order.'
|
|
)
|
|
parser.add_argument(
|
|
'--unique_addresses',
|
|
type=str,
|
|
nargs=1,
|
|
metavar='"FILE PATH"',
|
|
help='Search an input file, extracting, counting, and summarizing '
|
|
'IPv4/IPv6 addresses/networks.'
|
|
)
|
|
|
|
# Output options
|
|
group = parser.add_argument_group('Output options')
|
|
group.add_argument(
|
|
'--colorize',
|
|
action='store_true',
|
|
help='If set, colorizes the output using ANSI. Should work in most '
|
|
'platform consoles.'
|
|
)
|
|
|
|
# Get the args
|
|
script_args = parser.parse_args()
|
|
|
|
if script_args.ipv4_lstrip_zeros:
|
|
|
|
print(ipv4_lstrip_zeros(address=script_args.ipv4_lstrip_zeros[0]))
|
|
|
|
elif script_args.calculate_cidr:
|
|
|
|
try:
|
|
|
|
result = calculate_cidr(
|
|
start_address=script_args.calculate_cidr[0],
|
|
end_address=script_args.calculate_cidr[1]
|
|
)
|
|
|
|
print('{0}Found {1} CIDR blocks for ({2}, {3}){4}:\n{5}'.format(
|
|
ANSI['green'] if script_args.colorize else '',
|
|
len(result),
|
|
script_args.calculate_cidr[0],
|
|
script_args.calculate_cidr[1],
|
|
ANSI['end'] if script_args.colorize else '',
|
|
'\n'.join(result)
|
|
))
|
|
|
|
except Exception as e:
|
|
|
|
print('{0}Error{1}: {2}'.format(ANSI['red'], ANSI['end'], str(e)))
|
|
|
|
elif script_args.get_countries:
|
|
|
|
try:
|
|
|
|
result = get_countries()
|
|
|
|
print('{0}Found {1} countries{2}:\n{3}'.format(
|
|
ANSI['green'] if script_args.colorize else '',
|
|
len(result),
|
|
ANSI['end'] if script_args.colorize else '',
|
|
'\n'.join(['{0}: {1}'.format(k, v) for k, v in (
|
|
OrderedDict(sorted(result.items())).iteritems())])
|
|
))
|
|
|
|
except Exception as e:
|
|
|
|
print('{0}Error{1}: {2}'.format(ANSI['red'], ANSI['end'], str(e)))
|
|
|
|
elif script_args.get_country:
|
|
|
|
try:
|
|
|
|
countries = get_countries()
|
|
result = countries[script_args.get_country[0].upper()]
|
|
|
|
print('{0}Match found for country code ({1}){2}:\n{3}'.format(
|
|
ANSI['green'] if script_args.colorize else '',
|
|
script_args.get_country[0],
|
|
ANSI['end'] if script_args.colorize else '',
|
|
result
|
|
))
|
|
|
|
except Exception as e:
|
|
|
|
print('{0}Error{1}: {2}'.format(ANSI['red'], ANSI['end'], str(e)))
|
|
|
|
elif script_args.ipv4_is_defined:
|
|
|
|
try:
|
|
|
|
result = ipv4_is_defined(address=script_args.ipv4_is_defined[0])
|
|
|
|
if result[0]:
|
|
print('{0}{1} is defined{2}:\n{3}'.format(
|
|
ANSI['green'] if script_args.colorize else '',
|
|
script_args.ipv4_is_defined[0],
|
|
ANSI['end'] if script_args.colorize else '',
|
|
'Name: {0}\nRFC: {1}'.format(result[1], result[2])
|
|
))
|
|
else:
|
|
print('{0}{1} is not defined{2}'.format(
|
|
ANSI['yellow'] if script_args.colorize else '',
|
|
script_args.ipv4_is_defined[0],
|
|
ANSI['end'] if script_args.colorize else ''
|
|
))
|
|
|
|
except Exception as e:
|
|
|
|
print('{0}Error{1}: {2}'.format(ANSI['red'], ANSI['end'], str(e)))
|
|
|
|
elif script_args.ipv6_is_defined:
|
|
|
|
try:
|
|
|
|
result = ipv6_is_defined(address=script_args.ipv6_is_defined[0])
|
|
|
|
if result[0]:
|
|
print('{0}{1} is defined{2}:\n{3}'.format(
|
|
ANSI['green'] if script_args.colorize else '',
|
|
script_args.ipv6_is_defined[0],
|
|
ANSI['end'] if script_args.colorize else '',
|
|
'Name: {0}\nRFC: {1}'.format(result[1], result[2])
|
|
))
|
|
else:
|
|
print('{0}{1} is not defined{2}'.format(
|
|
ANSI['yellow'] if script_args.colorize else '',
|
|
script_args.ipv6_is_defined[0],
|
|
ANSI['end'] if script_args.colorize else ''
|
|
))
|
|
|
|
except Exception as e:
|
|
|
|
print('{0}Error{1}: {2}'.format(ANSI['red'], ANSI['end'], str(e)))
|
|
|
|
elif script_args.ipv4_generate_random:
|
|
|
|
try:
|
|
|
|
result = ipv4_generate_random(total=script_args.ipv4_generate_random[0])
|
|
|
|
for random_ip in result:
|
|
|
|
print(random_ip)
|
|
|
|
except Exception as e:
|
|
|
|
print('{0}Error{1}: {2}'.format(ANSI['red'], ANSI['end'], str(e)))
|
|
|
|
elif script_args.ipv6_generate_random:
|
|
|
|
try:
|
|
|
|
result = ipv6_generate_random(total=script_args.ipv6_generate_random[0])
|
|
|
|
for random_ip in result:
|
|
|
|
print(random_ip)
|
|
|
|
except Exception as e:
|
|
|
|
print('{0}Error{1}: {2}'.format(ANSI['red'], ANSI['end'], str(e)))
|
|
|
|
elif script_args.unique_everseen:
|
|
|
|
try:
|
|
|
|
result = list(unique_everseen(iterable=script_args.unique_everseen[0]))
|
|
|
|
print('{0}Unique everseen{1}:\n{2}'.format(
|
|
ANSI['green'] if script_args.colorize else '',
|
|
ANSI['end'] if script_args.colorize else '',
|
|
result
|
|
))
|
|
|
|
except Exception as e:
|
|
|
|
print('{0}Error{1}: {2}'.format(ANSI['red'], ANSI['end'], str(e)))
|
|
|
|
elif script_args.unique_addresses:
|
|
|
|
try:
|
|
|
|
result = unique_addresses(file_path=script_args.unique_addresses[0])
|
|
|
|
tmp = []
|
|
for k, v in sorted(result.items(), key=lambda kv: int(kv[1]['count']),
|
|
reverse=True):
|
|
tmp.append('{0}{1}{2}: Count: {3}, Ports: {4}'.format(
|
|
ANSI['b'] if script_args.colorize else '',
|
|
k,
|
|
ANSI['end'] if script_args.colorize else '',
|
|
v['count'],
|
|
json.dumps(v['ports'])
|
|
))
|
|
|
|
print('{0}Found {1} unique addresses{2}:\n{3}'.format(
|
|
ANSI['green'] if script_args.colorize else '',
|
|
len(result),
|
|
ANSI['end'] if script_args.colorize else '',
|
|
'\n'.join(tmp)
|
|
))
|
|
|
|
except Exception as e:
|
|
|
|
print('{0}Error{1}: {2}'.format(ANSI['red'], ANSI['end'], str(e)))
|