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.
5 // Network interface identification for Darwin
14 // If the ifindex is zero, interfaceMulticastAddrTable returns
15 // addresses for all network interfaces. Otherwise it returns
16 // addresses for a specific interface.
17 func interfaceMulticastAddrTable(ifindex
int) ([]Addr
, error
) {
18 tab
, err
:= syscall
.RouteRIB(syscall
.NET_RT_IFLIST2
, ifindex
)
20 return nil, os
.NewSyscallError("route rib", err
)
23 msgs
, err
:= syscall
.ParseRoutingMessage(tab
)
25 return nil, os
.NewSyscallError("route message", err
)
29 for _
, m
:= range msgs
{
30 switch v
:= m
.(type) {
31 case *syscall
.InterfaceMulticastAddrMessage
:
32 if ifindex
== 0 || ifindex
== int(v
.Header
.Index
) {
33 ifma
, err
:= newMulticastAddr(v
)
37 ifmat
= append(ifmat
, ifma
...)
44 func newMulticastAddr(m
*syscall
.InterfaceMulticastAddrMessage
) ([]Addr
, error
) {
45 sas
, err
:= syscall
.ParseRoutingSockaddr(m
)
47 return nil, os
.NewSyscallError("route sockaddr", err
)
51 for _
, s
:= range sas
{
52 switch v
:= s
.(type) {
53 case *syscall
.SockaddrInet4
:
54 ifma
:= &IPAddr
{IP
: IPv4(v
.Addr
[0], v
.Addr
[1], v
.Addr
[2], v
.Addr
[3])}
55 ifmat
= append(ifmat
, ifma
.toAddr())
56 case *syscall
.SockaddrInet6
:
57 ifma
:= &IPAddr
{IP
: make(IP
, IPv6len
)}
58 copy(ifma
.IP
, v
.Addr
[:])
59 // NOTE: KAME based IPv6 protcol stack usually embeds
60 // the interface index in the interface-local or link-
61 // local address as the kernel-internal form.
62 if ifma
.IP
.IsInterfaceLocalMulticast() ||
63 ifma
.IP
.IsLinkLocalMulticast() {
64 // remove embedded scope zone ID
65 ifma
.IP
[2], ifma
.IP
[3] = 0, 0
67 ifmat
= append(ifmat
, ifma
.toAddr())