message.go 1.5 KB

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