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 // +build darwin dragonfly freebsd netbsd openbsd
12 "golang_org/x/net/route"
15 // If the ifindex is zero, interfaceTable returns mappings of all
16 // network interfaces. Otherwise it returns a mapping of a specific
18 func interfaceTable(ifindex
int) ([]Interface
, error
) {
19 msgs
, err
:= interfaceMessages(ifindex
)
27 ift
:= make([]Interface
, n
)
29 for _
, m
:= range msgs
{
30 switch m
:= m
.(type) {
31 case *route
.InterfaceMessage
:
32 if ifindex
!= 0 && ifindex
!= m
.Index
{
35 ift
[n
].Index
= m
.Index
37 ift
[n
].Flags
= linkFlags(m
.Flags
)
38 if sa
, ok
:= m
.Addrs
[syscall
.RTAX_IFP
].(*route
.LinkAddr
); ok
&& len(sa
.Addr
) > 0 {
39 ift
[n
].HardwareAddr
= make([]byte, len(sa
.Addr
))
40 copy(ift
[n
].HardwareAddr
, sa
.Addr
)
42 for _
, sys
:= range m
.Sys() {
43 if imx
, ok
:= sys
.(*route
.InterfaceMetrics
); ok
{
49 if ifindex
== m
.Index
{
57 func linkFlags(rawFlags
int) Flags
{
59 if rawFlags
&syscall
.IFF_UP
!= 0 {
62 if rawFlags
&syscall
.IFF_BROADCAST
!= 0 {
65 if rawFlags
&syscall
.IFF_LOOPBACK
!= 0 {
68 if rawFlags
&syscall
.IFF_POINTOPOINT
!= 0 {
71 if rawFlags
&syscall
.IFF_MULTICAST
!= 0 {
77 // If the ifi is nil, interfaceAddrTable returns addresses for all
78 // network interfaces. Otherwise it returns addresses for a specific
80 func interfaceAddrTable(ifi
*Interface
) ([]Addr
, error
) {
85 msgs
, err
:= interfaceMessages(index
)
89 ifat
:= make([]Addr
, 0, len(msgs
))
90 for _
, m
:= range msgs
{
91 switch m
:= m
.(type) {
92 case *route
.InterfaceAddrMessage
:
93 if index
!= 0 && index
!= m
.Index
{
97 switch sa
:= m
.Addrs
[syscall
.RTAX_NETMASK
].(type) {
98 case *route
.Inet4Addr
:
99 mask
= IPv4Mask(sa
.IP
[0], sa
.IP
[1], sa
.IP
[2], sa
.IP
[3])
100 case *route
.Inet6Addr
:
101 mask
= make(IPMask
, IPv6len
)
105 switch sa
:= m
.Addrs
[syscall
.RTAX_IFA
].(type) {
106 case *route
.Inet4Addr
:
107 ip
= IPv4(sa
.IP
[0], sa
.IP
[1], sa
.IP
[2], sa
.IP
[3])
108 case *route
.Inet6Addr
:
109 ip
= make(IP
, IPv6len
)
112 if ip
!= nil && mask
!= nil { // NetBSD may contain route.LinkAddr
113 ifat
= append(ifat
, &IPNet
{IP
: ip
, Mask
: mask
})