Source file
src/net/interface_windows.go
1
2
3
4
5 package net
6
7 import (
8 "internal/syscall/windows"
9 "os"
10 "syscall"
11 "unsafe"
12 )
13
14
15
16
17
18 func adapterAddresses() ([]*windows.IpAdapterAddresses, error) {
19 var b []byte
20 l := uint32(15000)
21 for {
22 b = make([]byte, l)
23 const flags = windows.GAA_FLAG_INCLUDE_PREFIX | windows.GAA_FLAG_INCLUDE_GATEWAYS
24 err := windows.GetAdaptersAddresses(syscall.AF_UNSPEC, flags, 0, (*windows.IpAdapterAddresses)(unsafe.Pointer(&b[0])), &l)
25 if err == nil {
26 if l == 0 {
27 return nil, nil
28 }
29 break
30 }
31 if err.(syscall.Errno) != syscall.ERROR_BUFFER_OVERFLOW {
32 return nil, os.NewSyscallError("getadaptersaddresses", err)
33 }
34 if l <= uint32(len(b)) {
35 return nil, os.NewSyscallError("getadaptersaddresses", err)
36 }
37 }
38 var aas []*windows.IpAdapterAddresses
39 for aa := (*windows.IpAdapterAddresses)(unsafe.Pointer(&b[0])); aa != nil; aa = aa.Next {
40 aas = append(aas, aa)
41 }
42 return aas, nil
43 }
44
45
46
47
48 func interfaceTable(ifindex int) ([]Interface, error) {
49 aas, err := adapterAddresses()
50 if err != nil {
51 return nil, err
52 }
53 var ift []Interface
54 for _, aa := range aas {
55 index := aa.IfIndex
56 if index == 0 {
57 index = aa.Ipv6IfIndex
58 }
59 if ifindex == 0 || ifindex == int(index) {
60 ifi := Interface{
61 Index: int(index),
62 Name: windows.UTF16PtrToString(aa.FriendlyName),
63 }
64 if aa.OperStatus == windows.IfOperStatusUp {
65 ifi.Flags |= FlagUp
66 ifi.Flags |= FlagRunning
67 }
68
69
70
71
72 switch aa.IfType {
73 case windows.IF_TYPE_ETHERNET_CSMACD, windows.IF_TYPE_ISO88025_TOKENRING, windows.IF_TYPE_IEEE80211, windows.IF_TYPE_IEEE1394:
74 ifi.Flags |= FlagBroadcast | FlagMulticast
75 case windows.IF_TYPE_PPP, windows.IF_TYPE_TUNNEL:
76 ifi.Flags |= FlagPointToPoint | FlagMulticast
77 case windows.IF_TYPE_SOFTWARE_LOOPBACK:
78 ifi.Flags |= FlagLoopback | FlagMulticast
79 case windows.IF_TYPE_ATM:
80 ifi.Flags |= FlagBroadcast | FlagPointToPoint | FlagMulticast
81 }
82 if aa.Mtu == 0xffffffff {
83 ifi.MTU = -1
84 } else {
85 ifi.MTU = int(aa.Mtu)
86 }
87 if aa.PhysicalAddressLength > 0 {
88 ifi.HardwareAddr = make(HardwareAddr, aa.PhysicalAddressLength)
89 copy(ifi.HardwareAddr, aa.PhysicalAddress[:])
90 }
91 ift = append(ift, ifi)
92 if ifindex == ifi.Index {
93 break
94 }
95 }
96 }
97 return ift, nil
98 }
99
100
101
102
103 func interfaceAddrTable(ifi *Interface) ([]Addr, error) {
104 aas, err := adapterAddresses()
105 if err != nil {
106 return nil, err
107 }
108 var ifat []Addr
109 for _, aa := range aas {
110 index := aa.IfIndex
111 if index == 0 {
112 index = aa.Ipv6IfIndex
113 }
114 if ifi == nil || ifi.Index == int(index) {
115 for puni := aa.FirstUnicastAddress; puni != nil; puni = puni.Next {
116 sa, err := puni.Address.Sockaddr.Sockaddr()
117 if err != nil {
118 return nil, os.NewSyscallError("sockaddr", err)
119 }
120 switch sa := sa.(type) {
121 case *syscall.SockaddrInet4:
122 ifat = append(ifat, &IPNet{IP: IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3]), Mask: CIDRMask(int(puni.OnLinkPrefixLength), 8*IPv4len)})
123 case *syscall.SockaddrInet6:
124 ifa := &IPNet{IP: make(IP, IPv6len), Mask: CIDRMask(int(puni.OnLinkPrefixLength), 8*IPv6len)}
125 copy(ifa.IP, sa.Addr[:])
126 ifat = append(ifat, ifa)
127 }
128 }
129 for pany := aa.FirstAnycastAddress; pany != nil; pany = pany.Next {
130 sa, err := pany.Address.Sockaddr.Sockaddr()
131 if err != nil {
132 return nil, os.NewSyscallError("sockaddr", err)
133 }
134 switch sa := sa.(type) {
135 case *syscall.SockaddrInet4:
136 ifat = append(ifat, &IPAddr{IP: IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])})
137 case *syscall.SockaddrInet6:
138 ifa := &IPAddr{IP: make(IP, IPv6len)}
139 copy(ifa.IP, sa.Addr[:])
140 ifat = append(ifat, ifa)
141 }
142 }
143 }
144 }
145 return ifat, nil
146 }
147
148
149
150 func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) {
151 aas, err := adapterAddresses()
152 if err != nil {
153 return nil, err
154 }
155 var ifat []Addr
156 for _, aa := range aas {
157 index := aa.IfIndex
158 if index == 0 {
159 index = aa.Ipv6IfIndex
160 }
161 if ifi == nil || ifi.Index == int(index) {
162 for pmul := aa.FirstMulticastAddress; pmul != nil; pmul = pmul.Next {
163 sa, err := pmul.Address.Sockaddr.Sockaddr()
164 if err != nil {
165 return nil, os.NewSyscallError("sockaddr", err)
166 }
167 switch sa := sa.(type) {
168 case *syscall.SockaddrInet4:
169 ifat = append(ifat, &IPAddr{IP: IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])})
170 case *syscall.SockaddrInet6:
171 ifa := &IPAddr{IP: make(IP, IPv6len)}
172 copy(ifa.IP, sa.Addr[:])
173 ifat = append(ifat, ifa)
174 }
175 }
176 }
177 }
178 return ifat, nil
179 }
180
View as plain text