1
- # Copyright 2023 ClarkCodes
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
1
+ '''
2
+ Copyright 2023 ClarkCodes
14
3
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ '''
15
16
# NetScanner.py
16
17
# Descripción: Utilidad de red escrita en Python para escanear y detectar dispositivos
17
18
# en un segmento de red indicado con nmap, obtener direcciones ip, direcciones mac y
18
19
# sus puertos abiertos.
19
- # Author: Clark - ClarkCodes
20
+
21
+ # Author: Clark - @ClarkCodes
22
+ # Versión: 2.0
20
23
21
24
# Imports
22
25
import nmap
26
+ import typer
27
+ from rich import print
28
+ from rich .table import Table
29
+ from rich import box
30
+ from rich .progress import Progress , SpinnerColumn , TextColumn
31
+
32
+ # Constantes
33
+ SEPARATOR = "********************************************"
23
34
24
- # Predefined
25
- separator = "********************************************"
35
+ # Global Variables
36
+ dev_Scanner = nmap . PortScanner ()
26
37
27
38
# Functions
28
- def printFoundHosts ( allHostsList : list [str ] ):
29
- if len ( allHostsList ) > 0 :
30
- print ( "\n *--- Dispositivos encontrados:\n " )
39
+ def printFoundHosts ( all_hosts_list : list [str ] ):
40
+ if len ( all_hosts_list ) > 0 :
41
+ print ( "[yellow] *--- Dispositivos encontrados:\n " )
31
42
32
- for i , host in enumerate ( allHostsList ):
33
- print ( separator )
34
- print ( f"*** Dispositivo #{ i + 1 } ***" )
35
- print ( f"Nombre: { devScanner [host ].hostname () } " )
36
- print ( f"Dirección Ip: { host } " )
43
+ for i , host in enumerate ( all_hosts_list ):
44
+ print ( SEPARATOR )
45
+ found_device_table = Table ( f"[green]Parámetro" , "[green]Datos" , title = f"[bold][green] *** Dispositivo #{ i + 1 } ***", title_justify = "center" , box = box . ROUNDED )
46
+ found_device_table . add_row ( f"Nombre:" , f" { dev_Scanner [host ].hostname ()} " )
47
+ found_device_table . add_row ( f"Dirección Ip:" , f" { host } " )
37
48
38
- if 'mac' in devScanner [host ]['addresses' ]:
39
- print ( f"Dirección MAC: { devScanner [host ]['addresses' ]['mac' ] } " )
49
+ if 'mac' in dev_Scanner [host ]['addresses' ]:
50
+ found_device_table . add_row ( f"Dirección MAC:" , f" { dev_Scanner [host ]['addresses' ]['mac' ]} " )
40
51
41
- print ( f"Estado: { devScanner [host ].state () } " )
52
+ found_device_table . add_row ( f"Estado:" , f" { dev_Scanner [host ].state ()} " )
42
53
43
- protocolsList = devScanner [host ].all_protocols ()
54
+ print ( "" )
55
+ print ( found_device_table )
44
56
45
- if len ( protocolsList ) > 0 :
46
- print ( "\n * Protocolos *" )
57
+ protocols_list = dev_Scanner [host ].all_protocols ()
47
58
48
- for proto in devScanner [host ].all_protocols ():
49
- print ( f"\t Protocolo: { proto } " )
50
- lport = devScanner [host ][proto ].keys ()
59
+ if len ( protocols_list ) > 0 :
60
+ protocols_table = Table ( f"[green]Parámetro" , "[green]Datos" , title = "[bold][green]* Protocolos *" , title_justify = "center" , box = box .ROUNDED )
61
+
62
+ for proto in dev_Scanner [host ].all_protocols ():
63
+ protocols_table .add_row ( f"Protocolo:" , f"{ proto } " )
64
+
65
+ lport = dev_Scanner [host ][proto ].keys ()
51
66
#lport.sort()
52
67
for port in lport :
53
- print ( f"\t \t Puerto: { port } \t Estado: { devScanner [host ][proto ][port ]['state' ] } " )
54
-
55
- print ( separator )
56
- else :
57
- print ( "\n No se encontraron dispositivos en el segmento de red indicado." )
58
-
68
+ protocols_table .add_row ( f"Puerto:" , f"{ port } " )
69
+ protocols_table .add_row ( f"Estado:" , f"{ dev_Scanner [host ][proto ][port ]['state' ]} " )
59
70
60
- ### Script Body Code
61
- print ( " \n *** Clark's Network Devices Scanner *** \n " )
71
+ print ( "" )
72
+ print ( protocols_table )
62
73
63
- devScanner = nmap .PortScanner ()
64
-
65
- ip = input ( "Ingrese el Rango Ip: " )
66
-
67
- print ( "\n Buscando dispositivos presentes en la red del rango Ip indicado: " , ip )
68
- print ( "Un momento por favor, en breve se mostrará el resultado.\n Detectando..." )
69
-
70
- devScanner .scan ( ip )
71
-
72
- printFoundHosts ( devScanner .all_hosts () )
73
-
74
- # Fin del Script - Mensaje de Despedida
75
- print ( "\n Gracias por usar este Script, es todo por ahora, hasta pronto, bye. :)" )
76
- print ( "@ClarkCodes(en todas las redes sociales).\n \n " )
74
+ print ( f"[yellow]{ SEPARATOR } " )
75
+ else :
76
+ print ( "[bright_black]\n No se encontraron dispositivos en el segmento de red indicado." )
77
+
78
+ def is_ip_range_valid ( ip_range : str ):
79
+ dots_counter = ip_range .count ( '.' )
80
+
81
+ if ( dots_counter != 3 ):
82
+ return False
83
+
84
+ segments_list = ip_range .split ( '.' )
85
+
86
+ for index , segment in enumerate ( segments_list ):
87
+ if ( ( index < 3 or ( index == 3 and segment .find ( '/' ) == - 1 ) ) ):
88
+ number = int ( segment )
89
+
90
+ if ( number < 0 or number > 255 ):
91
+ return False
92
+
93
+ return True
94
+
95
+ # Función Principal
96
+ def main ():
97
+ print ( "[bold green]\n *** Clark's Network Devices Scanner ***" )
98
+
99
+ while True : # Bucle para Repetir el Menú hasta que el usuario decida salir.
100
+ print ( "\n [bright_cyan]* Lobby de Opciones *[/bright_cyan]\n Ingrese un rango ip para escanear la red o ingrese 'q' para salir." )
101
+
102
+ user_input = input ( "\n Ingrese el Rango Ip: " )
103
+
104
+ if ( user_input == 'q' or user_input == 'Q' ): # Condición de Salida
105
+ print ( "[green]\n ✅ Esto ha sido todo por hoy.\n ❤ Muchas gracias por ejecutar este Script, hasta la próxima...💻 Happy Coding!,👋🏼 bye :D\n 😎 Clark." )
106
+ break
107
+
108
+ try :
109
+ if ( not is_ip_range_valid ( user_input ) ):
110
+ raise ValueError
111
+
112
+ print ( "" )
113
+ with Progress ( SpinnerColumn (), TextColumn ( "[yellow][progress.description]{task.description}" ), transient = True ) as progress :
114
+ progress .add_task ( description = "[light_sky_blue1]Buscando dispositivos presentes en la red dentro del rango Ip indicado... Un momento por favor..." , total = None )
115
+
116
+ dev_Scanner .scan ( user_input )
117
+ printFoundHosts ( dev_Scanner .all_hosts () )
118
+
119
+ except ValueError :
120
+ print ( "\n ❌ La estructura del rango ip no es válida, verifique nuevamente." )
121
+ except Exception as ex :
122
+ print ( "\n ❌ Oops... algo no ha salido bien, revise nuevamente por favor." )
123
+ print ( "Message Error: " , ex )
124
+
125
+ # Llamada a la Función Principal usando typer
126
+ if __name__ == "__main__" :
127
+ typer .run ( main )
0 commit comments