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 }