blob: d53bb7f9b13108c9c1367da1874897afe5fb46e4 [file] [log] [blame]
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build darwin || dragonfly || freebsd || netbsd || openbsd
// +build darwin dragonfly freebsd netbsd openbsd
package route
// A Message represents a routing message.
type Message interface {
// Sys returns operating system-specific information.
Sys() []Sys
}
// A Sys reprensents operating system-specific information.
type Sys interface {
// SysType returns a type of operating system-specific
// information.
SysType() SysType
}
// A SysType represents a type of operating system-specific
// information.
type SysType int
const (
SysMetrics SysType = iota
SysStats
)
// ParseRIB parses b as a routing information base and returns a list
// of routing messages.
func ParseRIB(typ RIBType, b []byte) ([]Message, error) {
if !typ.parseable() {
return nil, errUnsupportedMessage
}
var msgs []Message
nmsgs, nskips := 0, 0
for len(b) > 4 {
nmsgs++
l := int(nativeEndian.Uint16(b[:2]))
if l == 0 {
return nil, errInvalidMessage
}
if len(b) < l {
return nil, errMessageTooShort
}
if b[2] != rtmVersion {
b = b[l:]
continue
}
if w, ok := wireFormats[int(b[3])]; !ok {
nskips++
} else {
m, err := w.parse(typ, b)
if err != nil {
return nil, err
}
if m == nil {
nskips++
} else {
msgs = append(msgs, m)
}
}
b = b[l:]
}
// We failed to parse any of the messages - version mismatch?
if nmsgs != len(msgs)+nskips {
return nil, errMessageMismatch
}
return msgs, nil
}