1
0
mirror of https://github.com/bgp/stayrtr.git synced 2024-05-06 15:54:54 +00:00

Add PDU encode/decode support for ASPA

This commit is contained in:
Ben Cartwright-Cox
2023-02-22 15:17:26 +00:00
parent 26be18ae2e
commit 3b73956a9c
2 changed files with 105 additions and 0 deletions

View File

@ -126,3 +126,30 @@ func TestRouterKeyEncodeDecode(t *testing.T) {
t.FailNow()
}
}
func TestASPAEncodeDecode(t *testing.T) {
p := &PDUASPA{
Version: 1,
Flags: 1,
AFIFlags: 1,
ProviderASCount: 2,
CustomerASNumber: 64497,
ProviderASNumbers: []uint32{64498, 64499},
}
buf := bytes.NewBuffer(nil)
p.Write(buf)
outputPdu, err := Decode(buf)
if err != nil {
t.FailNow()
}
orig := fmt.Sprintf("%#v", p)
decode := fmt.Sprintf("%#v", outputPdu)
if orig != decode {
t.Fatalf("%s\n is not\n%s", orig, decode)
t.FailNow()
}
}

View File

@ -23,6 +23,7 @@ const (
PROTOCOL_VERSION_0 = 0
PROTOCOL_VERSION_1 = 1
PROTOCOL_VERSION_2 = 2
PDU_ID_SERIAL_NOTIFY = 0
PDU_ID_SERIAL_QUERY = 1
@ -34,6 +35,7 @@ const (
PDU_ID_CACHE_RESET = 8
PDU_ID_ROUTER_KEY = 9
PDU_ID_ERROR_REPORT = 10
PDU_ID_ASPA = 11
FLAG_ADDED = 1
FLAG_REMOVED = 0
@ -84,6 +86,8 @@ func TypeToString(t uint8) string {
return "Router Key"
case PDU_ID_ERROR_REPORT:
return "Error Report"
case PDU_ID_ASPA:
return "ASPA PDU"
default:
return fmt.Sprintf("Unknown type %d", t)
}
@ -509,6 +513,51 @@ func (pdu *PDUErrorReport) Write(wr io.Writer) {
}
}
type PDUASPA struct {
Version uint8
Flags uint8
AFIFlags uint8
ProviderASCount uint16
CustomerASNumber uint32
ProviderASNumbers []uint32
}
func (pdu *PDUASPA) String() string {
return fmt.Sprintf("PDU ASPA v%d TODO", pdu.Version) // TODO
}
func (pdu *PDUASPA) Bytes() []byte {
b := bytes.NewBuffer([]byte{})
pdu.Write(b)
return b.Bytes()
}
func (pdu *PDUASPA) SetVersion(version uint8) {
pdu.Version = version
}
func (pdu *PDUASPA) GetVersion() uint8 {
return pdu.Version
}
func (pdu *PDUASPA) GetType() uint8 {
return PDU_ID_ASPA
}
func (pdu *PDUASPA) Write(wr io.Writer) {
binary.Write(wr, binary.BigEndian, uint8(pdu.Version))
binary.Write(wr, binary.BigEndian, uint8(PDU_ID_ASPA))
binary.Write(wr, binary.BigEndian, uint16(0))
binary.Write(wr, binary.BigEndian, uint32(16+(len(pdu.ProviderASNumbers)*4)))
binary.Write(wr, binary.BigEndian, uint8(pdu.Flags))
binary.Write(wr, binary.BigEndian, uint8(pdu.AFIFlags))
binary.Write(wr, binary.BigEndian, uint16(pdu.ProviderASCount))
binary.Write(wr, binary.BigEndian, uint32(pdu.CustomerASNumber))
for _, pasn := range pdu.ProviderASNumbers {
binary.Write(wr, binary.BigEndian, uint32(pasn))
}
}
func DecodeBytes(b []byte) (PDU, error) {
buf := bytes.NewBuffer(b)
return Decode(buf)
@ -694,6 +743,35 @@ func Decode(rdr io.Reader) (PDU, error) {
PDUCopy: errPdu,
ErrorMsg: errMsg,
}, nil
case PDU_ID_ASPA:
if len(toread) < 8 {
return nil, fmt.Errorf("wrong length for ASPA PDU: %d < 16", len(toread))
}
aspaFlag := uint8(toread[0])
aspaAFIFlag := uint8(toread[1])
PASCount := binary.BigEndian.Uint16(toread[2:4])
CASN := binary.BigEndian.Uint32(toread[4:8])
PASNs := make([]uint32, 0)
rbuf := bytes.NewReader(toread[8:])
for i := 0; i < int(PASCount); i++ {
var asn uint32
err := binary.Read(rbuf, binary.BigEndian, &asn)
if err != nil {
return nil, err
}
PASNs = append(PASNs, asn)
}
return &PDUASPA{
Version: pver,
Flags: aspaFlag,
AFIFlags: aspaAFIFlag,
ProviderASCount: PASCount,
CustomerASNumber: CASN,
ProviderASNumbers: PASNs,
}, nil
default:
return nil, errors.New("could not decode packet")
}