trivial v0.1.0 Trivial View Source
A Read-only TFTP Service for Elixir
Motivation
Erlang's :tftp
module is quite complex in order to service a broad featureset
and has some critical bugs which prevent it from being used in a
PXE Boot context.
This library addresses some of these limitations and gives you a way to instrument TFTP read requests in a clear and concise fashion. An emphasis has been made on code documentation and commenting, code structuring good practices, with direct references to relevant RFC content where appropriate.
Trivial
is designed to be a companion to ExDhcp
to make it easy to build observable and reproducible PXE-Booting solutions.
Security notes
TFTP is a fundamentally insecure protocol. Use of this library for purposes other than its intent (PXE booting) is highly discouraged. Even when using it for its intended purpose, please be very careful and only use this in networks where you are confident you have visibility and control over OSI layer 2.
Quick Start (Linux)
Write your
MyApplication.Tftp
module with the appropriateTrivial.Server
behaviour callbacks.defmodule MyApplication.Tftp do @behaviour Trivial.Server @impl true def init(request, data) do ...
Set up a trivial server in your application supervisory tree:
defmodule MyApplication ... def start(_type, _args) do children = [ {Trivial, {MyApplication.Tftp, nil, port: 69}} ] ...
as superuser, give your beam.smp a the capability to get low ports:
setcap 'cap_net_bind_service,cap_net_raw=+ep' /usr/lib/erlang/erts-10.6.1/bin/beam.smp
NB: the path to your beam.smp may be different
Note that you may want to use a different strategy to provide access to the
server, for example, forwarding port 69 to port 6969 via iptables
.
Supervision Tree
Trivial generates the following supervision tree:
Supervisor
:one_for_all
- Daemon
DynamicSupervisor
:one_for_one
- < Servers >
By default, the top supervisor is named Trivial
Without supervision
Link to this section Summary
Functions
Returns a specification to start this module under a supervisor.
retrieves the PID of the Trivial.Daemon
process being supervised
by the target supervisor.
retrieves the UDP port of the daemon process.
retrieves the PID of the DynamicSupervisor
process being
supervised by the target supervisor.
starts a supervised TFTP service.
Link to this section Functions
child_spec(init_arg) View Source
Returns a specification to start this module under a supervisor.
See Supervisor
.
daemon(supervisor \\ __MODULE__)
View Source
daemon(Supervisor.supervisor()) :: pid()
daemon(Supervisor.supervisor()) :: pid()
retrieves the PID of the Trivial.Daemon
process being supervised
by the target supervisor.
port(supervisor \\ __MODULE__)
View Source
port(Supervisor.supervisor()) :: pos_integer()
port(Supervisor.supervisor()) :: pos_integer()
retrieves the UDP port of the daemon process.
server_supervisor(supervisor \\ __MODULE__)
View Source
server_supervisor(Supervisor.supervisor()) :: pid()
server_supervisor(Supervisor.supervisor()) :: pid()
retrieves the PID of the DynamicSupervisor
process being
supervised by the target supervisor.
start_link(srv_module, srv_init, opts)
View Source
start_link(server_module :: module(), server_init :: term(), opts :: keyword()) ::
Supervisor.on_start()
start_link(server_module :: module(), server_init :: term(), opts :: keyword()) :: Supervisor.on_start()
starts a supervised TFTP service.
srv_module
should be a module that implements the Trivial.Server
behaviour; srv_init
is the initial data given to the child processes.
Options
trivial_name
: name given to the trivial server. Defaults toTrivial
port
: the UDP port that the Daemon will bind to. Defaults to 6969