-
Notifications
You must be signed in to change notification settings - Fork 1
TFTP readWritePacket
Read Requests (RRQ, opcode 1) and Write Requests (WRQ, opcode 2) share the same packet structure. They are the first message a client sends to initiate a file transfer.
Source file:
tftp.c
Hammer concepts:h_int_range·h_ch_range·h_token·h_many1·h_sequence
2 bytes string 1 byte string 1 byte
+---------+-----------+------+-----------+------+
| Opcode | Filename | 0 | Mode | 0 |
+---------+-----------+------+-----------+------+
According to the RFC, a read or write request consists of:
- Opcode - 2 bytes, value 1 (RRQ) or 2 (WRQ)
-
Filename - Variable-length string in netascii, terminated by a zero byte (
\x00) -
Mode - One of
"netascii","octet", or"mail", terminated by a zero byte (\x00)
All three sections must be valid for the packet to pass.
The opcode must be either 1 or 2:
H_RULE(opc, h_int_range(h_uint16(), 1, 2));This reads 16 bits and rejects any value outside the range [1, 2].
Both the filename and mode are terminated by a zero byte:
H_RULE(zbyt, h_int_range(h_uint8(), 0, 0));This reads 8 bits and only accepts a value of 0.
A TFTP filename is a sequence of printable netascii characters. We define parsers for each valid character class:
H_RULE(lcAlph, h_ch_range('a', 'z'));
H_RULE(ucAlph, h_ch_range('A', 'Z'));
H_RULE(numbers, h_ch_range('0', '9'));
H_RULE(spclChars, h_choice(h_ch('.'), h_ch('_'), h_ch('/'),
h_ch('-'), h_ch(' '), NULL));Then combine them into the filename parser using h_many1 (one or more characters) followed by the zero byte terminator:
H_RULE(filename, h_sequence(h_many1(h_choice(lcAlph, ucAlph,
numbers, spclChars, NULL)), zbyt, NULL));h_many1 requires at least one character, so empty filenames are rejected.
The mode field must be exactly one of three strings. h_token matches a specific byte sequence:
H_RULE(netascii, h_token((const uint8_t *)"netascii", 8));
H_RULE(octet, h_token((const uint8_t *)"octet", 5));
H_RULE(mail, h_token((const uint8_t *)"mail", 4));
H_RULE(mode, h_sequence(h_choice(netascii, octet, mail, NULL),
zbyt, NULL));h_token(string, length) succeeds only if the next length bytes match string exactly. The mode is followed by a zero byte terminator.
H_RULE(rrqwrq, h_sequence(opc, filename, mode, NULL));When rrqwrq runs, it parses the opcode, filename (with terminator), and mode (with terminator) in order. If any part fails, the entire parse fails.
| Concept | Hammer Function | Why It Matters in TFTP |
|---|---|---|
| Constrain values | h_int_range |
Opcode must be 1 or 2 |
| Match characters | h_ch_range |
Filename characters must be printable ASCII |
| Match exact strings | h_token |
Mode must be "netascii", "octet", or "mail"
|
| One or more | h_many1 |
Filenames must have at least one character |
| Parse in order | h_sequence |
Fields appear consecutively |
Next: DATA Packets
Previous: TFTP Overview
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