abbel/tlv/tlv.go

75 lines
1.0 KiB
Go

//go:generate stringer -type=TLV
package tlv
import "fmt"
type TLV uint8
const (
Pad1 TLV = iota
PadN
AckReq
Ack
Hello
IHU
RouterID
NextHop
Update
RouteRequest
RouteUpdate
TSPC
HMAC
)
type Scanner struct {
buf []byte
err error
t TLV
l uint8
}
func NewTLVScanner(buf []byte) *Scanner {
return &Scanner{
buf: buf,
}
}
func (ts *Scanner) Scan() bool {
if ts.err != nil {
return false
}
if len(ts.buf) <= int(ts.l) {
return false
}
// move beginning of the buffer to the next TLV
ts.buf = ts.buf[ts.l:]
ts.t, ts.l = TLV(ts.buf[0]), 0
switch ts.t {
case Pad1:
ts.buf = ts.buf[1:]
default:
ts.l = ts.buf[1]
if 2+int(ts.l) > len(ts.buf) {
ts.err = fmt.Errorf("Invalid length: type %d, length %d, size %d", ts.t, ts.l, len(ts.buf))
return false
}
// move beginning of the buffer behind the header
ts.buf = ts.buf[2:]
}
return true
}
func (ts *Scanner) Err() error {
return ts.err
}
func (ts *Scanner) TLV() (TLV, []byte) {
if ts.err != nil {
return 0, nil
}
return ts.t, ts.buf[:ts.l]
}