HPD API v1.2
A free, public HTTP API for decoding raw network packets using the Wireshark/tshark engine. No authentication required.
Introduction
Hex Packet Decoder exposes a REST API at /api that accepts a raw hex packet
and returns a full protocol dissection in XML (PDML), plain text, or PNG image format.
All requests are simple GET calls — no API key, for reasonable use only (100 requests maximum per hour).
Endpoint
GET https://hpd.gasmi.net/api
Parameters
| Parameter | Required | Values | Description |
|---|---|---|---|
data | Yes | hex string | Raw packet bytes in hex. Accepts raw hex, spaced hex, tcpdump/Wireshark dump formats. The packet must start with an Ethernet header unless force is set. |
format | No | xml (default)textfilepng |
xml — PDML XML, inline in the response.text — plain text tree (equivalent to tshark -V).file — PDML XML as a downloadable attachment.png — a PNG image of the hex map.
|
force | No | ipv4ipv6 |
Treat data as a raw IPv4 or IPv6 payload with no Ethernet header. HPD prepends a dummy 14-byte Ethernet header automatically. |
Response: XML (PDML)
The default response wraps standard
PDML
output with an <hpd_info> metadata block at the top of the
<pdml> element.
hpd_info fields
| Field | Description |
|---|---|
bytes | Normalised hex bytes that were decoded (including any prepended dummy Ethernet header) |
force_ipv4 | True if force=ipv4 was used |
force_ipv6 | True if force=ipv6 was used |
time_ms | Server-side decoding time in milliseconds |
request_error | True if the request itself was invalid |
packet_error | True if tshark could not parse the packet |
hpd_version | HPD version string |
Example XML response
<?xml version="1.0" encoding="utf-8"?>
<pdml version="0" creator="hpd.gasmi.net" …>
<hpd_info>
<bytes>000000000000000000000000080045000028…</bytes>
<force_ipv4>True</force_ipv4>
<force_ipv6>False</force_ipv6>
<time_ms>374</time_ms>
<request_error>False</request_error>
<packet_error>False</packet_error>
<hpd_version>4.1</hpd_version>
</hpd_info>
<packet>
<proto name="eth" showname="Ethernet II, Src: …" size="14" pos="0">
<!-- field elements … -->
</proto>
<proto name="ip" …> … </proto>
<proto name="udplite" …> … </proto>
</packet>
</pdml>
Response: Text
With format=text, the response is a plain-text protocol tree identical to
tshark -V output — useful for quick inspection or logging.
Frame 1: 60 bytes on wire (480 bits), 60 bytes captured (480 bits)
Encapsulation type: Ethernet (1)
Arrival Time: Jul 14, 2020 01:58:36.000000000 CEST
…
Ethernet II, Src: 00:00:00_00:00:00, Dst: 00:00:00_00:00:00
Type: IPv4 (0x0800)
Internet Protocol Version 4, Src: 139.133.204.176, Dst: 139.133.204.183
Version: 4
Header Length: 20 bytes
Total Length: 40
Time to live: 64
Protocol: UDPLite (136)
Source: 139.133.204.176
Destination: 139.133.204.183
Lightweight User Datagram Protocol, Src Port: 32768, Dst Port: 1234
Source Port: 32768
Destination Port: 1234
Checksum: 0xf53f
Data (12 bytes)
0000 68 65 6c 6c 6f 20 77 6f 72 6c 64 0a hello world.
Response: PNG
With format=png, the response is a PNG image of the hex map with the protocol
legend — the same graphic shown on the main interface. Useful for embedding in reports or
documentation.
Examples: curl
IPv4 + UDPLite payload, default XML output
curl "https://hpd.gasmi.net/api?force=ipv4&data=4500002852924000408837498B85CCB08B85CCB7800004D2000CF53F68656C6C6F20776F726C640A000000000000"
Plain text output
curl "https://hpd.gasmi.net/api?force=ipv4&data=4500002852924000408837498B85CCB08B85CCB7800004D2000CF53F68656C6C6F20776F726C640A000000000000&format=text"
Download as PDML file
curl -O -J "https://hpd.gasmi.net/api?force=ipv4&data=4500002852924000…&format=file"
Download as PNG
curl -o packet.png "https://hpd.gasmi.net/api?force=ipv4&data=4500002852924000…&format=png"
Examples: Python
Decode and walk the PDML tree
import requests, xml.etree.ElementTree as ET
hex_data = "4500002852924000408837498B85CCB08B85CCB7800004D2000CF53F68656C6C6F20776F726C640A000000000000"
r = requests.get("https://hpd.gasmi.net/api", params={
"data": hex_data,
"force": "ipv4",
})
root = ET.fromstring(r.text)
# Print top-level protocol names
for proto in root.find("packet").iter("proto"):
print(proto.get("name"), "→", proto.get("showname"))
Check for errors
info = root.find("hpd_info")
if info.findtext("request_error") == "True":
raise ValueError("HPD: bad request")
if info.findtext("packet_error") == "True":
raise ValueError("HPD: could not decode packet")
Examples: JavaScript
Fetch and parse XML
const params = new URLSearchParams({
data: "4500002852924000408837498B85CCB08B85CCB7800004D2000CF53F68656C6C6F20776F726C640A000000000000",
force: "ipv4",
});
const res = await fetch(`https://hpd.gasmi.net/api?${params}`);
const text = await res.text();
const xml = new DOMParser().parseFromString(text, "text/xml");
const error = xml.querySelector("request_error")?.textContent;
if (error === "True") throw new Error("HPD request error");
xml.querySelectorAll("packet > proto").forEach(proto => {
console.log(proto.getAttribute("name"), proto.getAttribute("showname"));
});
HPD by Salim Gasmi — packet decoding powered by Wireshark / tshark — hpd.gasmi.net