-
Notifications
You must be signed in to change notification settings - Fork 1
NTP Running and Testing
How to build, run, and test the NTP parser with both real captured packets and hand-crafted test inputs.
From the Hammer repository root, build the checkout-local library first:
scons examplesThen build the NTP example:
cd examples/ntp
makeThis produces the ntp_parser executable. If ../../build/opt/src is not present, the Makefile falls back to pkg-config libhammer. See Getting Started for prerequisites.
To clean and rebuild:
make clean && makeThe parser accepts raw bytes (not hex strings). Two ways to provide input:
Pass a file path as a command-line argument:
./ntp_parser packet/ntp_stream.binPipe raw bytes through stdin:
cat packet/ntp_stream.bin | ./ntp_parserIf you have a hex string (common when working with protocol specs or packet captures), convert it with xxd:
echo -n "e30003fa000100000001000000000000000000000000000000000000000000000000000000000000ec17ee223f54e6a6" | xxd -r -p | ./ntp_parserThe flags:
-
echo -n- no trailing newline -
xxd -r -p- reverse hex dump, plain (no line numbers)
The Makefile includes a convenience target:
make testpThis runs:
cat packet/ntp_stream.bin | ./ntp_parserExpected output:
Reading from stdin
Packet accepted
The smallest valid NTP packet is exactly 48 bytes: header + data fields, no extensions, no MAC.
echo -n "e30003fa000100000001000000000000000000000000000000000000000000000000000000000000ec17ee223f54e6a6" \
| xxd -r -p | ./ntp_parserBreakdown:
| Hex | Field | Value |
|---|---|---|
e3 |
LI=3, VN=4, Mode=3 | Header byte 1 |
00 |
Stratum | 0 |
03 |
Poll | 3 |
fa |
Precision | -6 (signed) |
00010000 |
Root Delay | 0x0001, 0x0000 |
00010000 |
Root Dispersion | 0x0001, 0x0000 |
00000000 |
Reference ID | 0 |
0000000000000000 |
Reference Timestamp | 0 |
0000000000000000 |
Origin Timestamp | 0 |
0000000000000000 |
Receive Timestamp | 0 |
ec17ee223f54e6a6 |
Transmit Timestamp | non-zero |
Expected: Packet accepted
Change the first byte so the version number is out of range (1-4):
# First byte 0x03: LI=0, VN=0, Mode=3 -- VN=0 is invalid (must be 1-4)
echo -n "030003fa000100000001000000000000000000000000000000000000000000000000000000000000ec17ee223f54e6a6" \
| xxd -r -p | ./ntp_parserExpected: Packet rejected (version 0 is outside the valid range 1-4)
Add extra bytes after a valid 48-byte packet:
echo -n "e30003fa000100000001000000000000000000000000000000000000000000000000000000000000ec17ee223f54e6a6DEADBEEF" \
| xxd -r -p | ./ntp_parserExpected: Packet rejected - the h_end_p() combinator detects unconsumed bytes.
Send fewer than 48 bytes:
echo -n "e30003fa00010000" | xxd -r -p | ./ntp_parserExpected: Packet rejected - not enough data for the mandatory fields.
To test with real network traffic, follow the steps in packet/steps.md:
sudo tcpdump -i enp2s1 -c 1 port 123 -s 0 -w ntp_packet.pcapReplace
enp2s1with your network interface (useip linkto find it). Port 123 is the standard NTP port.
tshark -r ntp_packet.pcap -T fields -e udp.payload > ntp_stream.hexxxd -r -p ntp_stream.hex > ntp_stream.bin./ntp_parser ntp_stream.bin| Output | Meaning |
|---|---|
Packet accepted |
The input matched the NTP grammar (exit code 0) |
Packet rejected |
The input did not match (exit code -1) |
You can use the exit code in scripts:
./ntp_parser packet/ntp_stream.bin && echo "Valid NTP" || echo "Not valid NTP"-
Check byte count: An NTP packet must be at least 48 bytes. You need at least 96 hex characters (2 per byte).
-
Check the first byte: Decode it manually to verify LI, VN, and Mode are in range:
Byte: 0xE3 = 11100011 binary LI = 11 (binary) = 3 (0-3) VN = 100 (binary) = 4 (1-4) Mode = 011 (binary) = 3 (0-7) -
Use
xxdto inspect binary files:xxd packet/ntp_stream.bin | head -
Use
h_pprintfor debugging: You can temporarily addh_pprint(stdout, result->ast, 0, 4);after a successful parse to dump the entire parse tree. This is useful for verifying that fields were split correctly.
Back to: NTP Overview · Examples Index
Previous: Hex Input Preprocessing
Learn Hammer
Protocol Examples
NTP
- NTP Overview
- Parsing the Header
- Parsing Data Fields
- Extension Fields and MAC
- Assembling the Parser
- Hex Input Preprocessing
- Running and Testing
DNS
TFTP
- TFTP Overview
- RRQ/WRQ Packets
- DATA Packets
- ACK Packets
- ERROR Packets
- Assembling the Parser
- Running and Testing
References
- Hammer Quick Reference
- Parsing Backends
- Unit Testing
- Using RTEMS
- Extending Hammer
- Adding a New Example
- Adding a New Binding
Further Reading