route_classic.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  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. //go:build darwin || dragonfly || freebsd || netbsd
  5. // +build darwin dragonfly freebsd netbsd
  6. package route
  7. import (
  8. "runtime"
  9. "syscall"
  10. )
  11. func (m *RouteMessage) marshal() ([]byte, error) {
  12. w, ok := wireFormats[m.Type]
  13. if !ok {
  14. return nil, errUnsupportedMessage
  15. }
  16. l := w.bodyOff + addrsSpace(m.Addrs)
  17. if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
  18. // Fix stray pointer writes on macOS.
  19. // See golang.org/issue/22456.
  20. l += 1024
  21. }
  22. b := make([]byte, l)
  23. nativeEndian.PutUint16(b[:2], uint16(l))
  24. if m.Version == 0 {
  25. b[2] = rtmVersion
  26. } else {
  27. b[2] = byte(m.Version)
  28. }
  29. b[3] = byte(m.Type)
  30. nativeEndian.PutUint32(b[8:12], uint32(m.Flags))
  31. nativeEndian.PutUint16(b[4:6], uint16(m.Index))
  32. nativeEndian.PutUint32(b[16:20], uint32(m.ID))
  33. nativeEndian.PutUint32(b[20:24], uint32(m.Seq))
  34. attrs, err := marshalAddrs(b[w.bodyOff:], m.Addrs)
  35. if err != nil {
  36. return nil, err
  37. }
  38. if attrs > 0 {
  39. nativeEndian.PutUint32(b[12:16], uint32(attrs))
  40. }
  41. return b, nil
  42. }
  43. func (w *wireFormat) parseRouteMessage(typ RIBType, b []byte) (Message, error) {
  44. if len(b) < w.bodyOff {
  45. return nil, errMessageTooShort
  46. }
  47. l := int(nativeEndian.Uint16(b[:2]))
  48. if len(b) < l {
  49. return nil, errInvalidMessage
  50. }
  51. m := &RouteMessage{
  52. Version: int(b[2]),
  53. Type: int(b[3]),
  54. Flags: int(nativeEndian.Uint32(b[8:12])),
  55. Index: int(nativeEndian.Uint16(b[4:6])),
  56. ID: uintptr(nativeEndian.Uint32(b[16:20])),
  57. Seq: int(nativeEndian.Uint32(b[20:24])),
  58. extOff: w.extOff,
  59. raw: b[:l],
  60. }
  61. errno := syscall.Errno(nativeEndian.Uint32(b[28:32]))
  62. if errno != 0 {
  63. m.Err = errno
  64. }
  65. var err error
  66. m.Addrs, err = parseAddrs(uint(nativeEndian.Uint32(b[12:16])), parseKernelInetAddr, b[w.bodyOff:])
  67. if err != nil {
  68. return nil, err
  69. }
  70. return m, nil
  71. }