Newer
Older
"github.com/bio-routing/bio-rd/util/decode"
type NLRI struct {
PathIdentifier uint32
IP uint32
Pfxlen uint8
Next *NLRI
}
func decodeNLRIs(buf *bytes.Buffer, length uint16) (*NLRI, error) {
var ret *NLRI
var eol *NLRI
var nlri *NLRI
var err error
var consumed uint8
p := uint16(0)
for p < length {
nlri, consumed, err = decodeNLRI(buf)
if err != nil {
return nil, fmt.Errorf("Unable to decode NLRI: %v", err)
}
p += uint16(consumed)
if ret == nil {
ret = nlri
eol = nlri
continue
}
eol.Next = nlri
eol = nlri
}
return ret, nil
}
func decodeNLRI(buf *bytes.Buffer) (*NLRI, uint8, error) {
var addr [4]byte
nlri := &NLRI{}
err := decode.Decode(buf, []interface{}{&nlri.Pfxlen})
if err != nil {
return nil, 0, err
}
toCopy := uint8(math.Ceil(float64(nlri.Pfxlen) / float64(OctetLen)))
for i := uint8(0); i < net.IPv4len%OctetLen; i++ {
if i < toCopy {
err := decode.Decode(buf, []interface{}{&addr[i]})
if err != nil {
return nil, 0, err
}
} else {
addr[i] = 0
}
}
func (n *NLRI) serialize(buf *bytes.Buffer) uint8 {
nBytes := BytesInAddr(n.Pfxlen)
buf.WriteByte(n.Pfxlen)
buf.Write(addr[:nBytes])
return nBytes + 1
}
func (n *NLRI) serializeAddPath(buf *bytes.Buffer) uint8 {
a := convert.Uint32Byte(n.IP)
addr := [4]byte{a[0], a[1], a[2], a[3]}
nBytes := BytesInAddr(n.Pfxlen)
buf.Write(convert.Uint32Byte(n.PathIdentifier))
buf.WriteByte(n.Pfxlen)
buf.Write(addr[:nBytes])
// BytesInAddr gets the amount of bytes needed to encode an NLRI of prefix length pfxlen
func BytesInAddr(pfxlen uint8) uint8 {
return uint8(math.Ceil(float64(pfxlen) / 8))
}