65 lines
1.2 KiB
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
|
|
}
|