summaryrefslogtreecommitdiffhomepage
path: root/packet/bgp
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2016-04-12 09:12:30 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2016-04-12 09:12:30 +0900
commit8daa5116576b3e3582e6c8e05ae1b64f56197ec6 (patch)
tree6fc1a336ba08c51cfac99da9127fa3117b517037 /packet/bgp
parent1151436f137e32ac5d5ce9592cada872f47f312b (diff)
packet: create rtr package
move rtr stuff from bgp to rtr package. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Diffstat (limited to 'packet/bgp')
-rw-r--r--packet/bgp/rtr.go392
-rw-r--r--packet/bgp/rtr_test.go122
2 files changed, 0 insertions, 514 deletions
diff --git a/packet/bgp/rtr.go b/packet/bgp/rtr.go
deleted file mode 100644
index 30657e15..00000000
--- a/packet/bgp/rtr.go
+++ /dev/null
@@ -1,392 +0,0 @@
-// Copyright (C) 2015 Nippon Telegraph and Telephone Corporation.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-// implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package bgp
-
-import (
- "encoding/binary"
- "fmt"
- "net"
-)
-
-const (
- RPKI_DEFAULT_PORT = 323
-)
-
-const (
- RTR_SERIAL_NOTIFY = iota
- RTR_SERIAL_QUERY
- RTR_RESET_QUERY
- RTR_CACHE_RESPONSE
- RTR_IPV4_PREFIX
- _
- RTR_IPV6_PREFIX
- RTR_END_OF_DATA
- RTR_CACHE_RESET
- _
- RTR_ERROR_REPORT
-)
-
-const (
- RTR_SERIAL_NOTIFY_LEN = 12
- RTR_SERIAL_QUERY_LEN = 12
- RTR_RESET_QUERY_LEN = 8
- RTR_CACHE_RESPONSE_LEN = 8
- RTR_IPV4_PREFIX_LEN = 20
- RTR_IPV6_PREFIX_LEN = 32
- RTR_END_OF_DATA_LEN = 12
- RTR_CACHE_RESET_LEN = 8
- RTR_MIN_LEN = 8
- RTR_ERROR_REPORT_ERR_PDU_LEN = 4
- RTR_ERROR_REPORT_ERR_TEXT_LEN = 4
-)
-
-const (
- WITHDRAWAL uint8 = iota
- ANNOUNCEMENT
-)
-
-const (
- CORRUPT_DATA uint16 = iota
- INTERNAL_ERROR
- NO_DATA_AVAILABLE
- INVALID_REQUEST
- UNSUPPORTED_PROTOCOL_VERSION
- UNSUPPORTED_PDU_TYPE
- WITHDRAWAL_OF_UNKNOWN_RECORD
- DUPLICATE_ANNOUNCEMENT_RECORD
-)
-
-type RTRMessage interface {
- DecodeFromBytes([]byte) error
- Serialize() ([]byte, error)
-}
-
-type RTRCommon struct {
- Version uint8
- Type uint8
- SessionID uint16
- Len uint32
- SerialNumber uint32
-}
-
-func (m *RTRCommon) DecodeFromBytes(data []byte) error {
- m.Version = data[0]
- m.Type = data[1]
- m.SessionID = binary.BigEndian.Uint16(data[2:4])
- m.Len = binary.BigEndian.Uint32(data[4:8])
- m.SerialNumber = binary.BigEndian.Uint32(data[8:12])
- return nil
-}
-
-func (m *RTRCommon) Serialize() ([]byte, error) {
- data := make([]byte, m.Len)
- data[0] = m.Version
- data[1] = m.Type
- binary.BigEndian.PutUint16(data[2:4], m.SessionID)
- binary.BigEndian.PutUint32(data[4:8], m.Len)
- binary.BigEndian.PutUint32(data[8:12], m.SerialNumber)
- return data, nil
-}
-
-type RTRSerialNotify struct {
- RTRCommon
-}
-
-func NewRTRSerialNotify(id uint16, sn uint32) *RTRSerialNotify {
- return &RTRSerialNotify{
- RTRCommon{
- Type: RTR_SERIAL_NOTIFY,
- SessionID: id,
- Len: RTR_SERIAL_NOTIFY_LEN,
- SerialNumber: sn,
- },
- }
-}
-
-type RTRSerialQuery struct {
- RTRCommon
-}
-
-func NewRTRSerialQuery(id uint16, sn uint32) *RTRSerialQuery {
- return &RTRSerialQuery{
- RTRCommon{
- Type: RTR_SERIAL_QUERY,
- SessionID: id,
- Len: RTR_SERIAL_QUERY_LEN,
- SerialNumber: sn,
- },
- }
-}
-
-type RTRReset struct {
- Version uint8
- Type uint8
- Len uint32
-}
-
-func (m *RTRReset) DecodeFromBytes(data []byte) error {
- m.Version = data[0]
- m.Type = data[1]
- m.Len = binary.BigEndian.Uint32(data[4:8])
- return nil
-}
-
-func (m *RTRReset) Serialize() ([]byte, error) {
- data := make([]byte, m.Len)
- data[0] = m.Version
- data[1] = m.Type
- binary.BigEndian.PutUint32(data[4:8], m.Len)
- return data, nil
-}
-
-type RTRResetQuery struct {
- RTRReset
-}
-
-func NewRTRResetQuery() *RTRResetQuery {
- return &RTRResetQuery{
- RTRReset{
- Type: RTR_RESET_QUERY,
- Len: RTR_RESET_QUERY_LEN,
- },
- }
-}
-
-type RTRCacheResponse struct {
- Version uint8
- Type uint8
- SessionID uint16
- Len uint32
-}
-
-func (m *RTRCacheResponse) DecodeFromBytes(data []byte) error {
- m.Version = data[0]
- m.Type = data[1]
- m.SessionID = binary.BigEndian.Uint16(data[2:4])
- m.Len = binary.BigEndian.Uint32(data[4:8])
- return nil
-}
-
-func (m *RTRCacheResponse) Serialize() ([]byte, error) {
- data := make([]byte, m.Len)
- data[0] = m.Version
- data[1] = m.Type
- binary.BigEndian.PutUint16(data[2:4], m.SessionID)
- binary.BigEndian.PutUint32(data[4:8], m.Len)
- return data, nil
-}
-
-func NewRTRCacheResponse(id uint16) *RTRCacheResponse {
- return &RTRCacheResponse{
- Type: RTR_CACHE_RESPONSE,
- SessionID: id,
- Len: RTR_CACHE_RESPONSE_LEN,
- }
-}
-
-type RTRIPPrefix struct {
- Version uint8
- Type uint8
- Len uint32
- Flags uint8
- PrefixLen uint8
- MaxLen uint8
- Prefix net.IP
- AS uint32
-}
-
-func (m *RTRIPPrefix) DecodeFromBytes(data []byte) error {
- m.Version = data[0]
- m.Type = data[1]
- m.Len = binary.BigEndian.Uint32(data[4:8])
- m.Flags = data[8]
- m.PrefixLen = data[9]
- m.MaxLen = data[10]
- if m.Type == RTR_IPV4_PREFIX {
- m.Prefix = net.IP(data[12:16]).To4()
- m.AS = binary.BigEndian.Uint32(data[16:20])
- } else {
- m.Prefix = net.IP(data[12:28]).To16()
- m.AS = binary.BigEndian.Uint32(data[28:32])
- }
- return nil
-}
-
-func (m *RTRIPPrefix) Serialize() ([]byte, error) {
- data := make([]byte, m.Len)
- data[0] = m.Version
- data[1] = m.Type
- binary.BigEndian.PutUint32(data[4:8], m.Len)
- data[8] = m.Flags
- data[9] = m.PrefixLen
- data[10] = m.MaxLen
- if m.Type == RTR_IPV4_PREFIX {
- copy(data[12:16], m.Prefix.To4())
- binary.BigEndian.PutUint32(data[16:20], m.AS)
- } else {
- copy(data[12:28], m.Prefix.To16())
- binary.BigEndian.PutUint32(data[28:32], m.AS)
- }
- return data, nil
-}
-
-func NewRTRIPPrefix(prefix net.IP, prefixLen, maxLen uint8, as uint32, flags uint8) *RTRIPPrefix {
- var pduType uint8
- var pduLen uint32
- if prefix.To4() != nil && prefixLen <= 32 {
- pduType = RTR_IPV4_PREFIX
- pduLen = RTR_IPV4_PREFIX_LEN
- } else {
- pduType = RTR_IPV6_PREFIX
- pduLen = RTR_IPV6_PREFIX_LEN
- }
-
- return &RTRIPPrefix{
- Type: pduType,
- Len: pduLen,
- Flags: flags,
- PrefixLen: prefixLen,
- MaxLen: maxLen,
- Prefix: prefix,
- AS: as,
- }
-}
-
-type RTREndOfData struct {
- RTRCommon
-}
-
-func NewRTREndOfData(id uint16, sn uint32) *RTREndOfData {
- return &RTREndOfData{
- RTRCommon{
- Type: RTR_END_OF_DATA,
- SessionID: id,
- Len: RTR_END_OF_DATA_LEN,
- SerialNumber: sn,
- },
- }
-}
-
-type RTRCacheReset struct {
- RTRReset
-}
-
-func NewRTRCacheReset() *RTRCacheReset {
- return &RTRCacheReset{
- RTRReset{
- Type: RTR_CACHE_RESET,
- Len: RTR_CACHE_RESET_LEN,
- },
- }
-}
-
-type RTRErrorReport struct {
- Version uint8
- Type uint8
- ErrorCode uint16
- Len uint32
- PDULen uint32
- PDU []byte
- TextLen uint32
- Text []byte
-}
-
-func (m *RTRErrorReport) DecodeFromBytes(data []byte) error {
- m.Version = data[0]
- m.Type = data[1]
- m.ErrorCode = binary.BigEndian.Uint16(data[2:4])
- m.Len = binary.BigEndian.Uint32(data[4:8])
- m.PDULen = binary.BigEndian.Uint32(data[8:12])
- m.PDU = make([]byte, m.PDULen)
- copy(m.PDU, data[12:12+m.PDULen])
- m.TextLen = binary.BigEndian.Uint32(data[12+m.PDULen : 16+m.PDULen])
- m.Text = make([]byte, m.TextLen)
- copy(m.Text, data[16+m.PDULen:])
- return nil
-}
-
-func (m *RTRErrorReport) Serialize() ([]byte, error) {
- data := make([]byte, m.Len)
- data[0] = m.Version
- data[1] = m.Type
- binary.BigEndian.PutUint16(data[2:4], m.ErrorCode)
- binary.BigEndian.PutUint32(data[4:8], m.Len)
- binary.BigEndian.PutUint32(data[8:12], m.PDULen)
- copy(data[12:], m.PDU)
- binary.BigEndian.PutUint32(data[12+m.PDULen:16+m.PDULen], m.TextLen)
- copy(data[16+m.PDULen:], m.Text)
- return data, nil
-}
-
-func NewRTRErrorReport(errCode uint16, errPDU []byte, errMsg []byte) *RTRErrorReport {
- pdu := &RTRErrorReport{Type: RTR_ERROR_REPORT, ErrorCode: errCode}
- if errPDU != nil {
- if errPDU[1] == RTR_ERROR_REPORT {
- return nil
- }
- pdu.PDULen = uint32(len(errPDU))
- pdu.PDU = errPDU
- }
- if errMsg != nil {
- pdu.Text = errMsg
- pdu.TextLen = uint32(len(errMsg))
- }
- pdu.Len = uint32(RTR_MIN_LEN) + uint32(RTR_ERROR_REPORT_ERR_PDU_LEN) + pdu.PDULen + uint32(RTR_ERROR_REPORT_ERR_TEXT_LEN) + pdu.TextLen
- return pdu
-}
-
-func SplitRTR(data []byte, atEOF bool) (advance int, token []byte, err error) {
- if atEOF && len(data) == 0 || len(data) < RTR_MIN_LEN {
- return 0, nil, nil
- }
-
- totalLen := binary.BigEndian.Uint32(data[4:8])
- if totalLen < RTR_MIN_LEN {
- return 0, nil, fmt.Errorf("Invalid length: %d", totalLen)
- }
- if uint32(len(data)) < totalLen {
- return 0, nil, nil
- }
- return int(totalLen), data[0:totalLen], nil
-}
-
-func ParseRTR(data []byte) (RTRMessage, error) {
- var msg RTRMessage
- switch data[1] {
- case RTR_SERIAL_NOTIFY:
- msg = &RTRSerialNotify{}
- case RTR_SERIAL_QUERY:
- msg = &RTRSerialQuery{}
- case RTR_RESET_QUERY:
- msg = &RTRResetQuery{}
- case RTR_CACHE_RESPONSE:
- msg = &RTRCacheResponse{}
- case RTR_IPV4_PREFIX:
- msg = &RTRIPPrefix{}
- case RTR_IPV6_PREFIX:
- msg = &RTRIPPrefix{}
- case RTR_END_OF_DATA:
- msg = &RTREndOfData{}
- case RTR_CACHE_RESET:
- msg = &RTRCacheReset{}
- case RTR_ERROR_REPORT:
- msg = &RTRErrorReport{}
- default:
- return nil, fmt.Errorf("unknown RTR message type %d:", data[1])
- }
- err := msg.DecodeFromBytes(data)
- return msg, err
-}
diff --git a/packet/bgp/rtr_test.go b/packet/bgp/rtr_test.go
deleted file mode 100644
index 0f9b9527..00000000
--- a/packet/bgp/rtr_test.go
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright (C) 2015 Nippon Telegraph and Telephone Corporation.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-// implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package bgp
-
-import (
- "encoding/hex"
- "math/rand"
- "net"
- "reflect"
- "testing"
- "time"
-)
-
-func verifyRTRMessage(t *testing.T, m1 RTRMessage) {
- buf1, _ := m1.Serialize()
- m2, err := ParseRTR(buf1)
- if err != nil {
- t.Error(err)
- }
- buf2, _ := m2.Serialize()
-
- if reflect.DeepEqual(buf1, buf2) == true {
- t.Log("OK")
- } else {
- t.Errorf("Something wrong")
- t.Error(len(buf1), m1, hex.EncodeToString(buf1))
- t.Error(len(buf2), m2, hex.EncodeToString(buf2))
- }
-}
-
-func randUint32() uint32 {
- rand.Seed(time.Now().UnixNano())
- return rand.Uint32()
-}
-
-func Test_RTRSerialNotify(t *testing.T) {
- id := uint16(time.Now().Unix())
- sn := randUint32()
- verifyRTRMessage(t, NewRTRSerialNotify(id, sn))
-}
-
-func Test_RTRSerialQuery(t *testing.T) {
- id := uint16(time.Now().Unix())
- sn := randUint32()
- verifyRTRMessage(t, NewRTRSerialQuery(id, sn))
-}
-
-func Test_RTRResetQuery(t *testing.T) {
- verifyRTRMessage(t, NewRTRResetQuery())
-}
-
-func Test_RTRCacheResponse(t *testing.T) {
- id := uint16(time.Now().Unix())
- verifyRTRMessage(t, NewRTRCacheResponse(id))
-}
-
-type rtrIPPrefixTestCase struct {
- pString string
- pLen uint8
- mLen uint8
- asn uint32
- flags uint8
-}
-
-var rtrIPPrefixTestCases = []rtrIPPrefixTestCase{
- {"192.168.0.0", 16, 32, 65001, ANNOUNCEMENT},
- {"192.168.0.0", 16, 32, 65001, WITHDRAWAL},
- {"2001:db8::", 32, 128, 65001, ANNOUNCEMENT},
- {"2001:db8::", 32, 128, 65001, WITHDRAWAL},
- {"::ffff:0.0.0.0", 96, 128, 65001, ANNOUNCEMENT},
- {"::ffff:0.0.0.0", 96, 128, 65001, WITHDRAWAL},
-}
-
-func Test_RTRIPPrefix(t *testing.T) {
- for i := range rtrIPPrefixTestCases {
- test := &rtrIPPrefixTestCases[i]
- addr := net.ParseIP(test.pString)
- verifyRTRMessage(t, NewRTRIPPrefix(addr, test.pLen, test.mLen, test.asn, test.flags))
- }
-}
-
-func Test_RTREndOfData(t *testing.T) {
- id := uint16(time.Now().Unix())
- sn := randUint32()
- verifyRTRMessage(t, NewRTREndOfData(id, sn))
-}
-
-func Test_RTRCacheReset(t *testing.T) {
- verifyRTRMessage(t, NewRTRCacheReset())
-}
-
-func Test_RTRErrorReport(t *testing.T) {
- errPDU, _ := NewRTRResetQuery().Serialize()
- errText1 := []byte("Couldn't send CacheResponce PDU")
- errText2 := []byte("Wrong Length of PDU: 10 bytes")
-
- // See 5.10 ErrorReport in RFC6810
- // when it doesn't have both "erroneous PDU" and "Arbitrary Text"
- verifyRTRMessage(t, NewRTRErrorReport(NO_DATA_AVAILABLE, nil, nil))
-
- // when it has "erroneous PDU"
- verifyRTRMessage(t, NewRTRErrorReport(UNSUPPORTED_PROTOCOL_VERSION, errPDU, nil))
-
- // when it has "ArbitaryText"
- verifyRTRMessage(t, NewRTRErrorReport(INTERNAL_ERROR, nil, errText1))
-
- // when it has both "erroneous PDU" and "Arbitrary Text"
- verifyRTRMessage(t, NewRTRErrorReport(CORRUPT_DATA, errPDU, errText2))
-}