message.go 1.5 KB

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