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 Windows
15 func bytePtrToString(p
*uint8) string {
16 a
:= (*[10000]uint8)(unsafe
.Pointer(p
))
24 func getAdapterList() (*syscall
.IpAdapterInfo
, error
) {
25 b
:= make([]byte, 1000)
27 a
:= (*syscall
.IpAdapterInfo
)(unsafe
.Pointer(&b
[0]))
28 err
:= syscall
.GetAdaptersInfo(a
, &l
)
29 if err
== syscall
.ERROR_BUFFER_OVERFLOW
{
31 a
= (*syscall
.IpAdapterInfo
)(unsafe
.Pointer(&b
[0]))
32 err
= syscall
.GetAdaptersInfo(a
, &l
)
35 return nil, os
.NewSyscallError("GetAdaptersInfo", err
)
40 func getInterfaceList() ([]syscall
.InterfaceInfo
, error
) {
41 s
, err
:= syscall
.Socket(syscall
.AF_INET
, syscall
.SOCK_DGRAM
, syscall
.IPPROTO_UDP
)
43 return nil, os
.NewSyscallError("Socket", err
)
45 defer syscall
.Closesocket(s
)
47 ii
:= [20]syscall
.InterfaceInfo
{}
49 size
:= uint32(unsafe
.Sizeof(ii
))
50 err
= syscall
.WSAIoctl(s
, syscall
.SIO_GET_INTERFACE_LIST
, nil, 0, (*byte)(unsafe
.Pointer(&ii
[0])), size
, &ret
, nil, 0)
52 return nil, os
.NewSyscallError("WSAIoctl", err
)
54 c
:= ret
/ uint32(unsafe
.Sizeof(ii
[0]))
58 // If the ifindex is zero, interfaceTable returns mappings of all
59 // network interfaces. Otherwise it returns a mapping of a specific
61 func interfaceTable(ifindex
int) ([]Interface
, error
) {
62 ai
, err
:= getAdapterList()
67 ii
, err
:= getInterfaceList()
73 for ; ai
!= nil; ai
= ai
.Next
{
75 if ifindex
== 0 || ifindex
== int(index
) {
78 row
:= syscall
.MibIfRow
{Index
: index
}
79 e
:= syscall
.GetIfEntry(&row
)
81 return nil, os
.NewSyscallError("GetIfEntry", e
)
84 for _
, ii
:= range ii
{
85 ip
:= (*syscall
.RawSockaddrInet4
)(unsafe
.Pointer(&ii
.Address
)).Addr
86 ipv4
:= IPv4(ip
[0], ip
[1], ip
[2], ip
[3])
87 ipl
:= &ai
.IpAddressList
89 ips
:= bytePtrToString(&ipl
.IpAddress
.String
[0])
90 if ipv4
.Equal(parseIPv4(ips
)) {
98 if ii
.Flags
&syscall
.IFF_UP
!= 0 {
101 if ii
.Flags
&syscall
.IFF_LOOPBACK
!= 0 {
102 flags |
= FlagLoopback
104 if ii
.Flags
&syscall
.IFF_BROADCAST
!= 0 {
105 flags |
= FlagBroadcast
107 if ii
.Flags
&syscall
.IFF_POINTTOPOINT
!= 0 {
108 flags |
= FlagPointToPoint
110 if ii
.Flags
&syscall
.IFF_MULTICAST
!= 0 {
111 flags |
= FlagMulticast
115 name
:= bytePtrToString(&ai
.AdapterName
[0])
121 HardwareAddr
: HardwareAddr(row
.PhysAddr
[:row
.PhysAddrLen
]),
123 ift
= append(ift
, ifi
)
129 // If the ifindex is zero, interfaceAddrTable returns addresses
130 // for all network interfaces. Otherwise it returns addresses
131 // for a specific interface.
132 func interfaceAddrTable(ifindex
int) ([]Addr
, error
) {
133 ai
, err
:= getAdapterList()
139 for ; ai
!= nil; ai
= ai
.Next
{
141 if ifindex
== 0 || ifindex
== int(index
) {
142 ipl
:= &ai
.IpAddressList
143 for ; ipl
!= nil; ipl
= ipl
.Next
{
145 ifa
.IP
= parseIPv4(bytePtrToString(&ipl
.IpAddress
.String
[0]))
146 ifat
= append(ifat
, ifa
.toAddr())
153 // If the ifindex is zero, interfaceMulticastAddrTable returns
154 // addresses for all network interfaces. Otherwise it returns
155 // addresses for a specific interface.
156 func interfaceMulticastAddrTable(ifindex
int) ([]Addr
, error
) {