//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] }