An annotated explanation of the code with details on what each component is (method, function, variable, or construct) for my utility at
https://github.com/genzo1977/PyNetScanner
Imports
import tkinter as tk # Module import
from tkinter import ttk # Module import
from ipaddress import ip_network # Function import
from pythonping import ping # Function import
import threading # Module import
- Module Import:
tkinter,threading- These are libraries/modules that provide additional functionality.
tkinteris for GUI creation, andthreadingis for running tasks in parallel.
- These are libraries/modules that provide additional functionality.
- Function Import:
ip_network,ping- Specific functions brought into the code for subnet handling (
ip_network) and network pinging (ping).
- Specific functions brought into the code for subnet handling (
Global Variable
cancel_scan = False # Global variable
- Variable:
cancel_scan- A Boolean flag used to indicate whether the scanning process should stop. It’s modified across functions (global scope).
Function: scan
def scan(): # Function definition
global cancel_scan # Keyword: global variable reference
- Function:
scan- A block of code that performs the main scanning task when triggered.
- Global Variable Reference:
cancel_scan- Allows the function to modify the globally defined variable.
Subsection: Input Validation
network_addr = network_var.get() # Method call: variable retrieval
try:
network = ip_network(network_addr, strict=False) # Method: input parsing
except ValueError: # Exception Handling: invalid input
- Variable Assignment:
network_addr- Fetches the user input from the GUI text field.
- Method Call:
network_var.get()- Calls the
getmethod to retrieve text input.
- Calls the
- Input Parsing:
ip_network- Ensures the input is a valid CIDR format. Adjusts the IP range with
strict=False.
- Ensures the input is a valid CIDR format. Adjusts the IP range with
- Exception Handling:
tryandexcept ValueError- Catches invalid inputs and gracefully displays an error.
Subsection: Progress Calculation
total_hosts = len(list(network.hosts())) # Function calls
progress_step = 100 / total_hosts # Calculation
- Function Calls:
list(...)andlen(...)- Converts the generator of hosts to a list and counts its elements.
- Variable Assignment:
progress_step- Calculates the percentage increment for the progress bar per host.
Nested Function: run_scan
def run_scan(): # Nested function definition
global cancel_scan # Global variable reference
- Function:
run_scan- A sub-function of
scan, handling the actual IP scanning in a separate thread.
- A sub-function of
- Global Variable Reference:
cancel_scan- Ensures the function can check for user cancellation.
Subsection: Looping Through Hosts
for index, ip in enumerate(network.hosts(), start=1): # Loop construct
if cancel_scan: # Conditional check
- Loop:
for- Iterates through all host IPs in the network.
- Conditional Check:
if cancel_scan- Stops the scan if the cancel button was clicked.
Subsection: Pinging and GUI Updates
response = ping(ip, count=1, timeout=1, verbose=False) # Function call
if response.success(): # Conditional check
results_listbox.insert(tk.END, f"IP: {ip} is online") # Method call
progress_bar["value"] += progress_step # Progress bar update
- Function Call:
ping- Sends an ICMP ping to check if the IP is reachable.
- Conditional Check:
if response.success()- Verifies whether the ping succeeded.
- Method Call:
results_listbox.insert- Updates the listbox widget to display a result.
- Progress Bar Update:
progress_bar["value"]- Advances the progress bar by the calculated step.
Subsection: Cleanup After Completion
scan_button.config(state=tk.NORMAL, text="Scan") # Method call
cancel_button.config(state=tk.DISABLED) # Method call
- Method Call:
config- Resets the buttons to their initial state after the scan ends.
Threading
threading.Thread(target=run_scan, daemon=True).start() # Thread creation
- Threading: Runs the
run_scanfunction in a separate thread so that the GUI remains responsive.
Function: cancel
def cancel(): # Function definition
global cancel_scan # Global variable reference
cancel_scan = True # Variable modification
cancel_button.config(state=tk.DISABLED) # Method call
- Function:
cancel- Handles the user’s action to stop the ongoing scan.
- Variable Modification:
cancel_scan = True- Signals the
run_scanloop to stop.
- Signals the
- Method Call:
cancel_button.config- Disables the cancel button to prevent repeated clicks.
GUI Setup
if __name__ == "__main__": # Main program check
root = tk.Tk() # Object creation: main window
root.title("Network Scanner") # Method call
root.geometry("400x300") # Method call
root.resizable(False, False) # Method call
- Main Program Check:
if __name__ == "__main__"- Ensures the code runs only if this script is the entry point.
- Object Creation:
tk.Tk()- Initializes the main application window (
root).
- Initializes the main application window (
- Method Calls:
.title(),.geometry(),.resizable()- Configure the window title, size, and resize behavior.
Input and Buttons
tk.Label(root, text="Network (e.g., 192.168.1.0/24):").pack(pady=5) # Widget creation
tk.Entry(root, textvariable=network_var, width=entry_width, justify=tk.CENTER).pack(pady=5) # Widget creation
scan_button = tk.Button(root, text="Scan", command=scan, width=entry_width).pack(pady=5) # Widget creation
cancel_button = tk.Button(root, text="Cancel", command=cancel, state=tk.DISABLED, width=entry_width).pack(pady=5) # Widget creation
- Widget Creation:
Label,Entry,Button- Adds interactive elements (label, text entry, buttons) to the GUI.
- Attributes:
text: Sets the label/button text.command: Specifies the function to call on user interaction.state: Defines the button’s enabled/disabled state.
Progress Bar
progress_bar = ttk.Progressbar(root, orient="horizontal", length=300, mode="determinate").pack(pady=10) # Widget creation
progress_label = tk.Label(root, text="Progress: 0%").pack() # Widget creation
- Widget Creation:
Progressbar,Label- Displays scanning progress visually and as text.
Results Listbox
results_listbox = tk.Listbox(root, width=45, height=10).pack(pady=10) # Widget creation
- Widget Creation:
Listbox- Adds a scrollable area to display scan results.
Main Loop
root.mainloop() # Event loop
- Event Loop: Starts the GUI application and keeps it running until closed by the user.
This breakdown includes every component’s type, purpose, and role in the program.