Skip to content

Commit c43a587

Browse files
authored
Update port_scanner.py
1 parent b70f459 commit c43a587

File tree

1 file changed

+67
-18
lines changed

1 file changed

+67
-18
lines changed

port_scanner.py

Lines changed: 67 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,23 @@
22

33
"""
44
Project: Port Scanner
5-
Description: Installs and runs nmap with colored scan results
5+
Description: Async port scanner with Nmap support
66
Author: batubyte
7-
Date: 2025-15-06
7+
Date: 2025-06-17
88
"""
99

1010
import subprocess
1111
import platform
12+
import argparse
13+
import asyncio
1214
import shutil
15+
import socket
1316
import sys
1417
import re
1518

19+
DESCRIPTION = "Async port scanner with Nmap support"
20+
VERSION = "0.1.1"
21+
1622
RED = "\033[31m"
1723
GREEN = "\033[32m"
1824
YELLOW = "\033[33m"
@@ -22,7 +28,7 @@
2228

2329

2430
def install_nmap():
25-
if shutil.which("nmap") is not None:
31+
if shutil.which("nmap"):
2632
return
2733

2834
answer = input("Nmap not found. Install? [Y/n]: ").strip().lower()
@@ -34,16 +40,20 @@ def install_nmap():
3440
subprocess.run(["sudo", "apt-get", "update"], check=True)
3541
subprocess.run(["sudo", "apt-get", "install", "-y", "nmap"], check=True)
3642
elif system == "Windows":
37-
print("Install nmap from https://nmap.org/download.html")
38-
print("Then restart your system.")
43+
print("Install nmap from https://nmap.org/download.html#windows")
44+
print("Restart system after installation")
3945
sys.exit(1)
4046

4147
if shutil.which("nmap") is None:
4248
print("Installation failed. Install nmap manually.")
4349
sys.exit(1)
4450

4551

46-
def print_output(output):
52+
def run_nmap(args):
53+
cmd = ["nmap"] + args
54+
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
55+
output = result.stdout
56+
4757
ports_section = False
4858
for line in output.splitlines():
4959
line = line.strip()
@@ -73,24 +83,63 @@ def print_output(output):
7383
print(line)
7484

7585

76-
def nmap(args):
77-
cmd = ["nmap"] + args
78-
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
79-
print_output(result.stdout)
86+
async def scan_port(host, port, sem):
87+
async with sem:
88+
try:
89+
reader, writer = await asyncio.open_connection(host, port)
90+
print(f"{port}/tcp open")
91+
writer.close()
92+
await writer.wait_closed()
93+
except:
94+
pass
8095

8196

82-
def main():
97+
async def full_scan(host):
98+
sem = asyncio.Semaphore(500)
99+
tasks = [scan_port(host, port, sem) for port in range(1, 65536)]
83100
try:
101+
await asyncio.gather(*tasks)
102+
except asyncio.CancelledError:
103+
pass
104+
105+
106+
def valid_host(host):
107+
try:
108+
socket.gethostbyname(host)
109+
return True
110+
except socket.error:
111+
return False
112+
113+
114+
def parse_args(parser):
115+
parser.add_argument("-v", "--version", action="version", version=VERSION)
116+
parser.add_argument("-n", nargs=argparse.REMAINDER, help="Run nmap")
117+
parser.add_argument("target", nargs="?", help="IP address, hostname or domain")
118+
return parser.parse_args()
119+
120+
121+
def main():
122+
parser = argparse.ArgumentParser(description=DESCRIPTION)
123+
args = parse_args(parser)
124+
125+
if args.n:
84126
install_nmap()
85-
if len(sys.argv) < 2:
127+
if len(args.n) == 0:
86128
subprocess.run(["nmap", "-h"])
87-
sys.exit(0)
88-
89-
nmap(sys.argv[1:])
90-
except Exception as e:
91-
print(f"Error: {e}")
129+
else:
130+
run_nmap(args.n)
131+
elif args.target and valid_host(args.target):
132+
asyncio.run(full_scan(args.target))
133+
else:
134+
parser.print_help()
92135
sys.exit(1)
93136

94137

95138
if __name__ == "__main__":
96-
main()
139+
try:
140+
main()
141+
except KeyboardInterrupt:
142+
sys.exit(130)
143+
except Exception as e:
144+
print(f"Error: {e}")
145+
sys.exit(1)

0 commit comments

Comments
 (0)