tftp

package
v0.773.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 28, 2026 License: AGPL-3.0 Imports: 5 Imported by: 0

Documentation

Overview

Package tftp decodes TFTP (Trivial File Transfer Protocol) packets per RFC 1350, with the Option Extension family from RFC 2347 (envelope) + RFC 2348 (blksize) + RFC 2349 (timeout + tsize) + RFC 7440 (windowsize). TFTP is the canonical minimal file-transfer protocol; despite its 1981 vintage it remains the dominant transport for:

  • **PXE / network boot** — every PXE-booting machine fetches its boot loader (`pxelinux.0`, `wdsnbp.com`, `ipxe.efi`) and kernel + initrd over TFTP.

  • **IoT firmware updates** — most embedded devices (routers, switches, IP cameras, smart plugs, factory equipment) fetch firmware via TFTP because it fits in 2 KB of ROM.

  • **Network device config push** — every Cisco / Juniper / Arista shop uses TFTP for `copy running-config tftp:` and `copy tftp: flash:` workflows.

Wrap-vs-native judgement

Native. RFC 1350 + 2347 are fully public; TFTP packets
have a tight 2-byte opcode + per-opcode body — no
crypto, no compression, no fancy framing. Operators
paste TFTP bytes (UDP destination port 69 server-side
or the ephemeral port the server picked for an active
transfer) from a `tcpdump -X udp port 69` line or a
Wireshark Follow-UDP-Stream view and get the documented
opcode + body breakdown.

What this package covers

  • **2-byte Opcode** (RFC 1350 §5) with **6-entry name table**: 1 RRQ (Read Request), 2 WRQ (Write Request), 3 DATA, 4 ACK, 5 ERROR, 6 OACK (Option Acknowledgment; RFC 2347).

  • **RRQ / WRQ body** (Types 1 + 2):

  • **Filename** (null-terminated UTF-8).

  • **Mode** (null-terminated UTF-8) — RFC 1350 defines "netascii", "octet" (the binary mode most operators use), and the deprecated "mail" mode.

  • **Options** (RFC 2347) — zero or more (name, value) pairs, each null-terminated. **4-entry option name table**: blksize (RFC 2348 — block-size override, default 512), timeout (RFC 2349 — retransmit timeout in seconds), tsize (RFC 2349 — transfer size in bytes; client sends 0 to request the server's value), windowsize (RFC 7440 — number of DATA blocks the sender can transmit before expecting an ACK).

  • **DATA body** (Type 3):

  • **Block Number** (uint16 BE; starts at 1, wraps to 0 after 65535 — the rollover is silently the reason for the long-standing 32 MB classic TFTP transfer cap, lifted by the windowsize + blksize options).

  • **Payload** (variable, up to the negotiated blksize — default 512 bytes; a short payload signals the last block).

  • **ACK body** (Type 4):

  • **Block Number** being acknowledged.

  • **ERROR body** (Type 5):

  • **Error Code** (uint16 BE) with **9-entry name table**: 0 Not defined / 1 File not found / 2 Access violation / 3 Disk full or allocation exceeded / 4 Illegal TFTP operation / 5 Unknown transfer ID / 6 File already exists / 7 No such user / 8 Option negotiation failure (RFC 2347).

  • **Error Message** (null-terminated UTF-8).

  • **OACK body** (Type 6) — same option-list layout as the options portion of RRQ/WRQ; the server replies with the option values it has agreed to.

What this package does NOT cover (deliberately out of scope)

  • UDP framing — feed TFTP bytes after the UDP header strip. TFTP runs on UDP destination port 69 server- side or the ephemeral port the server picked for transfer-data continuation.

  • TFTP state-machine reasoning (block-number windowing, retransmit-after-timeout logic, lockstep ACK ordering) — higher-level analysis.

  • Reassembly of the file payload across DATA blocks — each DATA block is decoded standalone; concatenating them is collector-side work.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AckBody

type AckBody struct {
	BlockNumber int `json:"block_number"`
}

AckBody is the decoded body of ACK (Type 4) packets.

type DataBody

type DataBody struct {
	BlockNumber       int    `json:"block_number"`
	PayloadBytes      int    `json:"payload_bytes"`
	PayloadBytesShown int    `json:"payload_bytes_shown,omitempty"`
	PayloadHex        string `json:"payload_hex,omitempty"`
	PayloadText       string `json:"payload_text,omitempty"`
}

DataBody is the decoded body of DATA (Type 3) packets.

type DecodeOpts

type DecodeOpts struct {
	// MaxPayloadBytes caps the per-DATA hex preview. Zero
	// surfaces the entire payload (which can be up to the
	// negotiated blksize, often 64 KB).
	MaxPayloadBytes int
}

DecodeOpts tunes the walker for output size.

func DefaultDecodeOpts

func DefaultDecodeOpts() DecodeOpts

DefaultDecodeOpts returns a 256-byte payload preview cap.

type ErrorBody

type ErrorBody struct {
	ErrorCode    int    `json:"error_code"`
	ErrorName    string `json:"error_name"`
	ErrorMessage string `json:"error_message"`
}

ErrorBody is the decoded body of ERROR (Type 5) packets.

type OackBody

type OackBody struct {
	Options []Option `json:"options"`
}

OackBody is the decoded body of OACK (Type 6) packets.

type Option

type Option struct {
	Name      string `json:"name"`
	NameKnown string `json:"name_known,omitempty"`
	Value     string `json:"value"`
}

Option is one (name, value) option pair from a RRQ / WRQ / OACK body.

type RequestBody

type RequestBody struct {
	Filename string   `json:"filename"`
	Mode     string   `json:"mode"`
	Options  []Option `json:"options,omitempty"`
}

RequestBody is the decoded body of RRQ (Type 1) or WRQ (Type 2) packets.

type Result

type Result struct {
	Opcode     int    `json:"opcode"`
	OpcodeName string `json:"opcode_name"`

	// One of the following is populated per opcode.
	RRQ   *RequestBody `json:"rrq,omitempty"`
	WRQ   *RequestBody `json:"wrq,omitempty"`
	DATA  *DataBody    `json:"data,omitempty"`
	ACK   *AckBody     `json:"ack,omitempty"`
	ERROR *ErrorBody   `json:"error,omitempty"`
	OACK  *OackBody    `json:"oack,omitempty"`

	TotalBytes int      `json:"total_bytes"`
	Notes      []string `json:"notes,omitempty"`
}

Result is the top-level decoded view of a TFTP packet.

func Decode

func Decode(hexStr string, opts DecodeOpts) (*Result, error)

Decode parses a single TFTP packet from hex.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL