Cross-platform TFTP client and server. Single binary, CLI and GUI, full RFC compliance.
Download a file:
chapulin get 192.168.1.1 firmware.bin
Upload a file:
chapulin put 192.168.1.1 config.txt --output=router-config.txt
Serve a directory:
chapulin serve ./tftp-root --port=69 --write=all
URI syntax works too:
chapulin get tftp://192.168.1.1:69/firmware.bin
Prebuilt binaries for Linux, macOS, and Windows are available on the releases page.
Requires Nim 2.0+.
nimble install
nimble build
With GUI support:
nim c --threads:on -d:withGui -d:release -o:chapulin src/chapulin.nim
docker build -t chapulin .
docker run --rm chapulin nimble test
chapulin get <host> <filename> [options]
chapulin get tftp://<host>[:<port>]/<filename> [options]
chapulin put <host> <filename> [options]
chapulin put tftp://<host>[:<port>]/<filename> [options]
chapulin serve <rootdir> [options]
chapulin gui
| Flag | Default | Description |
|---|---|---|
--port=N |
69 | Server port |
--blocksize=N |
512 | Block size in bytes |
--windowsize=N |
1 | Window size in blocks (RFC 7440) |
--timeout=N |
5 | Timeout in seconds |
--retries=N |
3 | Max retransmit attempts |
--output=PATH |
filename | Local file path |
--mode=MODE |
octet | Transfer mode: octet or netascii |
| Flag | Default | Description |
|---|---|---|
--port=N |
69 | Listen port |
--write=POLICY |
deny | Write policy: deny, create, overwrite, all |
--max-clients=N |
10 | Max concurrent transfers |
--blocksize=N |
65464 | Max negotiated blocksize |
--timeout=N |
5 | Timeout in seconds |
--port-range=S:E |
OS-assigned | Transfer port range for firewalls |
--pxe-compat |
off | Only negotiate tsize (for buggy PXE ROMs) |
--bind=ADDR |
0.0.0.0 | Bind to specific IP address |
--dir-list=FILE |
disabled | Serve directory listing as this filename |
--checksum=MODE |
disabled | Generate checksum sidecar after read (md5) |
| Flag | Description |
|---|---|
--notify |
Audible bell on transfer completion |
--verbose |
Debug-level output |
--quiet |
Errors only |
--help |
Show help |
--version |
Show version |
Launch with chapulin gui (requires build with -d:withGui). Client and server in one window with tabbed panels.
| RFC | Description | Status |
|---|---|---|
| RFC 1350 | TFTP Protocol (base) | Complete |
| RFC 2347 | Option Extension (OACK) | Complete |
| RFC 2348 | Blocksize Option | Complete |
| RFC 2349 | Timeout & Transfer Size | Complete |
| RFC 7440 | Windowsize Option | Complete |
| RFC 1123 s4.2 | Adaptive timeout, broadcast rejection | Complete |
| RFC 3617 | TFTP URI Scheme | Complete |
protocol.nim pure packet codec
|
transfer.nim async sendBlocks/recvBlocks primitives
|
options.nim option negotiation (client + server)
| \
engine.nim server.nim client and server as equal siblings
| |
| security.nim + server_config.nim
|
transport.nim async UDP sockets + server listener
|
api.nim public API
|
chapulin.nim combined CLI (get/put/serve/gui)
Single-threaded async I/O (std/asyncdispatch). Concurrent server transfers via asyncCheck. 228 tests. Interop tested against tftpd-hpa and atftp.
See design-philosophy.md for architectural decisions and rationale.
Apache 2.0