Code generator for binary parsing. Golang port of the original implementation for the Tor project.
Writing parsers for binary formats is error-prone and tedious. Critical security vulnerabilities are frequently found in parser code, especially in low-level languages such as C. Trunnel is a domain-specific language for describing binary formats and a parser generator for those formats.
Trunnel was initially designed and implemented by Nick Mathewson for the Tor Project. This Golang port is intended to support efforts to implement a Tor Relay in Go, with the goal of sharing trunnel files with the core Tor codebase.
Install trunnel with
go get -u github.com/mmcloughlin/trunnel/cmd/trunnel
As a very simple example, we can define a color struct in trunnel as follows.
struct color {
u8 r;
u8 g;
u8 b;
};Compile this with the trunnel tool as follows.
trunnel build -p color color.trunnel
The result will be a Golang package called color with a Color type and
methods to marshal to and from binary representation.
// Code generated by trunnel. DO NOT EDIT.
package color
import "errors"
type Color struct {
R uint8
G uint8
B uint8
}
func (c *Color) Parse(data []byte) ([]byte, error) {
cur := data
{
if len(cur) < 1 {
return nil, errors.New("data too short")
}
c.R = cur[0]
cur = cur[1:]
}
{
if len(cur) < 1 {
return nil, errors.New("data too short")
}
c.G = cur[0]
cur = cur[1:]
}
{
if len(cur) < 1 {
return nil, errors.New("data too short")
}
c.B = cur[0]
cur = cur[1:]
}
return cur, nil
}
func ParseColor(data []byte) (*Color, error) {
c := new(Color)
_, err := c.Parse(data)
if err != nil {
return nil, err
}
return c, nil
}Integer fields may have constraints.
struct date {
u16 year IN [ 1970..65535 ];
u8 month IN [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ];
u8 day IN [ 1,2,3..31 ];
};Please consult the trunnel manual for the full feature set.