#!/usr/bin/python3 import socket import common_ports import os import sys import re from concurrent.futures import ThreadPoolExecutor def scan_port(ip_addr, port): try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(1) result = s.connect_ex((ip_addr, port)) s.close() if result == 0: return port except: return None return None def get_open_ports(target, port_range, verbose=False): open_ports = [] # Try resolving the target try: ip_addr = socket.gethostbyname(target) except socket.gaierror: if re.match(r'^\d{1,3}(\.\d{1,3}){3}$', target): return "Error: Invalid IP address" else: return "Error: Invalid hostname" # Build the list of ports from range ports_list = list(range(port_range[0], port_range[1] + 1)) with ThreadPoolExecutor(max_workers=100) as executor: futures = [executor.submit(scan_port, ip_addr, port) for port in ports_list] for future in futures: result = future.result() if result: open_ports.append(result) # Output if verbose: try: hostname = socket.gethostbyaddr(ip_addr)[0] except socket.herror: hostname = target output = f"Open ports for {hostname} ({ip_addr})\nPORT SERVICE\n" try: import common_ports for port in open_ports: service = common_ports.ports_and_services.get(port, 'unknown') output += f"{port:<9}{service}\n" except ImportError: for port in open_ports: output += f"{port:<9}unknown\n" return output.strip() return open_ports # print(get_open_ports("scanme.nmap.org", [20, 80], verbose=True)) def main(): if len(sys.argv) < 2: print("Usage: python3 portscan.py [start_port] [end_port] [--verbose]") return input_arg = sys.argv[1] start_port = int(sys.argv[2]) if len(sys.argv) > 2 else 20 end_port = int(sys.argv[3]) if len(sys.argv) > 3 else 1024 verbose = "--verbose" in sys.argv targets = [] if os.path.isfile(input_arg): with open(input_arg) as f: targets = [line.strip() for line in f if line.strip()] else: targets = [input_arg] for target in targets: print(get_open_ports(target, [start_port, end_port], verbose)) print("-" * 40) if __name__ == "__main__": main()