1
0
mirror of https://github.com/golang/go synced 2024-10-05 16:41:21 -06:00
go/src/net/interface_windows.go

277 lines
7.6 KiB
Go
Raw Normal View History

// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package net
import (
"internal/syscall/windows"
net: fix inconsistent errors These a series of changes fix inconsistent errors on the package net APIs. Now almost all the APIs return OpError as a common error type except Lookup, Resolve and Parse APIs. The Lookup, Resolve and Parse APIs return more specific errors such as DNSError, AddrError or ParseError. An OpError may contain nested error information. For example, Dial may return an OpError containing a DNSError, AddrError, unexposed type/value or other package's type/value like the following: OpError{/* dial info */, Err: &DNSError{}} OpError{/* dial info */, Err: &AddrError{}} OpError{/* dial info */, Err: <unexposed type or value>} OpError{/* dial info */, Err: <other package's type or value>} and Read and Write may return an OpError containing other OpError when an application uses io.Copy or similar: OpError{/* for io.Reader */, Err: &OpError{/* for io.Writer */}} When an endpoint is created for connection-oriented byte-stream protocols, Read may return an io.EOF when the connection is closed by remote endpoint. Fixes #4856. A series of changes: - net: fix inconsistent error values on Dial, Listen partially https://go.googlesource.com/go/+/89b7c66d0d14462fd7893be4290bdfe5f9063ae1 - net: fix inconsistent error values on Read https://go.googlesource.com/go/+/ec1144423f45e010c72363fe59291d43214b6e31 - net: fix inconsistent error values on Write https://go.googlesource.com/go/+/11b5f98bf0d5eb8854f735cc332c912725070214 - net: fix inconsistent error values on Close https://go.googlesource.com/go/+/310db63c5bc121e7bfccb494c01a6b91a257e7fc - net: fix inconsistent error values on Accept https://go.googlesource.com/go/+/4540e162b1aefda8157372764ad3d290a414ef1d - net: fix inconsistent error values on File https://go.googlesource.com/go/+/885111365ba0a74421059bfbd18f4c57c1e70332 - net: fix inconsistent error values on setters https://go.googlesource.com/go/+/2173a27903897c481b0a0daf3ca3e0a0685701db - net: fix inconsistent error values on Interface https://go.googlesource.com/go/+/456cf0f22c93e1a6654980f4a48a564555f6c8a2 - net: fix inconsistent error values on Lookup https://go.googlesource.com/go/+/0fc582e87942b2e52bed751b6c56660ba99e9a7d - net: add Source field to OpError https://go.googlesource.com/go/+/afd2d2b6df3ebfe99faf347030f15adfdf422fa0 Change-Id: Id678e369088dc9fbe9073cfe7ff8a8754a57d61f Reviewed-on: https://go-review.googlesource.com/9236 Reviewed-by: Ian Lance Taylor <iant@golang.org>
2015-04-21 06:20:15 -06:00
"os"
"syscall"
"unsafe"
)
net, internal/syscall/windows: fix interface and address identification on windows The current implementation including Go 1.5 through 1.5.2 misuses Windows API and mishandles the returned values from GetAdapterAddresses on Windows. This change fixes various issues related to network facility information by readjusting interface and interface address parsers. Updates #5395. Updates #10530. Updates #12301. Updates #12551. Updates #13542. Fixes #12691. Fixes #12811. Fixes #13476. Fixes #13544. Also fixes fragile screen scraping test cases in net_windows_test.go. Additional information for reviewers: It seems like almost all the issues above have the same root cause and it is misunderstanding of Windows API. If my interpretation of the information on MSDN is correctly, current implementation contains the following bugs: - SIO_GET_INTERFACE_LIST should not be used for IPv6. The behavior of SIO_GET_INTERFACE_LIST is different on kernels and probably it doesn't work correctly for IPv6 on old kernels such as Windows XP w/ SP2. Unfortunately MSDN doesn't describe the detail of SIO_GET_INTERFACE_LIST, but information on the net suggests so. - Fetching IP_ADAPTER_ADDRESSES structures with fixed size area may not work when using IPv6. IPv6 generates ton of interface addresses for various addressing scopes. We need to adjust the area appropriately. - PhysicalAddress field of IP_ADAPTER_ADDRESSES structure may have extra space. We cannot ignore PhysicalAddressLength field of IP_ADAPTER_ADDRESS structure. - Flags field of IP_ADAPTER_ADDRESSES structure doesn't represent any of administratively and operatinal statuses. It just represents settings for windows network adapter. - MTU field of IP_ADAPTER_ADDRESSES structure may have a uint32(-1) on 64-bit platform. We need to convert the value to interger appropriately. - IfType field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - OperStatus field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - IPv6IfIndex field of IP_ADAPTER_ADDRESSES structure is just a substitute for IfIndex field. We cannot prefer IPv6IfIndex to IfIndex. - Windows XP, 2003 server and below don't set OnLinkPrefixLength field of IP_ADAPTER_UNICAST_ADDRESS structure. We cannot rely on the field on old kernels. We can use FirstPrefix field of IP_ADAPTER_ADDRESSES structure and IP_ADAPTER_PREFIX structure instead. - Length field of IP_ADAPTER_{UNICAST,ANYCAST,MULTICAST}_ADDRESS sturecures doesn't represent an address prefix length. It just represents a socket address length. Change-Id: Icabdaf7bd1d41360a981d2dad0b830b02b584528 Reviewed-on: https://go-review.googlesource.com/17412 Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
2015-12-04 03:06:01 -07:00
// supportsVistaIP reports whether the platform implements new IP
// stack and ABIs supported on Windows Vista and above.
var supportsVistaIP bool
net, internal/syscall/windows: fix interface and address identification on windows The current implementation including Go 1.5 through 1.5.2 misuses Windows API and mishandles the returned values from GetAdapterAddresses on Windows. This change fixes various issues related to network facility information by readjusting interface and interface address parsers. Updates #5395. Updates #10530. Updates #12301. Updates #12551. Updates #13542. Fixes #12691. Fixes #12811. Fixes #13476. Fixes #13544. Also fixes fragile screen scraping test cases in net_windows_test.go. Additional information for reviewers: It seems like almost all the issues above have the same root cause and it is misunderstanding of Windows API. If my interpretation of the information on MSDN is correctly, current implementation contains the following bugs: - SIO_GET_INTERFACE_LIST should not be used for IPv6. The behavior of SIO_GET_INTERFACE_LIST is different on kernels and probably it doesn't work correctly for IPv6 on old kernels such as Windows XP w/ SP2. Unfortunately MSDN doesn't describe the detail of SIO_GET_INTERFACE_LIST, but information on the net suggests so. - Fetching IP_ADAPTER_ADDRESSES structures with fixed size area may not work when using IPv6. IPv6 generates ton of interface addresses for various addressing scopes. We need to adjust the area appropriately. - PhysicalAddress field of IP_ADAPTER_ADDRESSES structure may have extra space. We cannot ignore PhysicalAddressLength field of IP_ADAPTER_ADDRESS structure. - Flags field of IP_ADAPTER_ADDRESSES structure doesn't represent any of administratively and operatinal statuses. It just represents settings for windows network adapter. - MTU field of IP_ADAPTER_ADDRESSES structure may have a uint32(-1) on 64-bit platform. We need to convert the value to interger appropriately. - IfType field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - OperStatus field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - IPv6IfIndex field of IP_ADAPTER_ADDRESSES structure is just a substitute for IfIndex field. We cannot prefer IPv6IfIndex to IfIndex. - Windows XP, 2003 server and below don't set OnLinkPrefixLength field of IP_ADAPTER_UNICAST_ADDRESS structure. We cannot rely on the field on old kernels. We can use FirstPrefix field of IP_ADAPTER_ADDRESSES structure and IP_ADAPTER_PREFIX structure instead. - Length field of IP_ADAPTER_{UNICAST,ANYCAST,MULTICAST}_ADDRESS sturecures doesn't represent an address prefix length. It just represents a socket address length. Change-Id: Icabdaf7bd1d41360a981d2dad0b830b02b584528 Reviewed-on: https://go-review.googlesource.com/17412 Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
2015-12-04 03:06:01 -07:00
func init() {
supportsVistaIP = probeWindowsIPStack()
}
net, internal/syscall/windows: fix interface and address identification on windows The current implementation including Go 1.5 through 1.5.2 misuses Windows API and mishandles the returned values from GetAdapterAddresses on Windows. This change fixes various issues related to network facility information by readjusting interface and interface address parsers. Updates #5395. Updates #10530. Updates #12301. Updates #12551. Updates #13542. Fixes #12691. Fixes #12811. Fixes #13476. Fixes #13544. Also fixes fragile screen scraping test cases in net_windows_test.go. Additional information for reviewers: It seems like almost all the issues above have the same root cause and it is misunderstanding of Windows API. If my interpretation of the information on MSDN is correctly, current implementation contains the following bugs: - SIO_GET_INTERFACE_LIST should not be used for IPv6. The behavior of SIO_GET_INTERFACE_LIST is different on kernels and probably it doesn't work correctly for IPv6 on old kernels such as Windows XP w/ SP2. Unfortunately MSDN doesn't describe the detail of SIO_GET_INTERFACE_LIST, but information on the net suggests so. - Fetching IP_ADAPTER_ADDRESSES structures with fixed size area may not work when using IPv6. IPv6 generates ton of interface addresses for various addressing scopes. We need to adjust the area appropriately. - PhysicalAddress field of IP_ADAPTER_ADDRESSES structure may have extra space. We cannot ignore PhysicalAddressLength field of IP_ADAPTER_ADDRESS structure. - Flags field of IP_ADAPTER_ADDRESSES structure doesn't represent any of administratively and operatinal statuses. It just represents settings for windows network adapter. - MTU field of IP_ADAPTER_ADDRESSES structure may have a uint32(-1) on 64-bit platform. We need to convert the value to interger appropriately. - IfType field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - OperStatus field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - IPv6IfIndex field of IP_ADAPTER_ADDRESSES structure is just a substitute for IfIndex field. We cannot prefer IPv6IfIndex to IfIndex. - Windows XP, 2003 server and below don't set OnLinkPrefixLength field of IP_ADAPTER_UNICAST_ADDRESS structure. We cannot rely on the field on old kernels. We can use FirstPrefix field of IP_ADAPTER_ADDRESSES structure and IP_ADAPTER_PREFIX structure instead. - Length field of IP_ADAPTER_{UNICAST,ANYCAST,MULTICAST}_ADDRESS sturecures doesn't represent an address prefix length. It just represents a socket address length. Change-Id: Icabdaf7bd1d41360a981d2dad0b830b02b584528 Reviewed-on: https://go-review.googlesource.com/17412 Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
2015-12-04 03:06:01 -07:00
func probeWindowsIPStack() (supportsVistaIP bool) {
v, err := syscall.GetVersion()
if err != nil {
net, internal/syscall/windows: fix interface and address identification on windows The current implementation including Go 1.5 through 1.5.2 misuses Windows API and mishandles the returned values from GetAdapterAddresses on Windows. This change fixes various issues related to network facility information by readjusting interface and interface address parsers. Updates #5395. Updates #10530. Updates #12301. Updates #12551. Updates #13542. Fixes #12691. Fixes #12811. Fixes #13476. Fixes #13544. Also fixes fragile screen scraping test cases in net_windows_test.go. Additional information for reviewers: It seems like almost all the issues above have the same root cause and it is misunderstanding of Windows API. If my interpretation of the information on MSDN is correctly, current implementation contains the following bugs: - SIO_GET_INTERFACE_LIST should not be used for IPv6. The behavior of SIO_GET_INTERFACE_LIST is different on kernels and probably it doesn't work correctly for IPv6 on old kernels such as Windows XP w/ SP2. Unfortunately MSDN doesn't describe the detail of SIO_GET_INTERFACE_LIST, but information on the net suggests so. - Fetching IP_ADAPTER_ADDRESSES structures with fixed size area may not work when using IPv6. IPv6 generates ton of interface addresses for various addressing scopes. We need to adjust the area appropriately. - PhysicalAddress field of IP_ADAPTER_ADDRESSES structure may have extra space. We cannot ignore PhysicalAddressLength field of IP_ADAPTER_ADDRESS structure. - Flags field of IP_ADAPTER_ADDRESSES structure doesn't represent any of administratively and operatinal statuses. It just represents settings for windows network adapter. - MTU field of IP_ADAPTER_ADDRESSES structure may have a uint32(-1) on 64-bit platform. We need to convert the value to interger appropriately. - IfType field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - OperStatus field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - IPv6IfIndex field of IP_ADAPTER_ADDRESSES structure is just a substitute for IfIndex field. We cannot prefer IPv6IfIndex to IfIndex. - Windows XP, 2003 server and below don't set OnLinkPrefixLength field of IP_ADAPTER_UNICAST_ADDRESS structure. We cannot rely on the field on old kernels. We can use FirstPrefix field of IP_ADAPTER_ADDRESSES structure and IP_ADAPTER_PREFIX structure instead. - Length field of IP_ADAPTER_{UNICAST,ANYCAST,MULTICAST}_ADDRESS sturecures doesn't represent an address prefix length. It just represents a socket address length. Change-Id: Icabdaf7bd1d41360a981d2dad0b830b02b584528 Reviewed-on: https://go-review.googlesource.com/17412 Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
2015-12-04 03:06:01 -07:00
return true // Windows 10 and above will deprecate this API
}
net, internal/syscall/windows: fix interface and address identification on windows The current implementation including Go 1.5 through 1.5.2 misuses Windows API and mishandles the returned values from GetAdapterAddresses on Windows. This change fixes various issues related to network facility information by readjusting interface and interface address parsers. Updates #5395. Updates #10530. Updates #12301. Updates #12551. Updates #13542. Fixes #12691. Fixes #12811. Fixes #13476. Fixes #13544. Also fixes fragile screen scraping test cases in net_windows_test.go. Additional information for reviewers: It seems like almost all the issues above have the same root cause and it is misunderstanding of Windows API. If my interpretation of the information on MSDN is correctly, current implementation contains the following bugs: - SIO_GET_INTERFACE_LIST should not be used for IPv6. The behavior of SIO_GET_INTERFACE_LIST is different on kernels and probably it doesn't work correctly for IPv6 on old kernels such as Windows XP w/ SP2. Unfortunately MSDN doesn't describe the detail of SIO_GET_INTERFACE_LIST, but information on the net suggests so. - Fetching IP_ADAPTER_ADDRESSES structures with fixed size area may not work when using IPv6. IPv6 generates ton of interface addresses for various addressing scopes. We need to adjust the area appropriately. - PhysicalAddress field of IP_ADAPTER_ADDRESSES structure may have extra space. We cannot ignore PhysicalAddressLength field of IP_ADAPTER_ADDRESS structure. - Flags field of IP_ADAPTER_ADDRESSES structure doesn't represent any of administratively and operatinal statuses. It just represents settings for windows network adapter. - MTU field of IP_ADAPTER_ADDRESSES structure may have a uint32(-1) on 64-bit platform. We need to convert the value to interger appropriately. - IfType field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - OperStatus field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - IPv6IfIndex field of IP_ADAPTER_ADDRESSES structure is just a substitute for IfIndex field. We cannot prefer IPv6IfIndex to IfIndex. - Windows XP, 2003 server and below don't set OnLinkPrefixLength field of IP_ADAPTER_UNICAST_ADDRESS structure. We cannot rely on the field on old kernels. We can use FirstPrefix field of IP_ADAPTER_ADDRESSES structure and IP_ADAPTER_PREFIX structure instead. - Length field of IP_ADAPTER_{UNICAST,ANYCAST,MULTICAST}_ADDRESS sturecures doesn't represent an address prefix length. It just represents a socket address length. Change-Id: Icabdaf7bd1d41360a981d2dad0b830b02b584528 Reviewed-on: https://go-review.googlesource.com/17412 Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
2015-12-04 03:06:01 -07:00
if byte(v) < 6 { // major version of Windows Vista is 6
return false
}
return true
}
net, internal/syscall/windows: fix interface and address identification on windows The current implementation including Go 1.5 through 1.5.2 misuses Windows API and mishandles the returned values from GetAdapterAddresses on Windows. This change fixes various issues related to network facility information by readjusting interface and interface address parsers. Updates #5395. Updates #10530. Updates #12301. Updates #12551. Updates #13542. Fixes #12691. Fixes #12811. Fixes #13476. Fixes #13544. Also fixes fragile screen scraping test cases in net_windows_test.go. Additional information for reviewers: It seems like almost all the issues above have the same root cause and it is misunderstanding of Windows API. If my interpretation of the information on MSDN is correctly, current implementation contains the following bugs: - SIO_GET_INTERFACE_LIST should not be used for IPv6. The behavior of SIO_GET_INTERFACE_LIST is different on kernels and probably it doesn't work correctly for IPv6 on old kernels such as Windows XP w/ SP2. Unfortunately MSDN doesn't describe the detail of SIO_GET_INTERFACE_LIST, but information on the net suggests so. - Fetching IP_ADAPTER_ADDRESSES structures with fixed size area may not work when using IPv6. IPv6 generates ton of interface addresses for various addressing scopes. We need to adjust the area appropriately. - PhysicalAddress field of IP_ADAPTER_ADDRESSES structure may have extra space. We cannot ignore PhysicalAddressLength field of IP_ADAPTER_ADDRESS structure. - Flags field of IP_ADAPTER_ADDRESSES structure doesn't represent any of administratively and operatinal statuses. It just represents settings for windows network adapter. - MTU field of IP_ADAPTER_ADDRESSES structure may have a uint32(-1) on 64-bit platform. We need to convert the value to interger appropriately. - IfType field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - OperStatus field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - IPv6IfIndex field of IP_ADAPTER_ADDRESSES structure is just a substitute for IfIndex field. We cannot prefer IPv6IfIndex to IfIndex. - Windows XP, 2003 server and below don't set OnLinkPrefixLength field of IP_ADAPTER_UNICAST_ADDRESS structure. We cannot rely on the field on old kernels. We can use FirstPrefix field of IP_ADAPTER_ADDRESSES structure and IP_ADAPTER_PREFIX structure instead. - Length field of IP_ADAPTER_{UNICAST,ANYCAST,MULTICAST}_ADDRESS sturecures doesn't represent an address prefix length. It just represents a socket address length. Change-Id: Icabdaf7bd1d41360a981d2dad0b830b02b584528 Reviewed-on: https://go-review.googlesource.com/17412 Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
2015-12-04 03:06:01 -07:00
// adapterAddresses returns a list of IP adapter and address
// structures. The structure contains an IP adapter and flattened
// multiple IP addresses including unicast, anycast and multicast
// addresses.
func adapterAddresses() ([]*windows.IpAdapterAddresses, error) {
var b []byte
l := uint32(15000) // recommended initial size
for {
b = make([]byte, l)
err := windows.GetAdaptersAddresses(syscall.AF_UNSPEC, windows.GAA_FLAG_INCLUDE_PREFIX, 0, (*windows.IpAdapterAddresses)(unsafe.Pointer(&b[0])), &l)
if err == nil {
if l == 0 {
return nil, nil
}
net, internal/syscall/windows: fix interface and address identification on windows The current implementation including Go 1.5 through 1.5.2 misuses Windows API and mishandles the returned values from GetAdapterAddresses on Windows. This change fixes various issues related to network facility information by readjusting interface and interface address parsers. Updates #5395. Updates #10530. Updates #12301. Updates #12551. Updates #13542. Fixes #12691. Fixes #12811. Fixes #13476. Fixes #13544. Also fixes fragile screen scraping test cases in net_windows_test.go. Additional information for reviewers: It seems like almost all the issues above have the same root cause and it is misunderstanding of Windows API. If my interpretation of the information on MSDN is correctly, current implementation contains the following bugs: - SIO_GET_INTERFACE_LIST should not be used for IPv6. The behavior of SIO_GET_INTERFACE_LIST is different on kernels and probably it doesn't work correctly for IPv6 on old kernels such as Windows XP w/ SP2. Unfortunately MSDN doesn't describe the detail of SIO_GET_INTERFACE_LIST, but information on the net suggests so. - Fetching IP_ADAPTER_ADDRESSES structures with fixed size area may not work when using IPv6. IPv6 generates ton of interface addresses for various addressing scopes. We need to adjust the area appropriately. - PhysicalAddress field of IP_ADAPTER_ADDRESSES structure may have extra space. We cannot ignore PhysicalAddressLength field of IP_ADAPTER_ADDRESS structure. - Flags field of IP_ADAPTER_ADDRESSES structure doesn't represent any of administratively and operatinal statuses. It just represents settings for windows network adapter. - MTU field of IP_ADAPTER_ADDRESSES structure may have a uint32(-1) on 64-bit platform. We need to convert the value to interger appropriately. - IfType field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - OperStatus field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - IPv6IfIndex field of IP_ADAPTER_ADDRESSES structure is just a substitute for IfIndex field. We cannot prefer IPv6IfIndex to IfIndex. - Windows XP, 2003 server and below don't set OnLinkPrefixLength field of IP_ADAPTER_UNICAST_ADDRESS structure. We cannot rely on the field on old kernels. We can use FirstPrefix field of IP_ADAPTER_ADDRESSES structure and IP_ADAPTER_PREFIX structure instead. - Length field of IP_ADAPTER_{UNICAST,ANYCAST,MULTICAST}_ADDRESS sturecures doesn't represent an address prefix length. It just represents a socket address length. Change-Id: Icabdaf7bd1d41360a981d2dad0b830b02b584528 Reviewed-on: https://go-review.googlesource.com/17412 Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
2015-12-04 03:06:01 -07:00
break
}
net, internal/syscall/windows: fix interface and address identification on windows The current implementation including Go 1.5 through 1.5.2 misuses Windows API and mishandles the returned values from GetAdapterAddresses on Windows. This change fixes various issues related to network facility information by readjusting interface and interface address parsers. Updates #5395. Updates #10530. Updates #12301. Updates #12551. Updates #13542. Fixes #12691. Fixes #12811. Fixes #13476. Fixes #13544. Also fixes fragile screen scraping test cases in net_windows_test.go. Additional information for reviewers: It seems like almost all the issues above have the same root cause and it is misunderstanding of Windows API. If my interpretation of the information on MSDN is correctly, current implementation contains the following bugs: - SIO_GET_INTERFACE_LIST should not be used for IPv6. The behavior of SIO_GET_INTERFACE_LIST is different on kernels and probably it doesn't work correctly for IPv6 on old kernels such as Windows XP w/ SP2. Unfortunately MSDN doesn't describe the detail of SIO_GET_INTERFACE_LIST, but information on the net suggests so. - Fetching IP_ADAPTER_ADDRESSES structures with fixed size area may not work when using IPv6. IPv6 generates ton of interface addresses for various addressing scopes. We need to adjust the area appropriately. - PhysicalAddress field of IP_ADAPTER_ADDRESSES structure may have extra space. We cannot ignore PhysicalAddressLength field of IP_ADAPTER_ADDRESS structure. - Flags field of IP_ADAPTER_ADDRESSES structure doesn't represent any of administratively and operatinal statuses. It just represents settings for windows network adapter. - MTU field of IP_ADAPTER_ADDRESSES structure may have a uint32(-1) on 64-bit platform. We need to convert the value to interger appropriately. - IfType field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - OperStatus field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - IPv6IfIndex field of IP_ADAPTER_ADDRESSES structure is just a substitute for IfIndex field. We cannot prefer IPv6IfIndex to IfIndex. - Windows XP, 2003 server and below don't set OnLinkPrefixLength field of IP_ADAPTER_UNICAST_ADDRESS structure. We cannot rely on the field on old kernels. We can use FirstPrefix field of IP_ADAPTER_ADDRESSES structure and IP_ADAPTER_PREFIX structure instead. - Length field of IP_ADAPTER_{UNICAST,ANYCAST,MULTICAST}_ADDRESS sturecures doesn't represent an address prefix length. It just represents a socket address length. Change-Id: Icabdaf7bd1d41360a981d2dad0b830b02b584528 Reviewed-on: https://go-review.googlesource.com/17412 Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
2015-12-04 03:06:01 -07:00
if err.(syscall.Errno) != syscall.ERROR_BUFFER_OVERFLOW {
return nil, os.NewSyscallError("getadaptersaddresses", err)
}
if l <= uint32(len(b)) {
return nil, os.NewSyscallError("getadaptersaddresses", err)
}
}
var aas []*windows.IpAdapterAddresses
for aa := (*windows.IpAdapterAddresses)(unsafe.Pointer(&b[0])); aa != nil; aa = aa.Next {
aas = append(aas, aa)
}
net, internal/syscall/windows: fix interface and address identification on windows The current implementation including Go 1.5 through 1.5.2 misuses Windows API and mishandles the returned values from GetAdapterAddresses on Windows. This change fixes various issues related to network facility information by readjusting interface and interface address parsers. Updates #5395. Updates #10530. Updates #12301. Updates #12551. Updates #13542. Fixes #12691. Fixes #12811. Fixes #13476. Fixes #13544. Also fixes fragile screen scraping test cases in net_windows_test.go. Additional information for reviewers: It seems like almost all the issues above have the same root cause and it is misunderstanding of Windows API. If my interpretation of the information on MSDN is correctly, current implementation contains the following bugs: - SIO_GET_INTERFACE_LIST should not be used for IPv6. The behavior of SIO_GET_INTERFACE_LIST is different on kernels and probably it doesn't work correctly for IPv6 on old kernels such as Windows XP w/ SP2. Unfortunately MSDN doesn't describe the detail of SIO_GET_INTERFACE_LIST, but information on the net suggests so. - Fetching IP_ADAPTER_ADDRESSES structures with fixed size area may not work when using IPv6. IPv6 generates ton of interface addresses for various addressing scopes. We need to adjust the area appropriately. - PhysicalAddress field of IP_ADAPTER_ADDRESSES structure may have extra space. We cannot ignore PhysicalAddressLength field of IP_ADAPTER_ADDRESS structure. - Flags field of IP_ADAPTER_ADDRESSES structure doesn't represent any of administratively and operatinal statuses. It just represents settings for windows network adapter. - MTU field of IP_ADAPTER_ADDRESSES structure may have a uint32(-1) on 64-bit platform. We need to convert the value to interger appropriately. - IfType field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - OperStatus field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - IPv6IfIndex field of IP_ADAPTER_ADDRESSES structure is just a substitute for IfIndex field. We cannot prefer IPv6IfIndex to IfIndex. - Windows XP, 2003 server and below don't set OnLinkPrefixLength field of IP_ADAPTER_UNICAST_ADDRESS structure. We cannot rely on the field on old kernels. We can use FirstPrefix field of IP_ADAPTER_ADDRESSES structure and IP_ADAPTER_PREFIX structure instead. - Length field of IP_ADAPTER_{UNICAST,ANYCAST,MULTICAST}_ADDRESS sturecures doesn't represent an address prefix length. It just represents a socket address length. Change-Id: Icabdaf7bd1d41360a981d2dad0b830b02b584528 Reviewed-on: https://go-review.googlesource.com/17412 Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
2015-12-04 03:06:01 -07:00
return aas, nil
}
// If the ifindex is zero, interfaceTable returns mappings of all
// network interfaces. Otherwise it returns a mapping of a specific
// interface.
func interfaceTable(ifindex int) ([]Interface, error) {
net, internal/syscall/windows: fix interface and address identification on windows The current implementation including Go 1.5 through 1.5.2 misuses Windows API and mishandles the returned values from GetAdapterAddresses on Windows. This change fixes various issues related to network facility information by readjusting interface and interface address parsers. Updates #5395. Updates #10530. Updates #12301. Updates #12551. Updates #13542. Fixes #12691. Fixes #12811. Fixes #13476. Fixes #13544. Also fixes fragile screen scraping test cases in net_windows_test.go. Additional information for reviewers: It seems like almost all the issues above have the same root cause and it is misunderstanding of Windows API. If my interpretation of the information on MSDN is correctly, current implementation contains the following bugs: - SIO_GET_INTERFACE_LIST should not be used for IPv6. The behavior of SIO_GET_INTERFACE_LIST is different on kernels and probably it doesn't work correctly for IPv6 on old kernels such as Windows XP w/ SP2. Unfortunately MSDN doesn't describe the detail of SIO_GET_INTERFACE_LIST, but information on the net suggests so. - Fetching IP_ADAPTER_ADDRESSES structures with fixed size area may not work when using IPv6. IPv6 generates ton of interface addresses for various addressing scopes. We need to adjust the area appropriately. - PhysicalAddress field of IP_ADAPTER_ADDRESSES structure may have extra space. We cannot ignore PhysicalAddressLength field of IP_ADAPTER_ADDRESS structure. - Flags field of IP_ADAPTER_ADDRESSES structure doesn't represent any of administratively and operatinal statuses. It just represents settings for windows network adapter. - MTU field of IP_ADAPTER_ADDRESSES structure may have a uint32(-1) on 64-bit platform. We need to convert the value to interger appropriately. - IfType field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - OperStatus field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - IPv6IfIndex field of IP_ADAPTER_ADDRESSES structure is just a substitute for IfIndex field. We cannot prefer IPv6IfIndex to IfIndex. - Windows XP, 2003 server and below don't set OnLinkPrefixLength field of IP_ADAPTER_UNICAST_ADDRESS structure. We cannot rely on the field on old kernels. We can use FirstPrefix field of IP_ADAPTER_ADDRESSES structure and IP_ADAPTER_PREFIX structure instead. - Length field of IP_ADAPTER_{UNICAST,ANYCAST,MULTICAST}_ADDRESS sturecures doesn't represent an address prefix length. It just represents a socket address length. Change-Id: Icabdaf7bd1d41360a981d2dad0b830b02b584528 Reviewed-on: https://go-review.googlesource.com/17412 Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
2015-12-04 03:06:01 -07:00
aas, err := adapterAddresses()
if err != nil {
return nil, err
}
var ift []Interface
net, internal/syscall/windows: fix interface and address identification on windows The current implementation including Go 1.5 through 1.5.2 misuses Windows API and mishandles the returned values from GetAdapterAddresses on Windows. This change fixes various issues related to network facility information by readjusting interface and interface address parsers. Updates #5395. Updates #10530. Updates #12301. Updates #12551. Updates #13542. Fixes #12691. Fixes #12811. Fixes #13476. Fixes #13544. Also fixes fragile screen scraping test cases in net_windows_test.go. Additional information for reviewers: It seems like almost all the issues above have the same root cause and it is misunderstanding of Windows API. If my interpretation of the information on MSDN is correctly, current implementation contains the following bugs: - SIO_GET_INTERFACE_LIST should not be used for IPv6. The behavior of SIO_GET_INTERFACE_LIST is different on kernels and probably it doesn't work correctly for IPv6 on old kernels such as Windows XP w/ SP2. Unfortunately MSDN doesn't describe the detail of SIO_GET_INTERFACE_LIST, but information on the net suggests so. - Fetching IP_ADAPTER_ADDRESSES structures with fixed size area may not work when using IPv6. IPv6 generates ton of interface addresses for various addressing scopes. We need to adjust the area appropriately. - PhysicalAddress field of IP_ADAPTER_ADDRESSES structure may have extra space. We cannot ignore PhysicalAddressLength field of IP_ADAPTER_ADDRESS structure. - Flags field of IP_ADAPTER_ADDRESSES structure doesn't represent any of administratively and operatinal statuses. It just represents settings for windows network adapter. - MTU field of IP_ADAPTER_ADDRESSES structure may have a uint32(-1) on 64-bit platform. We need to convert the value to interger appropriately. - IfType field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - OperStatus field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - IPv6IfIndex field of IP_ADAPTER_ADDRESSES structure is just a substitute for IfIndex field. We cannot prefer IPv6IfIndex to IfIndex. - Windows XP, 2003 server and below don't set OnLinkPrefixLength field of IP_ADAPTER_UNICAST_ADDRESS structure. We cannot rely on the field on old kernels. We can use FirstPrefix field of IP_ADAPTER_ADDRESSES structure and IP_ADAPTER_PREFIX structure instead. - Length field of IP_ADAPTER_{UNICAST,ANYCAST,MULTICAST}_ADDRESS sturecures doesn't represent an address prefix length. It just represents a socket address length. Change-Id: Icabdaf7bd1d41360a981d2dad0b830b02b584528 Reviewed-on: https://go-review.googlesource.com/17412 Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
2015-12-04 03:06:01 -07:00
for _, aa := range aas {
index := aa.IfIndex
if index == 0 { // ipv6IfIndex is a sustitute for ifIndex
index = aa.Ipv6IfIndex
}
if ifindex == 0 || ifindex == int(index) {
net, internal/syscall/windows: fix interface and address identification on windows The current implementation including Go 1.5 through 1.5.2 misuses Windows API and mishandles the returned values from GetAdapterAddresses on Windows. This change fixes various issues related to network facility information by readjusting interface and interface address parsers. Updates #5395. Updates #10530. Updates #12301. Updates #12551. Updates #13542. Fixes #12691. Fixes #12811. Fixes #13476. Fixes #13544. Also fixes fragile screen scraping test cases in net_windows_test.go. Additional information for reviewers: It seems like almost all the issues above have the same root cause and it is misunderstanding of Windows API. If my interpretation of the information on MSDN is correctly, current implementation contains the following bugs: - SIO_GET_INTERFACE_LIST should not be used for IPv6. The behavior of SIO_GET_INTERFACE_LIST is different on kernels and probably it doesn't work correctly for IPv6 on old kernels such as Windows XP w/ SP2. Unfortunately MSDN doesn't describe the detail of SIO_GET_INTERFACE_LIST, but information on the net suggests so. - Fetching IP_ADAPTER_ADDRESSES structures with fixed size area may not work when using IPv6. IPv6 generates ton of interface addresses for various addressing scopes. We need to adjust the area appropriately. - PhysicalAddress field of IP_ADAPTER_ADDRESSES structure may have extra space. We cannot ignore PhysicalAddressLength field of IP_ADAPTER_ADDRESS structure. - Flags field of IP_ADAPTER_ADDRESSES structure doesn't represent any of administratively and operatinal statuses. It just represents settings for windows network adapter. - MTU field of IP_ADAPTER_ADDRESSES structure may have a uint32(-1) on 64-bit platform. We need to convert the value to interger appropriately. - IfType field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - OperStatus field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - IPv6IfIndex field of IP_ADAPTER_ADDRESSES structure is just a substitute for IfIndex field. We cannot prefer IPv6IfIndex to IfIndex. - Windows XP, 2003 server and below don't set OnLinkPrefixLength field of IP_ADAPTER_UNICAST_ADDRESS structure. We cannot rely on the field on old kernels. We can use FirstPrefix field of IP_ADAPTER_ADDRESSES structure and IP_ADAPTER_PREFIX structure instead. - Length field of IP_ADAPTER_{UNICAST,ANYCAST,MULTICAST}_ADDRESS sturecures doesn't represent an address prefix length. It just represents a socket address length. Change-Id: Icabdaf7bd1d41360a981d2dad0b830b02b584528 Reviewed-on: https://go-review.googlesource.com/17412 Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
2015-12-04 03:06:01 -07:00
ifi := Interface{
Index: int(index),
Name: syscall.UTF16ToString((*(*[10000]uint16)(unsafe.Pointer(aa.FriendlyName)))[:]),
}
net, internal/syscall/windows: fix interface and address identification on windows The current implementation including Go 1.5 through 1.5.2 misuses Windows API and mishandles the returned values from GetAdapterAddresses on Windows. This change fixes various issues related to network facility information by readjusting interface and interface address parsers. Updates #5395. Updates #10530. Updates #12301. Updates #12551. Updates #13542. Fixes #12691. Fixes #12811. Fixes #13476. Fixes #13544. Also fixes fragile screen scraping test cases in net_windows_test.go. Additional information for reviewers: It seems like almost all the issues above have the same root cause and it is misunderstanding of Windows API. If my interpretation of the information on MSDN is correctly, current implementation contains the following bugs: - SIO_GET_INTERFACE_LIST should not be used for IPv6. The behavior of SIO_GET_INTERFACE_LIST is different on kernels and probably it doesn't work correctly for IPv6 on old kernels such as Windows XP w/ SP2. Unfortunately MSDN doesn't describe the detail of SIO_GET_INTERFACE_LIST, but information on the net suggests so. - Fetching IP_ADAPTER_ADDRESSES structures with fixed size area may not work when using IPv6. IPv6 generates ton of interface addresses for various addressing scopes. We need to adjust the area appropriately. - PhysicalAddress field of IP_ADAPTER_ADDRESSES structure may have extra space. We cannot ignore PhysicalAddressLength field of IP_ADAPTER_ADDRESS structure. - Flags field of IP_ADAPTER_ADDRESSES structure doesn't represent any of administratively and operatinal statuses. It just represents settings for windows network adapter. - MTU field of IP_ADAPTER_ADDRESSES structure may have a uint32(-1) on 64-bit platform. We need to convert the value to interger appropriately. - IfType field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - OperStatus field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - IPv6IfIndex field of IP_ADAPTER_ADDRESSES structure is just a substitute for IfIndex field. We cannot prefer IPv6IfIndex to IfIndex. - Windows XP, 2003 server and below don't set OnLinkPrefixLength field of IP_ADAPTER_UNICAST_ADDRESS structure. We cannot rely on the field on old kernels. We can use FirstPrefix field of IP_ADAPTER_ADDRESSES structure and IP_ADAPTER_PREFIX structure instead. - Length field of IP_ADAPTER_{UNICAST,ANYCAST,MULTICAST}_ADDRESS sturecures doesn't represent an address prefix length. It just represents a socket address length. Change-Id: Icabdaf7bd1d41360a981d2dad0b830b02b584528 Reviewed-on: https://go-review.googlesource.com/17412 Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
2015-12-04 03:06:01 -07:00
if aa.OperStatus == windows.IfOperStatusUp {
ifi.Flags |= FlagUp
}
net, internal/syscall/windows: fix interface and address identification on windows The current implementation including Go 1.5 through 1.5.2 misuses Windows API and mishandles the returned values from GetAdapterAddresses on Windows. This change fixes various issues related to network facility information by readjusting interface and interface address parsers. Updates #5395. Updates #10530. Updates #12301. Updates #12551. Updates #13542. Fixes #12691. Fixes #12811. Fixes #13476. Fixes #13544. Also fixes fragile screen scraping test cases in net_windows_test.go. Additional information for reviewers: It seems like almost all the issues above have the same root cause and it is misunderstanding of Windows API. If my interpretation of the information on MSDN is correctly, current implementation contains the following bugs: - SIO_GET_INTERFACE_LIST should not be used for IPv6. The behavior of SIO_GET_INTERFACE_LIST is different on kernels and probably it doesn't work correctly for IPv6 on old kernels such as Windows XP w/ SP2. Unfortunately MSDN doesn't describe the detail of SIO_GET_INTERFACE_LIST, but information on the net suggests so. - Fetching IP_ADAPTER_ADDRESSES structures with fixed size area may not work when using IPv6. IPv6 generates ton of interface addresses for various addressing scopes. We need to adjust the area appropriately. - PhysicalAddress field of IP_ADAPTER_ADDRESSES structure may have extra space. We cannot ignore PhysicalAddressLength field of IP_ADAPTER_ADDRESS structure. - Flags field of IP_ADAPTER_ADDRESSES structure doesn't represent any of administratively and operatinal statuses. It just represents settings for windows network adapter. - MTU field of IP_ADAPTER_ADDRESSES structure may have a uint32(-1) on 64-bit platform. We need to convert the value to interger appropriately. - IfType field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - OperStatus field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - IPv6IfIndex field of IP_ADAPTER_ADDRESSES structure is just a substitute for IfIndex field. We cannot prefer IPv6IfIndex to IfIndex. - Windows XP, 2003 server and below don't set OnLinkPrefixLength field of IP_ADAPTER_UNICAST_ADDRESS structure. We cannot rely on the field on old kernels. We can use FirstPrefix field of IP_ADAPTER_ADDRESSES structure and IP_ADAPTER_PREFIX structure instead. - Length field of IP_ADAPTER_{UNICAST,ANYCAST,MULTICAST}_ADDRESS sturecures doesn't represent an address prefix length. It just represents a socket address length. Change-Id: Icabdaf7bd1d41360a981d2dad0b830b02b584528 Reviewed-on: https://go-review.googlesource.com/17412 Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
2015-12-04 03:06:01 -07:00
// For now we need to infer link-layer service
// capabilities from media types.
// We will be able to use
// MIB_IF_ROW2.AccessType once we drop support
// for Windows XP.
switch aa.IfType {
case windows.IF_TYPE_ETHERNET_CSMACD, windows.IF_TYPE_ISO88025_TOKENRING, windows.IF_TYPE_IEEE80211, windows.IF_TYPE_IEEE1394:
ifi.Flags |= FlagBroadcast | FlagMulticast
case windows.IF_TYPE_PPP, windows.IF_TYPE_TUNNEL:
ifi.Flags |= FlagPointToPoint | FlagMulticast
case windows.IF_TYPE_SOFTWARE_LOOPBACK:
ifi.Flags |= FlagLoopback | FlagMulticast
case windows.IF_TYPE_ATM:
ifi.Flags |= FlagBroadcast |
FlagPointToPoint |
FlagMulticast // assume all services available; LANE, point-to-point and point-to-multipoint
}
net, internal/syscall/windows: fix interface and address identification on windows The current implementation including Go 1.5 through 1.5.2 misuses Windows API and mishandles the returned values from GetAdapterAddresses on Windows. This change fixes various issues related to network facility information by readjusting interface and interface address parsers. Updates #5395. Updates #10530. Updates #12301. Updates #12551. Updates #13542. Fixes #12691. Fixes #12811. Fixes #13476. Fixes #13544. Also fixes fragile screen scraping test cases in net_windows_test.go. Additional information for reviewers: It seems like almost all the issues above have the same root cause and it is misunderstanding of Windows API. If my interpretation of the information on MSDN is correctly, current implementation contains the following bugs: - SIO_GET_INTERFACE_LIST should not be used for IPv6. The behavior of SIO_GET_INTERFACE_LIST is different on kernels and probably it doesn't work correctly for IPv6 on old kernels such as Windows XP w/ SP2. Unfortunately MSDN doesn't describe the detail of SIO_GET_INTERFACE_LIST, but information on the net suggests so. - Fetching IP_ADAPTER_ADDRESSES structures with fixed size area may not work when using IPv6. IPv6 generates ton of interface addresses for various addressing scopes. We need to adjust the area appropriately. - PhysicalAddress field of IP_ADAPTER_ADDRESSES structure may have extra space. We cannot ignore PhysicalAddressLength field of IP_ADAPTER_ADDRESS structure. - Flags field of IP_ADAPTER_ADDRESSES structure doesn't represent any of administratively and operatinal statuses. It just represents settings for windows network adapter. - MTU field of IP_ADAPTER_ADDRESSES structure may have a uint32(-1) on 64-bit platform. We need to convert the value to interger appropriately. - IfType field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - OperStatus field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - IPv6IfIndex field of IP_ADAPTER_ADDRESSES structure is just a substitute for IfIndex field. We cannot prefer IPv6IfIndex to IfIndex. - Windows XP, 2003 server and below don't set OnLinkPrefixLength field of IP_ADAPTER_UNICAST_ADDRESS structure. We cannot rely on the field on old kernels. We can use FirstPrefix field of IP_ADAPTER_ADDRESSES structure and IP_ADAPTER_PREFIX structure instead. - Length field of IP_ADAPTER_{UNICAST,ANYCAST,MULTICAST}_ADDRESS sturecures doesn't represent an address prefix length. It just represents a socket address length. Change-Id: Icabdaf7bd1d41360a981d2dad0b830b02b584528 Reviewed-on: https://go-review.googlesource.com/17412 Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
2015-12-04 03:06:01 -07:00
if aa.Mtu == 0xffffffff {
ifi.MTU = -1
} else {
ifi.MTU = int(aa.Mtu)
}
net, internal/syscall/windows: fix interface and address identification on windows The current implementation including Go 1.5 through 1.5.2 misuses Windows API and mishandles the returned values from GetAdapterAddresses on Windows. This change fixes various issues related to network facility information by readjusting interface and interface address parsers. Updates #5395. Updates #10530. Updates #12301. Updates #12551. Updates #13542. Fixes #12691. Fixes #12811. Fixes #13476. Fixes #13544. Also fixes fragile screen scraping test cases in net_windows_test.go. Additional information for reviewers: It seems like almost all the issues above have the same root cause and it is misunderstanding of Windows API. If my interpretation of the information on MSDN is correctly, current implementation contains the following bugs: - SIO_GET_INTERFACE_LIST should not be used for IPv6. The behavior of SIO_GET_INTERFACE_LIST is different on kernels and probably it doesn't work correctly for IPv6 on old kernels such as Windows XP w/ SP2. Unfortunately MSDN doesn't describe the detail of SIO_GET_INTERFACE_LIST, but information on the net suggests so. - Fetching IP_ADAPTER_ADDRESSES structures with fixed size area may not work when using IPv6. IPv6 generates ton of interface addresses for various addressing scopes. We need to adjust the area appropriately. - PhysicalAddress field of IP_ADAPTER_ADDRESSES structure may have extra space. We cannot ignore PhysicalAddressLength field of IP_ADAPTER_ADDRESS structure. - Flags field of IP_ADAPTER_ADDRESSES structure doesn't represent any of administratively and operatinal statuses. It just represents settings for windows network adapter. - MTU field of IP_ADAPTER_ADDRESSES structure may have a uint32(-1) on 64-bit platform. We need to convert the value to interger appropriately. - IfType field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - OperStatus field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - IPv6IfIndex field of IP_ADAPTER_ADDRESSES structure is just a substitute for IfIndex field. We cannot prefer IPv6IfIndex to IfIndex. - Windows XP, 2003 server and below don't set OnLinkPrefixLength field of IP_ADAPTER_UNICAST_ADDRESS structure. We cannot rely on the field on old kernels. We can use FirstPrefix field of IP_ADAPTER_ADDRESSES structure and IP_ADAPTER_PREFIX structure instead. - Length field of IP_ADAPTER_{UNICAST,ANYCAST,MULTICAST}_ADDRESS sturecures doesn't represent an address prefix length. It just represents a socket address length. Change-Id: Icabdaf7bd1d41360a981d2dad0b830b02b584528 Reviewed-on: https://go-review.googlesource.com/17412 Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
2015-12-04 03:06:01 -07:00
if aa.PhysicalAddressLength > 0 {
ifi.HardwareAddr = make(HardwareAddr, aa.PhysicalAddressLength)
copy(ifi.HardwareAddr, aa.PhysicalAddress[:])
}
ift = append(ift, ifi)
net, internal/syscall/windows: fix interface and address identification on windows The current implementation including Go 1.5 through 1.5.2 misuses Windows API and mishandles the returned values from GetAdapterAddresses on Windows. This change fixes various issues related to network facility information by readjusting interface and interface address parsers. Updates #5395. Updates #10530. Updates #12301. Updates #12551. Updates #13542. Fixes #12691. Fixes #12811. Fixes #13476. Fixes #13544. Also fixes fragile screen scraping test cases in net_windows_test.go. Additional information for reviewers: It seems like almost all the issues above have the same root cause and it is misunderstanding of Windows API. If my interpretation of the information on MSDN is correctly, current implementation contains the following bugs: - SIO_GET_INTERFACE_LIST should not be used for IPv6. The behavior of SIO_GET_INTERFACE_LIST is different on kernels and probably it doesn't work correctly for IPv6 on old kernels such as Windows XP w/ SP2. Unfortunately MSDN doesn't describe the detail of SIO_GET_INTERFACE_LIST, but information on the net suggests so. - Fetching IP_ADAPTER_ADDRESSES structures with fixed size area may not work when using IPv6. IPv6 generates ton of interface addresses for various addressing scopes. We need to adjust the area appropriately. - PhysicalAddress field of IP_ADAPTER_ADDRESSES structure may have extra space. We cannot ignore PhysicalAddressLength field of IP_ADAPTER_ADDRESS structure. - Flags field of IP_ADAPTER_ADDRESSES structure doesn't represent any of administratively and operatinal statuses. It just represents settings for windows network adapter. - MTU field of IP_ADAPTER_ADDRESSES structure may have a uint32(-1) on 64-bit platform. We need to convert the value to interger appropriately. - IfType field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - OperStatus field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - IPv6IfIndex field of IP_ADAPTER_ADDRESSES structure is just a substitute for IfIndex field. We cannot prefer IPv6IfIndex to IfIndex. - Windows XP, 2003 server and below don't set OnLinkPrefixLength field of IP_ADAPTER_UNICAST_ADDRESS structure. We cannot rely on the field on old kernels. We can use FirstPrefix field of IP_ADAPTER_ADDRESSES structure and IP_ADAPTER_PREFIX structure instead. - Length field of IP_ADAPTER_{UNICAST,ANYCAST,MULTICAST}_ADDRESS sturecures doesn't represent an address prefix length. It just represents a socket address length. Change-Id: Icabdaf7bd1d41360a981d2dad0b830b02b584528 Reviewed-on: https://go-review.googlesource.com/17412 Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
2015-12-04 03:06:01 -07:00
if ifindex == ifi.Index {
break
}
}
}
return ift, nil
}
net: fix slow network interface manipulations This CL reduces unnecessary network facility lookups introduced by recent changes below. changeset: 15798:53a4da6a4f4a net: return correct point-to-point interface address on linux changeset: 15799:a81ef8e0cc05 net: set up IPv6 scoped addressing zone for network facilities Also adds a test case for issue 4839. Benchmark results on linux/amd64, virtual machine: benchmark old ns/op new ns/op delta BenchmarkInterfaces-2 80487 80382 -0.13% BenchmarkInterfaceByIndex-2 72013 71391 -0.86% BenchmarkInterfaceByName-2 79865 80101 +0.30% BenchmarkInterfaceAddrs-2 42071 829677 +1872.09% BenchmarkInterfacesAndAddrs-2 35016 607622 +1635.27% BenchmarkInterfacesAndMulticastAddrs-2 169849 169082 -0.45% old: 15797:9c3930413c1b, new: tip Benchmark results on linux/amd64, virtual machine: benchmark old ns/op new ns/op delta BenchmarkInterfaces-2 80487 81459 +1.21% BenchmarkInterfaceByIndex-2 72013 71512 -0.70% BenchmarkInterfaceByName-2 79865 80567 +0.88% BenchmarkInterfaceAddrs-2 42071 120108 +185.49% BenchmarkInterfacesAndAddrs-2 35016 33259 -5.02% BenchmarkInterfacesAndMulticastAddrs-2 169849 82391 -51.49% old: 15797:9c3930413c1b, new: tip+CL7400055 Benchmark results on darwin/amd64: benchmark old ns/op new ns/op delta BenchmarkInterfaces-2 34402 34231 -0.50% BenchmarkInterfaceByIndex-2 13192 12956 -1.79% BenchmarkInterfaceByName-2 34791 34388 -1.16% BenchmarkInterfaceAddrs-2 36565 63906 +74.77% BenchmarkInterfacesAndAddrs-2 17497 31068 +77.56% BenchmarkInterfacesAndMulticastAddrs-2 25276 66711 +163.93% old: 15797:9c3930413c1b, new: tip Benchmark results on darwin/amd64: benchmark old ns/op new ns/op delta BenchmarkInterfaces-2 34402 31854 -7.41% BenchmarkInterfaceByIndex-2 13192 12950 -1.83% BenchmarkInterfaceByName-2 34791 31926 -8.23% BenchmarkInterfaceAddrs-2 36565 42144 +15.26% BenchmarkInterfacesAndAddrs-2 17497 17329 -0.96% BenchmarkInterfacesAndMulticastAddrs-2 25276 24870 -1.61% old: 15797:9c3930413c1b, new: tip+CL7400055 Update #4234. Fixes #4839 (again). Fixes #4866. R=golang-dev, fullung CC=golang-dev https://golang.org/cl/7400055
2013-02-27 22:58:41 -07:00
// If the ifi is nil, interfaceAddrTable returns addresses for all
// network interfaces. Otherwise it returns addresses for a specific
// interface.
func interfaceAddrTable(ifi *Interface) ([]Addr, error) {
net, internal/syscall/windows: fix interface and address identification on windows The current implementation including Go 1.5 through 1.5.2 misuses Windows API and mishandles the returned values from GetAdapterAddresses on Windows. This change fixes various issues related to network facility information by readjusting interface and interface address parsers. Updates #5395. Updates #10530. Updates #12301. Updates #12551. Updates #13542. Fixes #12691. Fixes #12811. Fixes #13476. Fixes #13544. Also fixes fragile screen scraping test cases in net_windows_test.go. Additional information for reviewers: It seems like almost all the issues above have the same root cause and it is misunderstanding of Windows API. If my interpretation of the information on MSDN is correctly, current implementation contains the following bugs: - SIO_GET_INTERFACE_LIST should not be used for IPv6. The behavior of SIO_GET_INTERFACE_LIST is different on kernels and probably it doesn't work correctly for IPv6 on old kernels such as Windows XP w/ SP2. Unfortunately MSDN doesn't describe the detail of SIO_GET_INTERFACE_LIST, but information on the net suggests so. - Fetching IP_ADAPTER_ADDRESSES structures with fixed size area may not work when using IPv6. IPv6 generates ton of interface addresses for various addressing scopes. We need to adjust the area appropriately. - PhysicalAddress field of IP_ADAPTER_ADDRESSES structure may have extra space. We cannot ignore PhysicalAddressLength field of IP_ADAPTER_ADDRESS structure. - Flags field of IP_ADAPTER_ADDRESSES structure doesn't represent any of administratively and operatinal statuses. It just represents settings for windows network adapter. - MTU field of IP_ADAPTER_ADDRESSES structure may have a uint32(-1) on 64-bit platform. We need to convert the value to interger appropriately. - IfType field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - OperStatus field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - IPv6IfIndex field of IP_ADAPTER_ADDRESSES structure is just a substitute for IfIndex field. We cannot prefer IPv6IfIndex to IfIndex. - Windows XP, 2003 server and below don't set OnLinkPrefixLength field of IP_ADAPTER_UNICAST_ADDRESS structure. We cannot rely on the field on old kernels. We can use FirstPrefix field of IP_ADAPTER_ADDRESSES structure and IP_ADAPTER_PREFIX structure instead. - Length field of IP_ADAPTER_{UNICAST,ANYCAST,MULTICAST}_ADDRESS sturecures doesn't represent an address prefix length. It just represents a socket address length. Change-Id: Icabdaf7bd1d41360a981d2dad0b830b02b584528 Reviewed-on: https://go-review.googlesource.com/17412 Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
2015-12-04 03:06:01 -07:00
aas, err := adapterAddresses()
if err != nil {
return nil, err
}
var ifat []Addr
net, internal/syscall/windows: fix interface and address identification on windows The current implementation including Go 1.5 through 1.5.2 misuses Windows API and mishandles the returned values from GetAdapterAddresses on Windows. This change fixes various issues related to network facility information by readjusting interface and interface address parsers. Updates #5395. Updates #10530. Updates #12301. Updates #12551. Updates #13542. Fixes #12691. Fixes #12811. Fixes #13476. Fixes #13544. Also fixes fragile screen scraping test cases in net_windows_test.go. Additional information for reviewers: It seems like almost all the issues above have the same root cause and it is misunderstanding of Windows API. If my interpretation of the information on MSDN is correctly, current implementation contains the following bugs: - SIO_GET_INTERFACE_LIST should not be used for IPv6. The behavior of SIO_GET_INTERFACE_LIST is different on kernels and probably it doesn't work correctly for IPv6 on old kernels such as Windows XP w/ SP2. Unfortunately MSDN doesn't describe the detail of SIO_GET_INTERFACE_LIST, but information on the net suggests so. - Fetching IP_ADAPTER_ADDRESSES structures with fixed size area may not work when using IPv6. IPv6 generates ton of interface addresses for various addressing scopes. We need to adjust the area appropriately. - PhysicalAddress field of IP_ADAPTER_ADDRESSES structure may have extra space. We cannot ignore PhysicalAddressLength field of IP_ADAPTER_ADDRESS structure. - Flags field of IP_ADAPTER_ADDRESSES structure doesn't represent any of administratively and operatinal statuses. It just represents settings for windows network adapter. - MTU field of IP_ADAPTER_ADDRESSES structure may have a uint32(-1) on 64-bit platform. We need to convert the value to interger appropriately. - IfType field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - OperStatus field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - IPv6IfIndex field of IP_ADAPTER_ADDRESSES structure is just a substitute for IfIndex field. We cannot prefer IPv6IfIndex to IfIndex. - Windows XP, 2003 server and below don't set OnLinkPrefixLength field of IP_ADAPTER_UNICAST_ADDRESS structure. We cannot rely on the field on old kernels. We can use FirstPrefix field of IP_ADAPTER_ADDRESSES structure and IP_ADAPTER_PREFIX structure instead. - Length field of IP_ADAPTER_{UNICAST,ANYCAST,MULTICAST}_ADDRESS sturecures doesn't represent an address prefix length. It just represents a socket address length. Change-Id: Icabdaf7bd1d41360a981d2dad0b830b02b584528 Reviewed-on: https://go-review.googlesource.com/17412 Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
2015-12-04 03:06:01 -07:00
for _, aa := range aas {
index := aa.IfIndex
if index == 0 { // ipv6IfIndex is a sustitute for ifIndex
index = aa.Ipv6IfIndex
}
var pfx4, pfx6 []IPNet
if !supportsVistaIP {
pfx4, pfx6, err = addrPrefixTable(aa)
if err != nil {
return nil, err
}
}
net: fix slow network interface manipulations This CL reduces unnecessary network facility lookups introduced by recent changes below. changeset: 15798:53a4da6a4f4a net: return correct point-to-point interface address on linux changeset: 15799:a81ef8e0cc05 net: set up IPv6 scoped addressing zone for network facilities Also adds a test case for issue 4839. Benchmark results on linux/amd64, virtual machine: benchmark old ns/op new ns/op delta BenchmarkInterfaces-2 80487 80382 -0.13% BenchmarkInterfaceByIndex-2 72013 71391 -0.86% BenchmarkInterfaceByName-2 79865 80101 +0.30% BenchmarkInterfaceAddrs-2 42071 829677 +1872.09% BenchmarkInterfacesAndAddrs-2 35016 607622 +1635.27% BenchmarkInterfacesAndMulticastAddrs-2 169849 169082 -0.45% old: 15797:9c3930413c1b, new: tip Benchmark results on linux/amd64, virtual machine: benchmark old ns/op new ns/op delta BenchmarkInterfaces-2 80487 81459 +1.21% BenchmarkInterfaceByIndex-2 72013 71512 -0.70% BenchmarkInterfaceByName-2 79865 80567 +0.88% BenchmarkInterfaceAddrs-2 42071 120108 +185.49% BenchmarkInterfacesAndAddrs-2 35016 33259 -5.02% BenchmarkInterfacesAndMulticastAddrs-2 169849 82391 -51.49% old: 15797:9c3930413c1b, new: tip+CL7400055 Benchmark results on darwin/amd64: benchmark old ns/op new ns/op delta BenchmarkInterfaces-2 34402 34231 -0.50% BenchmarkInterfaceByIndex-2 13192 12956 -1.79% BenchmarkInterfaceByName-2 34791 34388 -1.16% BenchmarkInterfaceAddrs-2 36565 63906 +74.77% BenchmarkInterfacesAndAddrs-2 17497 31068 +77.56% BenchmarkInterfacesAndMulticastAddrs-2 25276 66711 +163.93% old: 15797:9c3930413c1b, new: tip Benchmark results on darwin/amd64: benchmark old ns/op new ns/op delta BenchmarkInterfaces-2 34402 31854 -7.41% BenchmarkInterfaceByIndex-2 13192 12950 -1.83% BenchmarkInterfaceByName-2 34791 31926 -8.23% BenchmarkInterfaceAddrs-2 36565 42144 +15.26% BenchmarkInterfacesAndAddrs-2 17497 17329 -0.96% BenchmarkInterfacesAndMulticastAddrs-2 25276 24870 -1.61% old: 15797:9c3930413c1b, new: tip+CL7400055 Update #4234. Fixes #4839 (again). Fixes #4866. R=golang-dev, fullung CC=golang-dev https://golang.org/cl/7400055
2013-02-27 22:58:41 -07:00
if ifi == nil || ifi.Index == int(index) {
net, internal/syscall/windows: fix interface and address identification on windows The current implementation including Go 1.5 through 1.5.2 misuses Windows API and mishandles the returned values from GetAdapterAddresses on Windows. This change fixes various issues related to network facility information by readjusting interface and interface address parsers. Updates #5395. Updates #10530. Updates #12301. Updates #12551. Updates #13542. Fixes #12691. Fixes #12811. Fixes #13476. Fixes #13544. Also fixes fragile screen scraping test cases in net_windows_test.go. Additional information for reviewers: It seems like almost all the issues above have the same root cause and it is misunderstanding of Windows API. If my interpretation of the information on MSDN is correctly, current implementation contains the following bugs: - SIO_GET_INTERFACE_LIST should not be used for IPv6. The behavior of SIO_GET_INTERFACE_LIST is different on kernels and probably it doesn't work correctly for IPv6 on old kernels such as Windows XP w/ SP2. Unfortunately MSDN doesn't describe the detail of SIO_GET_INTERFACE_LIST, but information on the net suggests so. - Fetching IP_ADAPTER_ADDRESSES structures with fixed size area may not work when using IPv6. IPv6 generates ton of interface addresses for various addressing scopes. We need to adjust the area appropriately. - PhysicalAddress field of IP_ADAPTER_ADDRESSES structure may have extra space. We cannot ignore PhysicalAddressLength field of IP_ADAPTER_ADDRESS structure. - Flags field of IP_ADAPTER_ADDRESSES structure doesn't represent any of administratively and operatinal statuses. It just represents settings for windows network adapter. - MTU field of IP_ADAPTER_ADDRESSES structure may have a uint32(-1) on 64-bit platform. We need to convert the value to interger appropriately. - IfType field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - OperStatus field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - IPv6IfIndex field of IP_ADAPTER_ADDRESSES structure is just a substitute for IfIndex field. We cannot prefer IPv6IfIndex to IfIndex. - Windows XP, 2003 server and below don't set OnLinkPrefixLength field of IP_ADAPTER_UNICAST_ADDRESS structure. We cannot rely on the field on old kernels. We can use FirstPrefix field of IP_ADAPTER_ADDRESSES structure and IP_ADAPTER_PREFIX structure instead. - Length field of IP_ADAPTER_{UNICAST,ANYCAST,MULTICAST}_ADDRESS sturecures doesn't represent an address prefix length. It just represents a socket address length. Change-Id: Icabdaf7bd1d41360a981d2dad0b830b02b584528 Reviewed-on: https://go-review.googlesource.com/17412 Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
2015-12-04 03:06:01 -07:00
for puni := aa.FirstUnicastAddress; puni != nil; puni = puni.Next {
sa, err := puni.Address.Sockaddr.Sockaddr()
if err != nil {
return nil, os.NewSyscallError("sockaddr", err)
}
var l int
switch sa := sa.(type) {
case *syscall.SockaddrInet4:
if supportsVistaIP {
l = int(puni.OnLinkPrefixLength)
} else {
l = addrPrefixLen(pfx4, IP(sa.Addr[:]))
}
net, internal/syscall/windows: fix interface and address identification on windows The current implementation including Go 1.5 through 1.5.2 misuses Windows API and mishandles the returned values from GetAdapterAddresses on Windows. This change fixes various issues related to network facility information by readjusting interface and interface address parsers. Updates #5395. Updates #10530. Updates #12301. Updates #12551. Updates #13542. Fixes #12691. Fixes #12811. Fixes #13476. Fixes #13544. Also fixes fragile screen scraping test cases in net_windows_test.go. Additional information for reviewers: It seems like almost all the issues above have the same root cause and it is misunderstanding of Windows API. If my interpretation of the information on MSDN is correctly, current implementation contains the following bugs: - SIO_GET_INTERFACE_LIST should not be used for IPv6. The behavior of SIO_GET_INTERFACE_LIST is different on kernels and probably it doesn't work correctly for IPv6 on old kernels such as Windows XP w/ SP2. Unfortunately MSDN doesn't describe the detail of SIO_GET_INTERFACE_LIST, but information on the net suggests so. - Fetching IP_ADAPTER_ADDRESSES structures with fixed size area may not work when using IPv6. IPv6 generates ton of interface addresses for various addressing scopes. We need to adjust the area appropriately. - PhysicalAddress field of IP_ADAPTER_ADDRESSES structure may have extra space. We cannot ignore PhysicalAddressLength field of IP_ADAPTER_ADDRESS structure. - Flags field of IP_ADAPTER_ADDRESSES structure doesn't represent any of administratively and operatinal statuses. It just represents settings for windows network adapter. - MTU field of IP_ADAPTER_ADDRESSES structure may have a uint32(-1) on 64-bit platform. We need to convert the value to interger appropriately. - IfType field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - OperStatus field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - IPv6IfIndex field of IP_ADAPTER_ADDRESSES structure is just a substitute for IfIndex field. We cannot prefer IPv6IfIndex to IfIndex. - Windows XP, 2003 server and below don't set OnLinkPrefixLength field of IP_ADAPTER_UNICAST_ADDRESS structure. We cannot rely on the field on old kernels. We can use FirstPrefix field of IP_ADAPTER_ADDRESSES structure and IP_ADAPTER_PREFIX structure instead. - Length field of IP_ADAPTER_{UNICAST,ANYCAST,MULTICAST}_ADDRESS sturecures doesn't represent an address prefix length. It just represents a socket address length. Change-Id: Icabdaf7bd1d41360a981d2dad0b830b02b584528 Reviewed-on: https://go-review.googlesource.com/17412 Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
2015-12-04 03:06:01 -07:00
ifa := &IPNet{IP: make(IP, IPv4len), Mask: CIDRMask(l, 8*IPv4len)}
copy(ifa.IP, sa.Addr[:])
ifat = append(ifat, ifa)
case *syscall.SockaddrInet6:
if supportsVistaIP {
l = int(puni.OnLinkPrefixLength)
} else {
l = addrPrefixLen(pfx6, IP(sa.Addr[:]))
}
ifa := &IPNet{IP: make(IP, IPv6len), Mask: CIDRMask(l, 8*IPv6len)}
copy(ifa.IP, sa.Addr[:])
ifat = append(ifat, ifa)
}
}
net, internal/syscall/windows: fix interface and address identification on windows The current implementation including Go 1.5 through 1.5.2 misuses Windows API and mishandles the returned values from GetAdapterAddresses on Windows. This change fixes various issues related to network facility information by readjusting interface and interface address parsers. Updates #5395. Updates #10530. Updates #12301. Updates #12551. Updates #13542. Fixes #12691. Fixes #12811. Fixes #13476. Fixes #13544. Also fixes fragile screen scraping test cases in net_windows_test.go. Additional information for reviewers: It seems like almost all the issues above have the same root cause and it is misunderstanding of Windows API. If my interpretation of the information on MSDN is correctly, current implementation contains the following bugs: - SIO_GET_INTERFACE_LIST should not be used for IPv6. The behavior of SIO_GET_INTERFACE_LIST is different on kernels and probably it doesn't work correctly for IPv6 on old kernels such as Windows XP w/ SP2. Unfortunately MSDN doesn't describe the detail of SIO_GET_INTERFACE_LIST, but information on the net suggests so. - Fetching IP_ADAPTER_ADDRESSES structures with fixed size area may not work when using IPv6. IPv6 generates ton of interface addresses for various addressing scopes. We need to adjust the area appropriately. - PhysicalAddress field of IP_ADAPTER_ADDRESSES structure may have extra space. We cannot ignore PhysicalAddressLength field of IP_ADAPTER_ADDRESS structure. - Flags field of IP_ADAPTER_ADDRESSES structure doesn't represent any of administratively and operatinal statuses. It just represents settings for windows network adapter. - MTU field of IP_ADAPTER_ADDRESSES structure may have a uint32(-1) on 64-bit platform. We need to convert the value to interger appropriately. - IfType field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - OperStatus field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - IPv6IfIndex field of IP_ADAPTER_ADDRESSES structure is just a substitute for IfIndex field. We cannot prefer IPv6IfIndex to IfIndex. - Windows XP, 2003 server and below don't set OnLinkPrefixLength field of IP_ADAPTER_UNICAST_ADDRESS structure. We cannot rely on the field on old kernels. We can use FirstPrefix field of IP_ADAPTER_ADDRESSES structure and IP_ADAPTER_PREFIX structure instead. - Length field of IP_ADAPTER_{UNICAST,ANYCAST,MULTICAST}_ADDRESS sturecures doesn't represent an address prefix length. It just represents a socket address length. Change-Id: Icabdaf7bd1d41360a981d2dad0b830b02b584528 Reviewed-on: https://go-review.googlesource.com/17412 Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
2015-12-04 03:06:01 -07:00
for pany := aa.FirstAnycastAddress; pany != nil; pany = pany.Next {
sa, err := pany.Address.Sockaddr.Sockaddr()
if err != nil {
return nil, os.NewSyscallError("sockaddr", err)
}
switch sa := sa.(type) {
case *syscall.SockaddrInet4:
ifa := &IPAddr{IP: make(IP, IPv4len)}
copy(ifa.IP, sa.Addr[:])
ifat = append(ifat, ifa)
case *syscall.SockaddrInet6:
ifa := &IPAddr{IP: make(IP, IPv6len)}
copy(ifa.IP, sa.Addr[:])
ifat = append(ifat, ifa)
}
}
}
}
return ifat, nil
}
net, internal/syscall/windows: fix interface and address identification on windows The current implementation including Go 1.5 through 1.5.2 misuses Windows API and mishandles the returned values from GetAdapterAddresses on Windows. This change fixes various issues related to network facility information by readjusting interface and interface address parsers. Updates #5395. Updates #10530. Updates #12301. Updates #12551. Updates #13542. Fixes #12691. Fixes #12811. Fixes #13476. Fixes #13544. Also fixes fragile screen scraping test cases in net_windows_test.go. Additional information for reviewers: It seems like almost all the issues above have the same root cause and it is misunderstanding of Windows API. If my interpretation of the information on MSDN is correctly, current implementation contains the following bugs: - SIO_GET_INTERFACE_LIST should not be used for IPv6. The behavior of SIO_GET_INTERFACE_LIST is different on kernels and probably it doesn't work correctly for IPv6 on old kernels such as Windows XP w/ SP2. Unfortunately MSDN doesn't describe the detail of SIO_GET_INTERFACE_LIST, but information on the net suggests so. - Fetching IP_ADAPTER_ADDRESSES structures with fixed size area may not work when using IPv6. IPv6 generates ton of interface addresses for various addressing scopes. We need to adjust the area appropriately. - PhysicalAddress field of IP_ADAPTER_ADDRESSES structure may have extra space. We cannot ignore PhysicalAddressLength field of IP_ADAPTER_ADDRESS structure. - Flags field of IP_ADAPTER_ADDRESSES structure doesn't represent any of administratively and operatinal statuses. It just represents settings for windows network adapter. - MTU field of IP_ADAPTER_ADDRESSES structure may have a uint32(-1) on 64-bit platform. We need to convert the value to interger appropriately. - IfType field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - OperStatus field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - IPv6IfIndex field of IP_ADAPTER_ADDRESSES structure is just a substitute for IfIndex field. We cannot prefer IPv6IfIndex to IfIndex. - Windows XP, 2003 server and below don't set OnLinkPrefixLength field of IP_ADAPTER_UNICAST_ADDRESS structure. We cannot rely on the field on old kernels. We can use FirstPrefix field of IP_ADAPTER_ADDRESSES structure and IP_ADAPTER_PREFIX structure instead. - Length field of IP_ADAPTER_{UNICAST,ANYCAST,MULTICAST}_ADDRESS sturecures doesn't represent an address prefix length. It just represents a socket address length. Change-Id: Icabdaf7bd1d41360a981d2dad0b830b02b584528 Reviewed-on: https://go-review.googlesource.com/17412 Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
2015-12-04 03:06:01 -07:00
func addrPrefixTable(aa *windows.IpAdapterAddresses) (pfx4, pfx6 []IPNet, err error) {
for p := aa.FirstPrefix; p != nil; p = p.Next {
sa, err := p.Address.Sockaddr.Sockaddr()
if err != nil {
return nil, nil, os.NewSyscallError("sockaddr", err)
}
switch sa := sa.(type) {
case *syscall.SockaddrInet4:
pfx := IPNet{IP: IP(sa.Addr[:]), Mask: CIDRMask(int(p.PrefixLength), 8*IPv4len)}
pfx4 = append(pfx4, pfx)
case *syscall.SockaddrInet6:
pfx := IPNet{IP: IP(sa.Addr[:]), Mask: CIDRMask(int(p.PrefixLength), 8*IPv6len)}
pfx6 = append(pfx6, pfx)
}
}
return
}
// addrPrefixLen returns an appropriate prefix length in bits for ip
// from pfxs. It returns 32 or 128 when no appropriate on-link address
// prefix found.
//
// NOTE: This is pretty naive implementation that contains many
// allocations and non-effective linear search, and should not be used
// freely.
func addrPrefixLen(pfxs []IPNet, ip IP) int {
var l int
var cand *IPNet
for i := range pfxs {
if !pfxs[i].Contains(ip) {
continue
}
if cand == nil {
l, _ = pfxs[i].Mask.Size()
cand = &pfxs[i]
continue
}
m, _ := pfxs[i].Mask.Size()
if m > l {
l = m
cand = &pfxs[i]
continue
}
}
if l > 0 {
return l
}
if ip.To4() != nil {
return 8 * IPv4len
}
return 8 * IPv6len
}
net: fix slow network interface manipulations This CL reduces unnecessary network facility lookups introduced by recent changes below. changeset: 15798:53a4da6a4f4a net: return correct point-to-point interface address on linux changeset: 15799:a81ef8e0cc05 net: set up IPv6 scoped addressing zone for network facilities Also adds a test case for issue 4839. Benchmark results on linux/amd64, virtual machine: benchmark old ns/op new ns/op delta BenchmarkInterfaces-2 80487 80382 -0.13% BenchmarkInterfaceByIndex-2 72013 71391 -0.86% BenchmarkInterfaceByName-2 79865 80101 +0.30% BenchmarkInterfaceAddrs-2 42071 829677 +1872.09% BenchmarkInterfacesAndAddrs-2 35016 607622 +1635.27% BenchmarkInterfacesAndMulticastAddrs-2 169849 169082 -0.45% old: 15797:9c3930413c1b, new: tip Benchmark results on linux/amd64, virtual machine: benchmark old ns/op new ns/op delta BenchmarkInterfaces-2 80487 81459 +1.21% BenchmarkInterfaceByIndex-2 72013 71512 -0.70% BenchmarkInterfaceByName-2 79865 80567 +0.88% BenchmarkInterfaceAddrs-2 42071 120108 +185.49% BenchmarkInterfacesAndAddrs-2 35016 33259 -5.02% BenchmarkInterfacesAndMulticastAddrs-2 169849 82391 -51.49% old: 15797:9c3930413c1b, new: tip+CL7400055 Benchmark results on darwin/amd64: benchmark old ns/op new ns/op delta BenchmarkInterfaces-2 34402 34231 -0.50% BenchmarkInterfaceByIndex-2 13192 12956 -1.79% BenchmarkInterfaceByName-2 34791 34388 -1.16% BenchmarkInterfaceAddrs-2 36565 63906 +74.77% BenchmarkInterfacesAndAddrs-2 17497 31068 +77.56% BenchmarkInterfacesAndMulticastAddrs-2 25276 66711 +163.93% old: 15797:9c3930413c1b, new: tip Benchmark results on darwin/amd64: benchmark old ns/op new ns/op delta BenchmarkInterfaces-2 34402 31854 -7.41% BenchmarkInterfaceByIndex-2 13192 12950 -1.83% BenchmarkInterfaceByName-2 34791 31926 -8.23% BenchmarkInterfaceAddrs-2 36565 42144 +15.26% BenchmarkInterfacesAndAddrs-2 17497 17329 -0.96% BenchmarkInterfacesAndMulticastAddrs-2 25276 24870 -1.61% old: 15797:9c3930413c1b, new: tip+CL7400055 Update #4234. Fixes #4839 (again). Fixes #4866. R=golang-dev, fullung CC=golang-dev https://golang.org/cl/7400055
2013-02-27 22:58:41 -07:00
// interfaceMulticastAddrTable returns addresses for a specific
// interface.
func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) {
net, internal/syscall/windows: fix interface and address identification on windows The current implementation including Go 1.5 through 1.5.2 misuses Windows API and mishandles the returned values from GetAdapterAddresses on Windows. This change fixes various issues related to network facility information by readjusting interface and interface address parsers. Updates #5395. Updates #10530. Updates #12301. Updates #12551. Updates #13542. Fixes #12691. Fixes #12811. Fixes #13476. Fixes #13544. Also fixes fragile screen scraping test cases in net_windows_test.go. Additional information for reviewers: It seems like almost all the issues above have the same root cause and it is misunderstanding of Windows API. If my interpretation of the information on MSDN is correctly, current implementation contains the following bugs: - SIO_GET_INTERFACE_LIST should not be used for IPv6. The behavior of SIO_GET_INTERFACE_LIST is different on kernels and probably it doesn't work correctly for IPv6 on old kernels such as Windows XP w/ SP2. Unfortunately MSDN doesn't describe the detail of SIO_GET_INTERFACE_LIST, but information on the net suggests so. - Fetching IP_ADAPTER_ADDRESSES structures with fixed size area may not work when using IPv6. IPv6 generates ton of interface addresses for various addressing scopes. We need to adjust the area appropriately. - PhysicalAddress field of IP_ADAPTER_ADDRESSES structure may have extra space. We cannot ignore PhysicalAddressLength field of IP_ADAPTER_ADDRESS structure. - Flags field of IP_ADAPTER_ADDRESSES structure doesn't represent any of administratively and operatinal statuses. It just represents settings for windows network adapter. - MTU field of IP_ADAPTER_ADDRESSES structure may have a uint32(-1) on 64-bit platform. We need to convert the value to interger appropriately. - IfType field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - OperStatus field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - IPv6IfIndex field of IP_ADAPTER_ADDRESSES structure is just a substitute for IfIndex field. We cannot prefer IPv6IfIndex to IfIndex. - Windows XP, 2003 server and below don't set OnLinkPrefixLength field of IP_ADAPTER_UNICAST_ADDRESS structure. We cannot rely on the field on old kernels. We can use FirstPrefix field of IP_ADAPTER_ADDRESSES structure and IP_ADAPTER_PREFIX structure instead. - Length field of IP_ADAPTER_{UNICAST,ANYCAST,MULTICAST}_ADDRESS sturecures doesn't represent an address prefix length. It just represents a socket address length. Change-Id: Icabdaf7bd1d41360a981d2dad0b830b02b584528 Reviewed-on: https://go-review.googlesource.com/17412 Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
2015-12-04 03:06:01 -07:00
aas, err := adapterAddresses()
if err != nil {
return nil, err
}
var ifat []Addr
net, internal/syscall/windows: fix interface and address identification on windows The current implementation including Go 1.5 through 1.5.2 misuses Windows API and mishandles the returned values from GetAdapterAddresses on Windows. This change fixes various issues related to network facility information by readjusting interface and interface address parsers. Updates #5395. Updates #10530. Updates #12301. Updates #12551. Updates #13542. Fixes #12691. Fixes #12811. Fixes #13476. Fixes #13544. Also fixes fragile screen scraping test cases in net_windows_test.go. Additional information for reviewers: It seems like almost all the issues above have the same root cause and it is misunderstanding of Windows API. If my interpretation of the information on MSDN is correctly, current implementation contains the following bugs: - SIO_GET_INTERFACE_LIST should not be used for IPv6. The behavior of SIO_GET_INTERFACE_LIST is different on kernels and probably it doesn't work correctly for IPv6 on old kernels such as Windows XP w/ SP2. Unfortunately MSDN doesn't describe the detail of SIO_GET_INTERFACE_LIST, but information on the net suggests so. - Fetching IP_ADAPTER_ADDRESSES structures with fixed size area may not work when using IPv6. IPv6 generates ton of interface addresses for various addressing scopes. We need to adjust the area appropriately. - PhysicalAddress field of IP_ADAPTER_ADDRESSES structure may have extra space. We cannot ignore PhysicalAddressLength field of IP_ADAPTER_ADDRESS structure. - Flags field of IP_ADAPTER_ADDRESSES structure doesn't represent any of administratively and operatinal statuses. It just represents settings for windows network adapter. - MTU field of IP_ADAPTER_ADDRESSES structure may have a uint32(-1) on 64-bit platform. We need to convert the value to interger appropriately. - IfType field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - OperStatus field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - IPv6IfIndex field of IP_ADAPTER_ADDRESSES structure is just a substitute for IfIndex field. We cannot prefer IPv6IfIndex to IfIndex. - Windows XP, 2003 server and below don't set OnLinkPrefixLength field of IP_ADAPTER_UNICAST_ADDRESS structure. We cannot rely on the field on old kernels. We can use FirstPrefix field of IP_ADAPTER_ADDRESSES structure and IP_ADAPTER_PREFIX structure instead. - Length field of IP_ADAPTER_{UNICAST,ANYCAST,MULTICAST}_ADDRESS sturecures doesn't represent an address prefix length. It just represents a socket address length. Change-Id: Icabdaf7bd1d41360a981d2dad0b830b02b584528 Reviewed-on: https://go-review.googlesource.com/17412 Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
2015-12-04 03:06:01 -07:00
for _, aa := range aas {
index := aa.IfIndex
if index == 0 { // ipv6IfIndex is a sustitute for ifIndex
index = aa.Ipv6IfIndex
}
if ifi == nil || ifi.Index == int(index) {
net, internal/syscall/windows: fix interface and address identification on windows The current implementation including Go 1.5 through 1.5.2 misuses Windows API and mishandles the returned values from GetAdapterAddresses on Windows. This change fixes various issues related to network facility information by readjusting interface and interface address parsers. Updates #5395. Updates #10530. Updates #12301. Updates #12551. Updates #13542. Fixes #12691. Fixes #12811. Fixes #13476. Fixes #13544. Also fixes fragile screen scraping test cases in net_windows_test.go. Additional information for reviewers: It seems like almost all the issues above have the same root cause and it is misunderstanding of Windows API. If my interpretation of the information on MSDN is correctly, current implementation contains the following bugs: - SIO_GET_INTERFACE_LIST should not be used for IPv6. The behavior of SIO_GET_INTERFACE_LIST is different on kernels and probably it doesn't work correctly for IPv6 on old kernels such as Windows XP w/ SP2. Unfortunately MSDN doesn't describe the detail of SIO_GET_INTERFACE_LIST, but information on the net suggests so. - Fetching IP_ADAPTER_ADDRESSES structures with fixed size area may not work when using IPv6. IPv6 generates ton of interface addresses for various addressing scopes. We need to adjust the area appropriately. - PhysicalAddress field of IP_ADAPTER_ADDRESSES structure may have extra space. We cannot ignore PhysicalAddressLength field of IP_ADAPTER_ADDRESS structure. - Flags field of IP_ADAPTER_ADDRESSES structure doesn't represent any of administratively and operatinal statuses. It just represents settings for windows network adapter. - MTU field of IP_ADAPTER_ADDRESSES structure may have a uint32(-1) on 64-bit platform. We need to convert the value to interger appropriately. - IfType field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - OperStatus field of IP_ADAPTER_ADDRESSES structure is not a bit field. Bitwire operation for the field is completely wrong. - IPv6IfIndex field of IP_ADAPTER_ADDRESSES structure is just a substitute for IfIndex field. We cannot prefer IPv6IfIndex to IfIndex. - Windows XP, 2003 server and below don't set OnLinkPrefixLength field of IP_ADAPTER_UNICAST_ADDRESS structure. We cannot rely on the field on old kernels. We can use FirstPrefix field of IP_ADAPTER_ADDRESSES structure and IP_ADAPTER_PREFIX structure instead. - Length field of IP_ADAPTER_{UNICAST,ANYCAST,MULTICAST}_ADDRESS sturecures doesn't represent an address prefix length. It just represents a socket address length. Change-Id: Icabdaf7bd1d41360a981d2dad0b830b02b584528 Reviewed-on: https://go-review.googlesource.com/17412 Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
2015-12-04 03:06:01 -07:00
for pmul := aa.FirstMulticastAddress; pmul != nil; pmul = pmul.Next {
sa, err := pmul.Address.Sockaddr.Sockaddr()
if err != nil {
return nil, os.NewSyscallError("sockaddr", err)
}
switch sa := sa.(type) {
case *syscall.SockaddrInet4:
ifa := &IPAddr{IP: make(IP, IPv4len)}
copy(ifa.IP, sa.Addr[:])
ifat = append(ifat, ifa)
case *syscall.SockaddrInet6:
ifa := &IPAddr{IP: make(IP, IPv6len)}
copy(ifa.IP, sa.Addr[:])
ifat = append(ifat, ifa)
}
}
}
}
return ifat, nil
}