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 // +build darwin dragonfly freebsd netbsd openbsd 6 7 package route 8 9 // A Message represents a routing message. 10 // 11 // Note: This interface will be changed to support Marshal method in 12 // future version. 13 type Message interface { 14 // Sys returns operating system-specific information. 15 Sys() []Sys 16 } 17 18 // A Sys reprensents operating system-specific information. 19 type Sys interface { 20 // SysType returns a type of operating system-specific 21 // information. 22 SysType() SysType 23 } 24 25 // A SysType represents a type of operating system-specific 26 // information. 27 type SysType int 28 29 const ( 30 SysMetrics SysType = iota 31 SysStats 32 ) 33 34 // ParseRIB parses b as a routing information base and returns a list 35 // of routing messages. 36 func ParseRIB(typ RIBType, b []byte) ([]Message, error) { 37 if !typ.parseable() { 38 return nil, errUnsupportedMessage 39 } 40 var msgs []Message 41 nmsgs, nskips := 0, 0 42 for len(b) > 4 { 43 nmsgs++ 44 l := int(nativeEndian.Uint16(b[:2])) 45 if l == 0 { 46 return nil, errInvalidMessage 47 } 48 if len(b) < l { 49 return nil, errMessageTooShort 50 } 51 if b[2] != sysRTM_VERSION { 52 b = b[l:] 53 continue 54 } 55 mtyp := int(b[3]) 56 if fn, ok := parseFns[mtyp]; !ok { 57 nskips++ 58 } else { 59 m, err := fn(typ, b) 60 if err != nil { 61 return nil, err 62 } 63 if m == nil { 64 nskips++ 65 } else { 66 msgs = append(msgs, m) 67 } 68 } 69 b = b[l:] 70 } 71 // We failed to parse any of the messages - version mismatch? 72 if nmsgs != len(msgs)+nskips { 73 return nil, errMessageMismatch 74 } 75 return msgs, nil 76 } 77