1// Copyright 2016 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5//go:build darwin || dragonfly || freebsd || netbsd || openbsd 6// +build darwin dragonfly freebsd netbsd openbsd 7 8package route 9 10// A Message represents a routing message. 11type Message interface { 12 // Sys returns operating system-specific information. 13 Sys() []Sys 14} 15 16// A Sys reprensents operating system-specific information. 17type Sys interface { 18 // SysType returns a type of operating system-specific 19 // information. 20 SysType() SysType 21} 22 23// A SysType represents a type of operating system-specific 24// information. 25type SysType int 26 27const ( 28 SysMetrics SysType = iota 29 SysStats 30) 31 32// ParseRIB parses b as a routing information base and returns a list 33// of routing messages. 34func ParseRIB(typ RIBType, b []byte) ([]Message, error) { 35 if !typ.parseable() { 36 return nil, errUnsupportedMessage 37 } 38 var msgs []Message 39 nmsgs, nskips := 0, 0 40 for len(b) > 4 { 41 nmsgs++ 42 l := int(nativeEndian.Uint16(b[:2])) 43 if l == 0 { 44 return nil, errInvalidMessage 45 } 46 if len(b) < l { 47 return nil, errMessageTooShort 48 } 49 if b[2] != rtmVersion { 50 b = b[l:] 51 continue 52 } 53 if w, ok := wireFormats[int(b[3])]; !ok { 54 nskips++ 55 } else { 56 m, err := w.parse(typ, b) 57 if err != nil { 58 return nil, err 59 } 60 if m == nil { 61 nskips++ 62 } else { 63 msgs = append(msgs, m) 64 } 65 } 66 b = b[l:] 67 } 68 // We failed to parse any of the messages - version mismatch? 69 if nmsgs != len(msgs)+nskips { 70 return nil, errMessageMismatch 71 } 72 return msgs, nil 73} 74