summaryrefslogtreecommitdiff
path: root/vendor/golang.org/x/net/route/message.go
blob: 0fa7e09f468ed125526c47160a4ebaf2b273f8a2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// 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.
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] != sysRTM_VERSION {
			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
}