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.
13 func bytePtrToString(p
*uint8) string {
14 a
:= (*[10000]uint8)(unsafe
.Pointer(p
))
22 func getAdapterList() (*syscall
.IpAdapterInfo
, error
) {
23 b
:= make([]byte, 1000)
25 a
:= (*syscall
.IpAdapterInfo
)(unsafe
.Pointer(&b
[0]))
26 // TODO(mikio): GetAdaptersInfo returns IP_ADAPTER_INFO that
27 // contains IPv4 address list only. We should use another API
28 // for fetching IPv6 stuff from the kernel.
29 err
:= syscall
.GetAdaptersInfo(a
, &l
)
30 if err
== syscall
.ERROR_BUFFER_OVERFLOW
{
32 a
= (*syscall
.IpAdapterInfo
)(unsafe
.Pointer(&b
[0]))
33 err
= syscall
.GetAdaptersInfo(a
, &l
)
36 return nil, os
.NewSyscallError("GetAdaptersInfo", err
)
41 func getInterfaceList() ([]syscall
.InterfaceInfo
, error
) {
42 s
, err
:= sysSocket(syscall
.AF_INET
, syscall
.SOCK_DGRAM
, syscall
.IPPROTO_UDP
)
44 return nil, os
.NewSyscallError("Socket", err
)
46 defer syscall
.Closesocket(s
)
48 ii
:= [20]syscall
.InterfaceInfo
{}
50 size
:= uint32(unsafe
.Sizeof(ii
))
51 err
= syscall
.WSAIoctl(s
, syscall
.SIO_GET_INTERFACE_LIST
, nil, 0, (*byte)(unsafe
.Pointer(&ii
[0])), size
, &ret
, nil, 0)
53 return nil, os
.NewSyscallError("WSAIoctl", err
)
55 c
:= ret
/ uint32(unsafe
.Sizeof(ii
[0]))
59 // If the ifindex is zero, interfaceTable returns mappings of all
60 // network interfaces. Otherwise it returns a mapping of a specific
62 func interfaceTable(ifindex
int) ([]Interface
, error
) {
63 ai
, err
:= getAdapterList()
68 ii
, err
:= getInterfaceList()
74 for ; ai
!= nil; ai
= ai
.Next
{
76 if ifindex
== 0 || ifindex
== int(index
) {
79 row
:= syscall
.MibIfRow
{Index
: index
}
80 e
:= syscall
.GetIfEntry(&row
)
82 return nil, os
.NewSyscallError("GetIfEntry", e
)
85 for _
, ii
:= range ii
{
86 ip
:= (*syscall
.RawSockaddrInet4
)(unsafe
.Pointer(&ii
.Address
)).Addr
87 ipv4
:= IPv4(ip
[0], ip
[1], ip
[2], ip
[3])
88 ipl
:= &ai
.IpAddressList
90 ips
:= bytePtrToString(&ipl
.IpAddress
.String
[0])
91 if ipv4
.Equal(parseIPv4(ips
)) {
99 if ii
.Flags
&syscall
.IFF_UP
!= 0 {
102 if ii
.Flags
&syscall
.IFF_LOOPBACK
!= 0 {
103 flags |
= FlagLoopback
105 if ii
.Flags
&syscall
.IFF_BROADCAST
!= 0 {
106 flags |
= FlagBroadcast
108 if ii
.Flags
&syscall
.IFF_POINTTOPOINT
!= 0 {
109 flags |
= FlagPointToPoint
111 if ii
.Flags
&syscall
.IFF_MULTICAST
!= 0 {
112 flags |
= FlagMulticast
116 name
:= bytePtrToString(&ai
.AdapterName
[0])
122 HardwareAddr
: HardwareAddr(row
.PhysAddr
[:row
.PhysAddrLen
]),
124 ift
= append(ift
, ifi
)
130 // If the ifi is nil, interfaceAddrTable returns addresses for all
131 // network interfaces. Otherwise it returns addresses for a specific
133 func interfaceAddrTable(ifi
*Interface
) ([]Addr
, error
) {
134 ai
, err
:= getAdapterList()
140 for ; ai
!= nil; ai
= ai
.Next
{
142 if ifi
== nil || ifi
.Index
== int(index
) {
143 ipl
:= &ai
.IpAddressList
144 for ; ipl
!= nil; ipl
= ipl
.Next
{
145 ifa
:= IPAddr
{IP
: parseIPv4(bytePtrToString(&ipl
.IpAddress
.String
[0]))}
146 ifat
= append(ifat
, ifa
.toAddr())
153 // interfaceMulticastAddrTable returns addresses for a specific
155 func interfaceMulticastAddrTable(ifi
*Interface
) ([]Addr
, error
) {
156 // TODO(mikio): Implement this like other platforms.