abbel/tlv/update.go

65 lines
1.2 KiB
Go

package tlv
import (
"bytes"
"encoding/binary"
"net"
)
type PacketUpdateHeader struct {
AE uint8
Flags uint8
Plen uint8
Omitted uint8
Interval uint16
Seqno uint16
Metric uint16
}
type PacketUpdate struct {
PacketUpdateHeader
Prefix net.IPNet
}
type PacketDecoder struct {
routerID [8]byte
v4 [4]byte
v6 [16]byte
}
func (s *PacketDecoder) UpdateFromBytes(b []byte) (PacketUpdate, error) {
var u PacketUpdate
r := bytes.NewReader(b[:10])
err := binary.Read(r, binary.BigEndian, &u.PacketUpdateHeader)
b = b[10:]
psize := (u.Plen+7)/8 - u.Omitted
switch u.AE {
case 0:
case 1:
u.Prefix.Mask = net.CIDRMask(int(u.Plen), 4*8)
u.Prefix.IP = append([]byte{}, s.v4[:]...)
copy(u.Prefix.IP[u.Omitted:], b[:psize])
if u.Flags&0x80 > 0 {
copy(s.v4[:], u.Prefix.IP)
}
case 2:
u.Prefix.Mask = net.CIDRMask(int(u.Plen), 16*8)
u.Prefix.IP = append([]byte{}, s.v6[:]...)
copy(u.Prefix.IP[u.Omitted:], b[:psize])
if u.Flags&0x80 > 0 {
copy(s.v6[:], u.Prefix.IP)
}
case 3:
u.Prefix.Mask = net.CIDRMask(8, 16*8)
u.Prefix.IP = make([]byte, 16)
u.Prefix.IP[0] = 0xfe
u.Prefix.IP[1] = 0x80
copy(u.Prefix.IP[8:], b[:8])
}
return u, err
}