Skip to content

TFTP Overview

Elbasiouny, Mahmoud edited this page May 29, 2026 · 8 revisions

This example builds a complete parser for TFTP packets (RFC 1350) using Hammer. By the end, you'll have a working validator that accepts or rejects raw TFTP packets based on grammar correctness and protocol constraints.

TFTP is a simpler protocol than NTP or DNS, making it a great starting point for learning Hammer's core combinators.

Prerequisites: Make sure you've completed Getting Started and have either built Hammer in the checkout with scons examples or installed Hammer system-wide.


The TFTP Protocol

TFTP (Trivial File Transfer Protocol) is a simple file transfer protocol built on top of UDP. Unlike FTP, it has no authentication, no directory listing, and no connection negotiation beyond the initial request.

A link to the full RFC can be found here.

TFTP defines five packet types, each identified by a 2-byte opcode:

Opcode Packet Type Description
1 RRQ Read Request
2 WRQ Write Request
3 DATA Data
4 ACK Acknowledgement
5 ERROR Error

TFTP Packet Formats

RRQ/WRQ:
 2 bytes     string    1 byte    string   1 byte
+---------+-----------+------+-----------+------+
| Opcode  | Filename  |  0   |   Mode    |  0   |
+---------+-----------+------+-----------+------+

DATA:
 2 bytes    2 bytes      n bytes
+---------+---------+--------------+
| Opcode  | Block # |    Data      |
+---------+---------+--------------+

ACK:
 2 bytes    2 bytes
+---------+---------+
| Opcode  | Block # |
+---------+---------+

ERROR:
 2 bytes    2 bytes      string    1 byte
+---------+---------+-----------+------+
| Opcode  | ErrCode |  ErrMsg   |  0   |
+---------+---------+-----------+------+

Why TFTP Is a Good Hammer Example

TFTP exercises several Hammer features:

  • Value constraints - Opcodes must be in specific ranges (h_int_range)
  • String matching - Mode field must be one of "netascii", "octet", or "mail" (h_token)
  • Character-level parsing - Filenames use printable ASCII characters (h_ch_range)
  • Variable-length data - Data payloads use h_many with h_end_p
  • Null-terminated fields - Filenames and strings end with 0x00
  • Alternatives - The top-level parser tries each packet type (h_choice)

Project Structure

examples/tftp/
├── main.c         # Entry point: defines test packets and runs the parser
├── tftp.c         # TFTP protocol grammar defined with Hammer
└── Makefile       # Build system
File Role
main.c Entry point. Defines test packets, calls the parser, prints results.
tftp.c Defines the TFTP protocol grammar using Hammer combinators.

Building

From the Hammer repository root, build the checkout-local library first:

scons examples

Then build the TFTP example:

cd examples/tftp
make

This produces the tftp executable. The Makefile first looks for a checkout-local Hammer library at ../../build/opt/src. If that library is not present, it falls back to pkg-config libhammer.

Quick Test

Run the executable:

./tftp

Expected output shows each test case with a pass/fail result.


Walkthrough Pages

Follow these pages in order for the full tutorial:

# Page Hammer Concepts
1 RRQ/WRQ Packets h_int_range, h_ch_range, h_token, h_many1, h_sequence
2 DATA Packets h_int_range, h_many, h_end_p
3 ACK Packets h_int_range, h_sequence
4 ERROR Packets h_int_range, h_ch_range, h_many1
5 Assembling the Parser h_choice, h_parse
6 Running and Testing Testing with valid and invalid packets

Next: RRQ/WRQ Packets

Back to: Examples Index · Hammer Fundamentals

Clone this wiki locally