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