diff options
Diffstat (limited to 'packet/rtr/rtr.go')
-rw-r--r-- | packet/rtr/rtr.go | 392 |
1 files changed, 0 insertions, 392 deletions
diff --git a/packet/rtr/rtr.go b/packet/rtr/rtr.go deleted file mode 100644 index 902f1e62..00000000 --- a/packet/rtr/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 rtr - -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 -} |