interface_freebsd.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  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. package net
  5. import (
  6. "os"
  7. "syscall"
  8. )
  9. // interfaceMulticastAddrTable returns addresses for a specific
  10. // interface.
  11. func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) {
  12. tab, err := syscall.RouteRIB(syscall.NET_RT_IFMALIST, ifi.Index)
  13. if err != nil {
  14. return nil, os.NewSyscallError("route rib", err)
  15. }
  16. msgs, err := syscall.ParseRoutingMessage(tab)
  17. if err != nil {
  18. return nil, os.NewSyscallError("route message", err)
  19. }
  20. var ifmat []Addr
  21. for _, m := range msgs {
  22. switch m := m.(type) {
  23. case *syscall.InterfaceMulticastAddrMessage:
  24. if ifi.Index == int(m.Header.Index) {
  25. ifma, err := newMulticastAddr(ifi, m)
  26. if err != nil {
  27. return nil, err
  28. }
  29. ifmat = append(ifmat, ifma...)
  30. }
  31. }
  32. }
  33. return ifmat, nil
  34. }
  35. func newMulticastAddr(ifi *Interface, m *syscall.InterfaceMulticastAddrMessage) ([]Addr, error) {
  36. sas, err := syscall.ParseRoutingSockaddr(m)
  37. if err != nil {
  38. return nil, os.NewSyscallError("route sockaddr", err)
  39. }
  40. var ifmat []Addr
  41. for _, sa := range sas {
  42. switch sa := sa.(type) {
  43. case *syscall.SockaddrInet4:
  44. ifma := &IPAddr{IP: IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])}
  45. ifmat = append(ifmat, ifma.toAddr())
  46. case *syscall.SockaddrInet6:
  47. ifma := &IPAddr{IP: make(IP, IPv6len)}
  48. copy(ifma.IP, sa.Addr[:])
  49. // NOTE: KAME based IPv6 protocol stack usually embeds
  50. // the interface index in the interface-local or link-
  51. // local address as the kernel-internal form.
  52. if ifma.IP.IsInterfaceLocalMulticast() || ifma.IP.IsLinkLocalMulticast() {
  53. ifma.IP[2], ifma.IP[3] = 0, 0
  54. }
  55. ifmat = append(ifmat, ifma.toAddr())
  56. }
  57. }
  58. return ifmat, nil
  59. }