-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpy
198 lines (167 loc) · 6.83 KB
/
py
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
import scapy.all as scapy
import pandas as pd
import tkinter as tk
from tkinter import ttk
from threading import Thread
import queue
from dash import Dash, dcc, html
from dash.dependencies import Input, Output
import plotly.express as px
import webview
# Create a DataFrame to store packet information
df = pd.DataFrame(columns=["Source IP", "Destination IP", "Protocol", "Source Port", "Destination Port", "Service"])
packet_queue = queue.Queue()
# Function to append data to the DataFrame and update the UI table
def packet_callback(packet):
try:
if packet.haslayer(scapy.IP):
ip_src = packet[scapy.IP].src
ip_dst = packet[scapy.IP].dst
else:
ip_src = ip_dst = "N/A"
if packet.haslayer(scapy.TCP):
protocol = "TCP"
sport = packet[scapy.TCP].sport
dport = packet[scapy.TCP].dport
elif packet.haslayer(scapy.UDP):
protocol = "UDP"
sport = packet[scapy.UDP].sport
dport = packet[scapy.UDP].dport
elif packet.haslayer(scapy.ICMP):
protocol = "ICMP"
sport = dport = "N/A"
else:
protocol = "Other"
sport = dport = "N/A"
# Determine the service based on the port number
if dport == 80 or sport == 80:
service = "HTTP"
elif dport == 443 or sport == 443:
service = "HTTPS"
elif dport == 3389 or sport == 3389:
service = "RDP"
else:
service = "Other"
# Put packet info in the queue
new_row = {"Source IP": ip_src, "Destination IP": ip_dst, "Protocol": protocol, "Source Port": sport,
"Destination Port": dport, "Service": service}
packet_queue.put(new_row)
except Exception as e:
print(f"Error in packet_callback: {e}")
# Function to update the UI table safely and sync with DataFrame
def update_ui():
global df
while not packet_queue.empty():
new_row = packet_queue.get()
tree.insert("", "end", values=(new_row["Source IP"], new_row["Destination IP"], new_row["Protocol"],
new_row["Source Port"], new_row["Destination Port"], new_row["Service"]))
df = pd.concat([df, pd.DataFrame([new_row])], ignore_index=True)
root.after(100, update_ui) # Check for new packets every 100 ms
# Function to start sniffing packets
def start_sniffing():
try:
scapy.sniff(prn=packet_callback, store=0, filter="ip", count=0)
except Exception as e:
status_label.config(text=f"Error: {str(e)}")
print(f"Error in start_sniffing: {e}")
# Function to start sniffing in a new thread
def start_sniffer_thread():
sniff_thread = Thread(target=start_sniffing, daemon=True)
sniff_thread.start()
status_label.config(text="Sniffing started...")
update_ui() # Start updating the UI
# Function to export data to CSV
def export_to_csv():
filename = "packet_log.csv"
try:
df.to_csv(filename, index=False)
status_label.config(text=f"Data exported to {filename}")
print(f"Data exported to {filename}")
except Exception as e:
status_label.config(text=f"Export failed: {str(e)}")
print(f"Error in export_to_csv: {e}")
# Function to analyze collected data and show the graph
def analyze_data():
# Open Dash visualization in a new webview window
analysis_window = tk.Toplevel(root)
analysis_window.title("Data Analysis and Graph")
analysis_window.geometry("800x600")
# Embed the Dash app in the new window
webview_frame = webview.create_window("Packet Analysis", "http://127.0.0.1:8050", width=800, height=600)
webview.start(gui='tkinter')
# Create the main Tkinter application window
root = tk.Tk()
root.title("Professional Packet Sniffer")
root.geometry("900x500")
root.configure(bg="#f0f0f0") # Set background color
# Add CSS styling to the UI
def add_css():
style = ttk.Style()
style.theme_use("clam")
style.configure("Treeview", font=("Helvetica", 10), rowheight=25, background="#ffffff", fieldbackground="#ffffff")
style.configure("Treeview.Heading", font=("Helvetica", 11, "bold"), background="#4CAF50", foreground="white")
style.configure("TButton", font=("Helvetica", 10), background="#4CAF50", foreground="white")
style.map("TButton", background=[["active", "#45a049"]])
style.configure("TLabel", font=("Helvetica", 10))
add_css()
# Create frames for organization
control_frame = ttk.Frame(root)
control_frame.pack(fill="x", padx=10, pady=5)
display_frame = ttk.Frame(root)
display_frame.pack(fill="both", expand=True, padx=10, pady=5)
# Control buttons
start_button = ttk.Button(control_frame, text="Start Sniffing", command=start_sniffer_thread)
start_button.pack(side="left", padx=5)
export_button = ttk.Button(control_frame, text="Export to CSV", command=export_to_csv)
export_button.pack(side="left", padx=5)
analyze_button = ttk.Button(control_frame, text="Analyze Data", command=analyze_data)
analyze_button.pack(side="left", padx=5)
# Treeview for displaying packet data
columns = ["Source IP", "Destination IP", "Protocol", "Source Port", "Destination Port", "Service"]
tree = ttk.Treeview(display_frame, columns=columns, show="headings")
for col in columns:
tree.heading(col, text=col)
tree.column(col, width=150)
tree.pack(fill="both", expand=True)
# Create a status label
status_label = ttk.Label(root, text="Status: Ready", anchor="w")
status_label.pack(fill="x", padx=10, pady=5)
# Create a Dash application for visualization
app = Dash(__name__)
# Layout for Dash
app.layout = html.Div([
dcc.Graph(id='protocol-graph'),
html.Div([
dcc.Interval(id='interval-component', interval=1000, n_intervals=0),
html.Div(id='data-summary', style={"font-size": "16px", "margin": "20px 0"})
])
])
# Callback to update the graph and add analyzed data summary
@app.callback([
Output('protocol-graph', 'figure'),
Output('data-summary', 'children')
],
Input('interval-component', 'n_intervals')
)
def update_graph(n):
global df
# Count packets by protocol
protocol_counts = df['Protocol'].value_counts().reset_index()
protocol_counts.columns = ['Protocol', 'Count']
# Create a bar chart
fig = px.bar(protocol_counts, x='Protocol', y='Count', title='Packet Protocol Distribution',
labels={'Protocol': 'Protocol Type', 'Count': 'Number of Packets'},
color='Protocol')
# Add analyzed data summary
total_packets = len(df)
unique_ips = df['Source IP'].nunique()
summary = f"Total Packets: {total_packets}, Unique Source IPs: {unique_ips}"
return fig, summary
# Start the Dash app in a separate thread
def run_dash():
app.run_server(debug=False, use_reloader=False)
# Start the Dash app
dash_thread = Thread(target=run_dash, daemon=True)
dash_thread.start()
# Run the Tkinter event loop
root.mainloop()