Home | History | Annotate | Download | only in route
      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