route_freebsd.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. // Copyright 2011 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. // Routing sockets and messages for FreeBSD
  5. package unix
  6. import "unsafe"
  7. // See http://www.freebsd.org/doc/en/books/porters-handbook/freebsd-versions.html.
  8. var freebsdVersion uint32
  9. func init() {
  10. freebsdVersion, _ = SysctlUint32("kern.osreldate")
  11. }
  12. func (any *anyMessage) toRoutingMessage(b []byte) RoutingMessage {
  13. switch any.Type {
  14. case RTM_ADD, RTM_DELETE, RTM_CHANGE, RTM_GET, RTM_LOSING, RTM_REDIRECT, RTM_MISS, RTM_LOCK, RTM_RESOLVE:
  15. p := (*RouteMessage)(unsafe.Pointer(any))
  16. return &RouteMessage{Header: p.Header, Data: b[SizeofRtMsghdr:any.Msglen]}
  17. case RTM_IFINFO:
  18. return any.parseInterfaceMessage(b)
  19. case RTM_IFANNOUNCE:
  20. p := (*InterfaceAnnounceMessage)(unsafe.Pointer(any))
  21. return &InterfaceAnnounceMessage{Header: p.Header}
  22. case RTM_NEWADDR, RTM_DELADDR:
  23. p := (*InterfaceAddrMessage)(unsafe.Pointer(any))
  24. return &InterfaceAddrMessage{Header: p.Header, Data: b[SizeofIfaMsghdr:any.Msglen]}
  25. case RTM_NEWMADDR, RTM_DELMADDR:
  26. p := (*InterfaceMulticastAddrMessage)(unsafe.Pointer(any))
  27. return &InterfaceMulticastAddrMessage{Header: p.Header, Data: b[SizeofIfmaMsghdr:any.Msglen]}
  28. }
  29. return nil
  30. }
  31. // InterfaceAnnounceMessage represents a routing message containing
  32. // network interface arrival and departure information.
  33. type InterfaceAnnounceMessage struct {
  34. Header IfAnnounceMsghdr
  35. }
  36. func (m *InterfaceAnnounceMessage) sockaddr() (sas []Sockaddr) { return nil }
  37. // InterfaceMulticastAddrMessage represents a routing message
  38. // containing network interface address entries.
  39. type InterfaceMulticastAddrMessage struct {
  40. Header IfmaMsghdr
  41. Data []byte
  42. }
  43. const rtaIfmaMask = RTA_GATEWAY | RTA_IFP | RTA_IFA
  44. func (m *InterfaceMulticastAddrMessage) sockaddr() (sas []Sockaddr) {
  45. if m.Header.Addrs&rtaIfmaMask == 0 {
  46. return nil
  47. }
  48. b := m.Data[:]
  49. for i := uint(0); i < RTAX_MAX; i++ {
  50. if m.Header.Addrs&rtaIfmaMask&(1<<i) == 0 {
  51. continue
  52. }
  53. rsa := (*RawSockaddr)(unsafe.Pointer(&b[0]))
  54. switch i {
  55. case RTAX_IFA:
  56. sa, e := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(rsa)))
  57. if e != nil {
  58. return nil
  59. }
  60. sas = append(sas, sa)
  61. case RTAX_GATEWAY, RTAX_IFP:
  62. // nothing to do
  63. }
  64. b = b[rsaAlignOf(int(rsa.Len)):]
  65. }
  66. return sas
  67. }