A network packet analyzer with a Qt based GUI, designed for real-time packet capture.
- Qt6 (6.10.1)
- PcapPlusPlus (25.05)
- Spdlog (1.17.0)
- CMake (3.16 or later)
- Doxygen (Optional for documentation)
-
Install dependencies
-
Configure Qt Path Before started to build you must edit
CMakeLists.txtand set the correct Qt path for your host:set(CMAKE_PREFIX_PATH "/path/to/Qt/6.10.1") -
Build
mkdir build && cd build && cmake .. && makeIt will build for Release build type. If you want to Debug, you must use:
mkdir build && cd build && cmake ..-DCMAKE_BUILD_TYPE=DEBUG && makeOptional: If you want to enable sanitizers for debugging, you can simply add
-DENABLE_ASAN=ONor-DENABLE_TSAN=ON
Optional: If you want to build documentation you might be consider to enable-DBUILD_DOCS=ON -
Run
sudo ./packet-scope
PacketCapture [Capture Thread]
|
| RawPacketData
v
ThreadSafeQueue<RawPacketData> [Blocking Buffer]
|
| pop()
v
Dispatcher Loop [Dispatcher Thread, in PipelineController]
|
| task submit()
v
ThreadPool [Worker Threads]
|
| PacketProcessor::process()
v
PacketStore [shared_mutex, owned by PipelineController]
|
| ParsedPacket (shared_lock read)
v
PacketListModel -> MainWindow [Main Thread]
-
Raw Packet Queue (Producer-Consumer)
- Producer: Capture Thread (single)
- Consumer: Dispatcher Thread (single)
- Synchronization:
std::mutex+std::condition_variable - Shutdown: Poison pill with
std::nullopt
-
Task Queue (ThreadPool)
- Producer: Dispatcher Thread (single)
- Consumers: Worker Threads (multiple)
- Synchronization: ThreadSafeQueue (same as above)
- Shutdown: Poison pill with empty
std::function<void()>
-
PacketStore (Reader-Writer)
- Writers: Worker Threads (multiple but
shared_mutexensures exclusivity) - Readers: Main Thread (UI refresh via
PacketListModel) - Synchronization:
std::shared_mutex - Lock Strategy:
addPacket(): Exclusive lock (one writer at a time)getById(),count(): Shared lock (multiple readers)
- Writers: Worker Threads (multiple but
-
Stop PacketCapture
-> No new packets produced -
Push poison pill (std::nullopt) to raw queue
-> Signals dispatcher to exit -
Dispatcher thread drains queue
-> Submits all pending packets to ThreadPool
-> Exits on receiving poison pill -
Join dispatcher thread
-> Ensures all packets are submitted -
ThreadPool shutdown
-> Stops accepting new tasks
-> Pushes empty function (poison pill) per worker
-> Workers drain their task queue
-> Workers exit on empty function -
Join all worker threads
-> Pipeline fully stopped

