Skip to content

Commit f42a817

Browse files
committed
Update: Finish capture and show.
1 parent 5faaceb commit f42a817

File tree

3 files changed

+174
-20
lines changed

3 files changed

+174
-20
lines changed

tools/utils.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,87 @@
1+
import time
2+
import pcap
3+
import dpkt
4+
import threading
15
from winpcapy import WinPcapUtils, WinPcapDevices
26

37

48
def get_devices():
59
devices = WinPcapDevices.list_devices()
610
return devices
11+
12+
13+
def iter2string(ip):
14+
return f'{ip[0]}.{ip[1]}.{ip[2]}.{ip[3]}'
15+
16+
17+
def parse_raw_package(ts, data):
18+
eth = dpkt.ethernet.Ethernet(data)
19+
if not isinstance(eth.data, dpkt.ip.IP):
20+
return 0, '', '', ''
21+
timestamp = time.strftime('%Y-%m-%d %H:%M:%S', (time.localtime(ts)))
22+
ip = eth.data
23+
src = iter2string(ip.src)
24+
dst = iter2string(ip.dst)
25+
if ip.p == 17:
26+
udp = ip.data
27+
protocol = 'UDP'
28+
if udp.sport == 443 or udp.dport == 443:
29+
protocol += '-HTTPS'
30+
elif udp.sport == 80 or udp.dport == 80:
31+
protocol += '-HTTP'
32+
elif udp.sport == 53 or udp.dport == 53:
33+
protocol += '-DNS'
34+
elif ip.p == 6:
35+
tcp = ip.data
36+
protocol = 'TCP'
37+
if tcp.sport == 443 or tcp.dport == 443:
38+
protocol += '-HTTPS'
39+
elif tcp.sport == 80 or tcp.dport == 80:
40+
protocol += '-HTTP'
41+
else:
42+
protocol = str(ip.p)
43+
return timestamp, protocol, src, dst
44+
45+
46+
def capture_package(device, ip_address, event, task_list):
47+
while True:
48+
p = pcap.pcap(device, promisc=True)
49+
filter_str = 'ip and host ' + ip_address
50+
p.setfilter(filter_str)
51+
for ts, data in p:
52+
if event.is_set():
53+
task = ThreadWorker(ts, data)
54+
task_list.append(task)
55+
task.setDaemon(True)
56+
task.start()
57+
else:
58+
return
59+
60+
61+
class ThreadWorker(threading.Thread):
62+
def __init__(self, ts, data):
63+
super(ThreadWorker, self).__init__()
64+
self.result = None
65+
self.ts = ts
66+
self.data = data
67+
68+
def run(self):
69+
self.result = parse_raw_package(self.ts, self.data)
70+
71+
def get_result(self):
72+
return self.result
73+
74+
75+
class MainCaptureWorker(threading.Thread):
76+
def __init__(self, device, ip_address, event):
77+
super(MainCaptureWorker, self).__init__()
78+
self.device = device
79+
self.ip_address = ip_address
80+
self.event = event
81+
self.sub_task_list = []
82+
83+
def run(self):
84+
capture_package(self.device, self.ip_address, self.event, self.sub_task_list)
85+
86+
def get_result(self):
87+
return [worker.get_result() for worker in self.sub_task_list]

ui/DeviceChooser.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
from PyQt5.QtCore import QRect
2-
from PyQt5.QtWidgets import QWidget, QLabel, QDialog, QListWidget, QListWidgetItem, QPushButton, QHBoxLayout, \
3-
QTableWidget, QTableWidgetItem, QVBoxLayout, QMessageBox
1+
from PyQt5.QtWidgets import QDialog, QPushButton, QTableWidget, QTableWidgetItem, QVBoxLayout, QMessageBox
42
from tools import utils
53

64

@@ -19,19 +17,24 @@ def __init__(self, main_window):
1917
self.__init_ui()
2018

2119
def __init_ui(self):
20+
# Set window size
2221
self.setGeometry(self.main_window.main_window_rect)
2322
self.resize(self.main_window.main_window_size)
2423
self.setFixedSize(self.main_window.main_window_size)
2524

25+
# V Box Layout container
2626
total_container = QVBoxLayout()
27+
# Choose device and start capture button
2728
confirm_button = QPushButton('Choose and Start Capture', self)
2829
confirm_button.clicked.connect(self.start_button_listener)
2930
total_container.addWidget(confirm_button)
3031

32+
# Set table widget, column name, number and row count
3133
self.table.setRowCount(len(self.device_dic))
3234
self.table.setColumnCount(2)
3335
self.table.setHorizontalHeaderLabels(['device name', 'device id'])
3436
self.table.setVerticalHeaderLabels([str(i) for i in range(len(self.device_dic))])
37+
# set each index
3538
for idx, device in enumerate(self.device_dic):
3639
device_name_item = QTableWidgetItem(self.device_dic[device])
3740
device_id_item = QTableWidgetItem(device)
@@ -46,6 +49,8 @@ def __init_ui(self):
4649
def start_button_listener(self):
4750
row = self.table.currentRow()
4851
if row == -1:
52+
# It's illegal when row is -1, warning.
4953
QMessageBox.warning(self, 'Error!', 'Please choose legal row!')
50-
self.main_window.set_device(self.device_id_list[row], self.device_dic[self.device_id_list[row]])
51-
self.close()
54+
else:
55+
self.main_window.set_device(self.device_id_list[row], self.device_dic[self.device_id_list[row]])
56+
self.close()

ui/MainWindow.py

Lines changed: 83 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1+
import threading
2+
import time
3+
14
from PyQt5.QtCore import QRect, QSize
2-
from PyQt5.QtWidgets import QWidget, QLabel, QPushButton, QLineEdit, QApplication, QVBoxLayout, QHBoxLayout
5+
from PyQt5.QtWidgets import QWidget, QLabel, QPushButton, QLineEdit, QApplication, QVBoxLayout, QHBoxLayout, \
6+
QTableWidget, QMessageBox, QTableWidgetItem
37
from .DeviceChooser import DeviceChooser
8+
from tools import utils
49

510

611
class MainWindow(QWidget):
@@ -9,11 +14,23 @@ class MainWindow(QWidget):
914
"""
1015
def __init__(self, window_name, is_debug=True):
1116
super().__init__()
12-
# Get resolution of current monitor
13-
self.device_name = 'Name: NULL'
14-
self.device_id = 'ID: NULL'
17+
# Timer
18+
self.event = threading.Event()
19+
20+
# Basic value of device, ip address and duration time
21+
self.device_name = 'Device Name: NULL'
22+
self.device_id = 'Device ID: NULL'
23+
self.ip_address = '-1.-1.-1.-1'
24+
self.duration_time = -1
25+
26+
# Basic component
1527
self.device_id_label = QLabel(self.device_id, self)
1628
self.device_name_label = QLabel(self.device_name, self)
29+
self.time_input = QLineEdit(self)
30+
self.ip_input = QLineEdit(self)
31+
self.table = QTableWidget()
32+
33+
# Get resolution of current monitor
1734
self.desktop = QApplication.desktop()
1835
self.screen_rect = self.desktop.screenGeometry()
1936
self.height = self.screen_rect.height()
@@ -22,16 +39,21 @@ def __init__(self, window_name, is_debug=True):
2239
# calculate the window size by monitor size.
2340
self.window_height = int(self.height / 2)
2441
self.window_width = int(self.width / 3)
42+
2543
# The start position of main window.
2644
self.window_pos_x = int(self.width / 2 - self.window_width / 2)
2745
self.window_pos_y = int(self.height / 2 - self.window_height / 2)
46+
2847
# Main windows rect
2948
self.main_window_rect = QRect(self.window_pos_x, self.window_pos_y, self.window_width, self.window_height)
3049
self.main_window_size = QSize(self.window_width, self.window_height)
50+
3151
# Set main window title
3252
self.setWindowTitle(window_name)
53+
3354
# Call init_ui to init window.
3455
self.init_ui()
56+
3557
# If is_debug is True, print basic information of main window.
3658
if is_debug:
3759
self.__print_info()
@@ -54,41 +76,87 @@ def init_ui(self):
5476
total_container = QVBoxLayout()
5577
top_container = QHBoxLayout()
5678
middle_container = QHBoxLayout()
79+
bottom_container = QHBoxLayout()
5780

5881
choose_device_btn = QPushButton('Choose device', self)
59-
# choose_device_btn.move(20, 20)
6082
choose_device_btn.clicked.connect(self.choose_device_button_listener)
6183
top_container.addWidget(choose_device_btn)
6284
top_container.addWidget(self.device_id_label)
6385
top_container.addWidget(self.device_name_label)
64-
# self.device_id_label.move(220, 27)
6586

66-
# Middle h-box, input capture duration time.
6787
time_hint = QLabel('Capture duration (s)', self)
68-
# time_hint.move(20, 60)
69-
time_input = QLineEdit(self)
70-
# time_input.move(220, 57)
71-
88+
ip_address_hint = QLabel('IP address', self)
7289
middle_container.addWidget(time_hint)
73-
middle_container.addWidget(time_input)
90+
middle_container.addWidget(self.time_input)
91+
middle_container.addWidget(ip_address_hint)
92+
middle_container.addWidget(self.ip_input)
93+
94+
self.table.setColumnCount(4)
95+
self.table.setHorizontalHeaderLabels(['Time', 'Protocol', 'Origin Address', 'Target Address'])
96+
bottom_container.addWidget(self.table)
7497

7598
total_container.addLayout(top_container)
7699
total_container.addLayout(middle_container)
100+
total_container.addLayout(bottom_container)
77101

78102
self.setLayout(total_container)
79-
80103
self.show()
81104

82105
def choose_device_button_listener(self):
83106
chooser = DeviceChooser(self)
84107
chooser.show()
85108
chooser.exec_()
86109

110+
def __get_input(self):
111+
self.duration_time = self.time_input.text()
112+
self.ip_address = self.ip_input.text()
113+
114+
def __check_and_transform_input_value(self):
115+
self.__get_input()
116+
try:
117+
self.duration_time = int(self.duration_time)
118+
except ValueError:
119+
QMessageBox.warning(self, 'Value Error', 'Please input correct time!')
120+
return False
121+
if self.duration_time <= 0:
122+
QMessageBox.warning(self, 'Value Error', 'Please input positive time!')
123+
return False
124+
if self.ip_address == '' or self.ip_address == '-1.-1.-1.-1' or self.ip_address is None:
125+
QMessageBox.warning(self, 'Value Error', 'Please input right ip address')
126+
return False
127+
return True
128+
129+
def __show_result(self):
130+
res = self.capture_task.get_result()
131+
self.table.setRowCount(len(res))
132+
for i, line in enumerate(res):
133+
for j, item in enumerate(line):
134+
self.table.setItem(i, j, QTableWidgetItem(item))
135+
self.show()
136+
137+
def __time_control(self):
138+
time.sleep(self.duration_time)
139+
self.event.clear()
140+
self.__show_result()
141+
142+
def __handle_capture(self):
143+
if self.__check_and_transform_input_value():
144+
self.event.set()
145+
self.capture_task = utils.MainCaptureWorker(self.device_id, self.ip_address, self.event)
146+
controller = threading.Thread(
147+
target=self.__time_control
148+
)
149+
self.capture_task.start()
150+
controller.start()
151+
else:
152+
return
153+
87154
def set_device(self, device_id, device_name):
88155
self.device_id = device_id
89-
self.device_id_label.setText('ID: ' + device_id)
156+
self.device_id_label.setText('Device ID: ' + device_id)
90157
self.device_name = device_name
91-
self.device_name_label.setText('Name: ' + device_name)
158+
self.device_name_label.setText('Device Name: ' + device_name)
92159
self.device_id_label.adjustSize()
93160
self.device_name_label.adjustSize()
94161
self.show()
162+
self.__handle_capture()

0 commit comments

Comments
 (0)