Skip to content

Tinshea/WireOwl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

WireOwl — a packet analyzer that takes hex dumps apart, layer by layer

Python 3.11+ tkinter 2 dependencies Cross-platform

WireOwl

A Wireshark-inspired packet analyzer written from scratch in Python. Point it at a hex dump and it walks the bytes down the stack — Ethernet frame, then IPv4 header, then TCP segment, then HTTP payload — rendering each layer as readable fields, drawing a conversation flow graph, and exporting the whole analysis as a PDF.

Every protocol decoder is hand-written: no scapy, no dpkt. The point of the project was to read RFCs and slice bytes by hand, so the parsers work off raw offsets and bit masks.


Quick start

You need Python 3.11+ with tkinter. Nothing else — the two runtime dependencies install themselves.

git clone https://github.com/Tinshea/WireOwl.git
cd WireOwl

Linux / macOS

chmod +x run.sh
./run.sh

Windows (PowerShell)

.\run.ps1

Or, if you have make:

make setup && make run

All three create a .venv, install the dependencies and launch the app. Press Start, pick any file from sample/, and you are in.

WireOwl reads hex dump text, not .pcap. It needs no root privileges and never touches a network interface — it only ever parses a file you hand it. To analyse your own traffic, export it from Wireshark with File → Export Packet Dissections → As Plain Text, with "Hex dump" enabled.


What it looks like

Load a capture and every frame is summarised on one line: source and destination, ports, TCP flags, sequence and acknowledgement numbers, window size. Frames belonging to the same conversation share a colour, HTTP frames are picked out in magenta, and clicking one decodes it in the panel below — here the TCP layer of a SYN.

Frame list showing a TCP handshake, with the TCP layer of the selected frame decoded below

The five icons down the left switch which layer the detail panel shows: the raw frame, Ethernet, IPv4, TCP, or the reassembled HTTP payload.

Filtering

Type an expression and the frame list narrows to matching frames. The field turns teal when the expression parses and red when it does not, so a typo is obvious. Filters are evaluated by loading the parsed frames into an in-memory SQLite schema and running the expression as a WHERE clause — below, 477 TCP frames pulled out of a 2.3 MB capture.

The filter protocol == 6 applied, narrowing a large capture to its TCP frames

Field Matches on Example
protocol IP protocol number (see table below) protocol == 6
ip.src / ip.addr IPv4 source / destination ip.src == 192.168.1.102
tcp.src / tcp.addr TCP source / destination port tcp.addr == 80
eth.src / eth.addr MAC source / destination eth.src == f0189859ae32
http.version HTTP version string http.version == 1.1

Operators are == and !=, combined with and / && / or / ||:

protocol == 6 and ip.src == 192.168.31.69
ip.src == 192.168.1.102 or ip.addr == 192.168.1.117

Two things to know about the syntax:

  • protocol holds the numeric IANA value, not a name — protocol == 6, not protocol == TCP. The latter parses fine and simply matches nothing.
  • Compound expressions must stay within one field family. Each family lives in its own SQLite table (protocol/ip.* together, tcp.*, eth.*, http.version), and the generated query targets the table named by the first term. protocol == 6 and ip.src == … works; protocol == 6 and tcp.addr == 80 is rejected.

Flow graph

The flow graph lays hosts out as columns and frames as rows, drawing each exchange as an arrow annotated with its ports — the shape of a conversation at a glance.

Flow graph with hosts as columns and one arrow per frame, annotated with ports

PDF report

One click writes a full report into PDF/: a linked table of contents, the flow graph, then one page per frame with every decoded field.

A page of the generated PDF report showing a fully decoded frame


How it works

traitement() reads the dump, treating a line that starts at offset 0000 as the start of a new frame, and strips the offset column and ASCII gutter to leave one hex string per frame. Those strings then flow through four parsers, each consuming the header it understands and handing the remainder to the next:

hex text  ──▶  trame.tramecalcul      MAC addresses, EtherType
          ──▶  paquetip.paquetipv4    IPv4 header: TTL, flags, protocol, addresses
          ──▶  tcp.tcpaquet           ports, sequence numbers, flags, window
          ──▶  httpmodule.req_or_rep  request/response, method, status, headers

Each stage appends its human-readable output to Trames/TrameN.txt, and populates module-level dictionaries keyed by frame number (Source_Address, Port_Source, flagdic, …). Those dictionaries are what the GUI, the filter engine and the PDF exporter all read from — the parse happens once, then everything else is a lookup.

Supported protocols

Layer What is decoded
Ethernet Source and destination MAC, EtherType
IPv4 Header length, TOS, total length, identification, DF/MF, fragment offset, TTL, protocol, header checksum, addresses
TCP Ports, sequence and acknowledgement numbers, data offset, all six flags, window, checksum, urgent pointer, options
HTTP Request vs response, method, version, status code, headers

IP protocol numbers are resolved through dico_protocol: 1 ICMP, 2 IGMP, 6 TCP, 8 EGP, 9 IGP, 17 UDP, 36 XTP, 46 RSVP.

Only IPv4 is parsed. Frames carrying anything else — IPv6, ARP — are listed with their type and flagged n'est pas pris en charge par le programme rather than decoded. Likewise, only TCP gets a transport-layer decode; UDP frames are counted and filterable but not broken down.


Sample captures

sample/ doubles as the test suite — several files exist specifically to exercise error paths.

File Contents
Trace.txt, TCP_1..3.txt Clean TCP handshakes — the best starting point
HTTP_2.txt, HTTP_TCP.txt HTTP request/response over TCP
ARP_UDP_ICMP_IGMP.txt 63 mixed frames; good for exercising filters
test-3f.txt 2.3 MB, ~500 frames — the stress case
HTTP_1.txt A single IPv6 frame, i.e. the unsupported-protocol path
Corrupted.txt, Empty.txt, Text.txt Malformed input; should warn, not crash

Project structure

WireOwl/
├── run.sh / run.ps1     # set up the venv and launch
├── Makefile             # setup / run / clean
├── core/
│   ├── main.py          # entry point
│   ├── source.py        # tkinter GUI, dump parsing, all screens
│   ├── trame.py         # Ethernet layer
│   ├── paquetip.py      # IPv4 layer
│   ├── tcp.py           # TCP layer
│   ├── httpmodule.py    # HTTP layer
│   ├── filtrage.py      # SQLite-backed filter engine
│   └── pdf.py           # report + flow graph export
├── affichage/           # icons, backgrounds, logo
├── sample/              # hex dump captures (see above)
├── Tools/requirements.txt
├── Trames/              # per-frame decode output (generated)
└── PDF/                 # generated reports

main.py must run with the repository root as the working directory: source.py loads its images through relative paths like ./affichage/bg.png. The launch scripts handle this for you.


Notes

  • tkmacosx is optional. It exists only to give macOS a button widget that honours bg; source.py falls back to tkinter.Button everywhere else, so it is installed on macOS only.
  • Linux needs tkinter installed separately on many distributions — sudo apt install python3-tk on Debian/Ubuntu. run.sh checks and tells you.
  • Trames/ is wiped on every load. It holds the per-frame decode dumps and the filter database, all rebuilt from scratch each time you open a capture.
  • The UI and the decode output are in French, matching the coursework it was written for.

Credits

Sorbonne Université — Networks course.

No license specified.

About

Wireshark-inspired network packet analyzer in Python — GUI with tkinter, multi-protocol parsing (TCP/UDP/HTTP/IPv4/IPv6/MAC), SQLite-backed filter engine, and automated PDF report generation.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages