#!/usr/bin/python3

import socket
import common_ports
import re


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))

    for port in ports_list:
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.settimeout(1)
            result = s.connect_ex((ip_addr, port))
            if result == 0:
                open_ports.append(port)
            s.close()
        except:
            continue

    # 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))
