You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

65 lines
1.7 KiB

  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. package route
  5. import "syscall"
  6. func (m *RouteMessage) marshal() ([]byte, error) {
  7. l := sizeofRtMsghdr + addrsSpace(m.Addrs)
  8. b := make([]byte, l)
  9. nativeEndian.PutUint16(b[:2], uint16(l))
  10. if m.Version == 0 {
  11. b[2] = sysRTM_VERSION
  12. } else {
  13. b[2] = byte(m.Version)
  14. }
  15. b[3] = byte(m.Type)
  16. nativeEndian.PutUint16(b[4:6], uint16(sizeofRtMsghdr))
  17. nativeEndian.PutUint32(b[16:20], uint32(m.Flags))
  18. nativeEndian.PutUint16(b[6:8], uint16(m.Index))
  19. nativeEndian.PutUint32(b[24:28], uint32(m.ID))
  20. nativeEndian.PutUint32(b[28:32], uint32(m.Seq))
  21. attrs, err := marshalAddrs(b[sizeofRtMsghdr:], m.Addrs)
  22. if err != nil {
  23. return nil, err
  24. }
  25. if attrs > 0 {
  26. nativeEndian.PutUint32(b[12:16], uint32(attrs))
  27. }
  28. return b, nil
  29. }
  30. func (*wireFormat) parseRouteMessage(_ RIBType, b []byte) (Message, error) {
  31. if len(b) < sizeofRtMsghdr {
  32. return nil, errMessageTooShort
  33. }
  34. l := int(nativeEndian.Uint16(b[:2]))
  35. if len(b) < l {
  36. return nil, errInvalidMessage
  37. }
  38. m := &RouteMessage{
  39. Version: int(b[2]),
  40. Type: int(b[3]),
  41. Flags: int(nativeEndian.Uint32(b[16:20])),
  42. Index: int(nativeEndian.Uint16(b[6:8])),
  43. ID: uintptr(nativeEndian.Uint32(b[24:28])),
  44. Seq: int(nativeEndian.Uint32(b[28:32])),
  45. raw: b[:l],
  46. }
  47. ll := int(nativeEndian.Uint16(b[4:6]))
  48. if len(b) < ll {
  49. return nil, errInvalidMessage
  50. }
  51. errno := syscall.Errno(nativeEndian.Uint32(b[32:36]))
  52. if errno != 0 {
  53. m.Err = errno
  54. }
  55. as, err := parseAddrs(uint(nativeEndian.Uint32(b[12:16])), parseKernelInetAddr, b[ll:])
  56. if err != nil {
  57. return nil, err
  58. }
  59. m.Addrs = as
  60. return m, nil
  61. }