75 lines
1.0 KiB
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]
|
|
}
|