forked from fa-python-network/2_threaded_server
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathscanner.py
More file actions
139 lines (114 loc) · 4.34 KB
/
Copy pathscanner.py
File metadata and controls
139 lines (114 loc) · 4.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import socket
import threading
import queue
import time
import sys
socket.setdefaulttimeout(0.25)
que = queue.Queue()
results = []
def ip_validation(address: str) -> bool:
"""Проверка на корректность ip-адреса (v4)"""
error_message = f"Некорректный ip-адрес {address}"
ok_message = f"Корректный ip-адрес {address}"
try:
socket.inet_pton(socket.AF_INET, address)
except AttributeError:
try:
socket.inet_aton(address)
except socket.error:
print(error_message)
return False
return address.count(".") == 3
except socket.error:
print(error_message)
return False
print(ok_message)
return True
class ProgressBar:
"""Класс визуализации прогресса сканирования"""
def __init__(self, iterable: iter, size: int) -> None:
self.iterable = iterable
self.iter_len = len(self.iterable)
self.output = sys.stdout
self.size = size
def display(self, j):
x = int(self.size * j / self.iter_len)
current_percent = round(j / self.iter_len * 100, 1)
items_ready_str = "=" * x
items_waiting_str = " " * (self.size - x)
self.output.write(
f"[{items_ready_str}{items_waiting_str}] {current_percent}/100%\r"
)
self.output.flush()
def processing(self):
self.display(0)
for i, item in enumerate(self.iterable):
yield item
self.display(i + 1)
self.output.write("\n")
self.output.flush()
class Worker(threading.Thread):
def __init__(self, number: int, ip: str) -> None:
threading.Thread.__init__(self, name=f"t{number}")
self.number = number
self.ip = ip
def run(self):
global results
while True:
try:
current_port = que.get_nowait()
# print(f"Поток {self.number} взял порт {current_port}..")
sock = socket.socket()
try:
sock.connect((self.ip, current_port))
# print(f"Порт {current_port} открыт")
with threading.Lock():
results.append(current_port)
except ConnectionRefusedError:
continue
except socket.timeout:
continue
except Exception as e:
print(f"Какая-то новая ошибка: {e}")
continue
finally:
sock.close()
que.task_done()
# Елси больше нет заданий - гасим поток
except queue.Empty:
# print(f"Для потока {self.number} больше нет портов")
break
class Scanner:
def __init__(self, ip: str, max_port: int) -> None:
self.time_begin = time.monotonic()
self.ip = ip
self.max_port = max_port
self.result = []
self.adder()
for i in range(300):
t = Worker(i, self.ip)
t.start()
progress_bar = ProgressBar(range(self.max_port + 1), 35)
for i in progress_bar.processing():
while (self.max_port - que.unfinished_tasks) < i:
continue
self.result_output()
def adder(self):
"""Добавляет порты в очередь"""
for port in range(1, self.max_port + 1):
que.put(port)
def result_output(self):
time_result = round(time.monotonic() - self.time_begin, 2)
results_str = "\n -> ".join(map(str, results))
print(f"Заняло времени: {time_result} сек.")
print(f"**Открытые порты**\n -> {results_str}")
def main():
DEFAULT_IP = "127.0.0.1"
n = 2 ** 16 - 1
ip_input = input("Введите ip адрес для сканирования -> ")
if not ip_validation(ip_input):
ip_input = DEFAULT_IP
print(f"Выставили дефолтный ip: {DEFAULT_IP}")
scanner = Scanner(ip_input, n)
if __name__ == "__main__":
main()