Source file
src/net/interface_windows.go
Documentation: net
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 ifi.Flags |= FlagRunning
66 }
67
68
69
70
71 switch aa.IfType {
72 case windows.IF_TYPE_ETHERNET_CSMACD, windows.IF_TYPE_ISO88025_TOKENRING, windows.IF_TYPE_IEEE80211, windows.IF_TYPE_IEEE1394:
73 ifi.Flags |= FlagBroadcast | FlagMulticast
74 case windows.IF_TYPE_PPP, windows.IF_TYPE_TUNNEL:
75 ifi.Flags |= FlagPointToPoint | FlagMulticast
76 case windows.IF_TYPE_SOFTWARE_LOOPBACK:
77 ifi.Flags |= FlagLoopback | FlagMulticast
78 case windows.IF_TYPE_ATM:
79 ifi.Flags |= FlagBroadcast | FlagPointToPoint | FlagMulticast
80 }
81 if aa.Mtu == 0xffffffff {
82 ifi.MTU = -1
83 } else {
84 ifi.MTU = int(aa.Mtu)
85 }
86 if aa.PhysicalAddressLength > 0 {
87 ifi.HardwareAddr = make(HardwareAddr, aa.PhysicalAddressLength)
88 copy(ifi.HardwareAddr, aa.PhysicalAddress[:])
89 }
90 ift = append(ift, ifi)
91 if ifindex == ifi.Index {
92 break
93 }
94 }
95 }
96 return ift, nil
97 }
98
99
100
101
102 func interfaceAddrTable(ifi *Interface) ([]Addr, error) {
103 aas, err := adapterAddresses()
104 if err != nil {
105 return nil, err
106 }
107 var ifat []Addr
108 for _, aa := range aas {
109 index := aa.IfIndex
110 if index == 0 {
111 index = aa.Ipv6IfIndex
112 }
113 if ifi == nil || ifi.Index == int(index) {
114 for puni := aa.FirstUnicastAddress; puni != nil; puni = puni.Next {
115 sa, err := puni.Address.Sockaddr.Sockaddr()
116 if err != nil {
117 return nil, os.NewSyscallError("sockaddr", err)
118 }
119 switch sa := sa.(type) {
120 case *syscall.SockaddrInet4:
121 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)})
122 case *syscall.SockaddrInet6:
123 ifa := &IPNet{IP: make(IP, IPv6len), Mask: CIDRMask(int(puni.OnLinkPrefixLength), 8*IPv6len)}
124 copy(ifa.IP, sa.Addr[:])
125 ifat = append(ifat, ifa)
126 }
127 }
128 for pany := aa.FirstAnycastAddress; pany != nil; pany = pany.Next {
129 sa, err := pany.Address.Sockaddr.Sockaddr()
130 if err != nil {
131 return nil, os.NewSyscallError("sockaddr", err)
132 }
133 switch sa := sa.(type) {
134 case *syscall.SockaddrInet4:
135 ifat = append(ifat, &IPAddr{IP: IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])})
136 case *syscall.SockaddrInet6:
137 ifa := &IPAddr{IP: make(IP, IPv6len)}
138 copy(ifa.IP, sa.Addr[:])
139 ifat = append(ifat, ifa)
140 }
141 }
142 }
143 }
144 return ifat, nil
145 }
146
147
148
149 func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) {
150 aas, err := adapterAddresses()
151 if err != nil {
152 return nil, err
153 }
154 var ifat []Addr
155 for _, aa := range aas {
156 index := aa.IfIndex
157 if index == 0 {
158 index = aa.Ipv6IfIndex
159 }
160 if ifi == nil || ifi.Index == int(index) {
161 for pmul := aa.FirstMulticastAddress; pmul != nil; pmul = pmul.Next {
162 sa, err := pmul.Address.Sockaddr.Sockaddr()
163 if err != nil {
164 return nil, os.NewSyscallError("sockaddr", err)
165 }
166 switch sa := sa.(type) {
167 case *syscall.SockaddrInet4:
168 ifat = append(ifat, &IPAddr{IP: IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])})
169 case *syscall.SockaddrInet6:
170 ifa := &IPAddr{IP: make(IP, IPv6len)}
171 copy(ifa.IP, sa.Addr[:])
172 ifat = append(ifat, ifa)
173 }
174 }
175 }
176 }
177 return ifat, nil
178 }
179
View as plain text