71 lines
1.5 KiB
Go
71 lines
1.5 KiB
Go
|
// 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.
|
||
|
|
||
|
// +build darwin dragonfly freebsd netbsd openbsd
|
||
|
|
||
|
package route
|
||
|
|
||
|
// A Message represents a routing message.
|
||
|
//
|
||
|
// Note: This interface will be changed to support Marshal method in
|
||
|
// future version.
|
||
|
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 b[2] != sysRTM_VERSION {
|
||
|
b = b[l:]
|
||
|
continue
|
||
|
}
|
||
|
mtyp := int(b[3])
|
||
|
if fn, ok := parseFns[mtyp]; !ok {
|
||
|
nskips++
|
||
|
} else {
|
||
|
m, err := fn(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
|
||
|
}
|