Overview
View SourceEtiquette is a library for creating packet specifications. The usage of packets is standard across most network communications, but it can have other uses and be a good way to efficiently store data and move it around.
Let's take a simple packet specification. The UDP header format:
| Byte 0 | Byte 1 | Byte 2 | Byte 3 | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Source Port | Destination Port | ||||||||||||||||||||||||||||||
| Length | Checksum | ||||||||||||||||||||||||||||||
| Data | |||||||||||||||||||||||||||||||
From this specification we can gather that the packet has five fields, the first
with a fixed length of two bytes and the last with an indefinite length. Using
Etiquette.Spec, we can create the specification as
follows:
defmodule UDPSpec do
use Etiquette.Spec
packet "UDP Header Format", id: :udp_header do
field "Source Port", 16
field "Destination Port", 16
field "Length", 16, id: :length
field "Checksum", 16
field "Data", (..), length_by: :length
end
endUsing the information provided, Etiquette.Spec will
generate the following:
UDPSpec.is_udp_header?/1: Will returntrueif the binary data conforms to the specification.UDPSpec.parse_udp_header/1: Will parse the binary data into a map with the fields names as keys and the values as the parsed data according to the spec. So, the result following the example above would be something like:
The parser function returns as part of the result the remaining data after extracting the fields. Since the size depends on the data sent, it is possible that some data falls outside the determined length of the last field and which may still be useful.iex> {packet_data, remaining_data} = UDPSpec.parse_udp_header(some_data) %{ source_port: ..., destination_port: ..., length: ..., checksum: ..., data: ..., } = packet_dataUDPSpec.build_udp_header/5: Will create the binary from the given arguments. Depending on the spec, the function will have a different number of arguments, one for each field that is not of a fixed value.
Above we used a very simple example. To define more complex specifications,
there are more arguments and options for packet
and field. Continue reading the guides to learn
how to use the multiple available options to your advantage.