From e4a929de90876ff2b931b918255d01b8cd8909ac Mon Sep 17 00:00:00 2001 From: Dan Kortschak <90160302+efd6@users.noreply.github.com> Date: Thu, 7 Jul 2022 07:28:45 +0930 Subject: [PATCH] packetbeat/route: make use of newly added GetBestInterfaceEx in x/sys/windows (#32180) Also use windows.GetAdaptersAddresses and windows.IpAdapterAddresses (now complete). --- NOTICE.txt | 4 +- go.mod | 2 +- go.sum | 3 +- packetbeat/route/route_windows.go | 155 +++++------------------------- 4 files changed, 29 insertions(+), 135 deletions(-) diff --git a/NOTICE.txt b/NOTICE.txt index 1c3e40439ae..4cac97feec5 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -17431,11 +17431,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- Dependency : golang.org/x/sys -Version: v0.0.0-20220520151302-bc2c85ada10a +Version: v0.0.0-20220702020025-31831981b65f Licence type (autodetected): BSD-3-Clause -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/golang.org/x/sys@v0.0.0-20220520151302-bc2c85ada10a/LICENSE: +Contents of probable licence file $GOMODCACHE/golang.org/x/sys@v0.0.0-20220702020025-31831981b65f/LICENSE: Copyright (c) 2009 The Go Authors. All rights reserved. diff --git a/go.mod b/go.mod index e82fbf1ba3b..1dbaf310144 100644 --- a/go.mod +++ b/go.mod @@ -138,7 +138,7 @@ require ( golang.org/x/net v0.0.0-20220225172249-27dd8689420f golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 golang.org/x/sync v0.0.0-20220513210516-0976fa681c29 - golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a + golang.org/x/sys v0.0.0-20220702020025-31831981b65f golang.org/x/text v0.3.7 golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac golang.org/x/tools v0.1.9 diff --git a/go.sum b/go.sum index 9dde2b972f4..b5e579a0400 100644 --- a/go.sum +++ b/go.sum @@ -2103,8 +2103,9 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220702020025-31831981b65f h1:xdsejrW/0Wf2diT5CPp3XmKUNbr7Xvw8kYilQ+6qjRY= +golang.org/x/sys v0.0.0-20220702020025-31831981b65f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= diff --git a/packetbeat/route/route_windows.go b/packetbeat/route/route_windows.go index 1cee4895f8e..3f9755aacd8 100644 --- a/packetbeat/route/route_windows.go +++ b/packetbeat/route/route_windows.go @@ -15,70 +15,59 @@ // specific language governing permissions and limitations // under the License. -//nolint:unused,structcheck // How many ways to check for unused? (╯°□°)╯︵ ┻━┻ Fields kept for documentation. package route import ( "errors" "runtime" - "syscall" "unsafe" "golang.org/x/sys/windows" ) -var ( - // For details of the APIs used, see: - // https://docs.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getbestinterfaceex - // https://docs.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getadaptersaddresses - libiphlpapi = windows.NewLazySystemDLL("Iphlpapi.dll") - getBestInterfaceEx = libiphlpapi.NewProc("GetBestInterfaceEx") - getAdaptersAddresses = libiphlpapi.NewProc("GetAdaptersAddresses") -) - // Default returns the interface and netstat device index of the network interface // used for the first identified default route for the specified address family. // Valid values for af are syscall.AF_INET and syscall.AF_INET6. The iface name // returned will include only the GUID of the device. func Default(af int) (name string, index int, err error) { + var family windows.Sockaddr switch af { - case windows.AF_INET, windows.AF_INET6: + case windows.AF_INET: + family = &windows.SockaddrInet4{} + case windows.AF_INET6: + family = &windows.SockaddrInet6{} default: return "", -1, errors.New("invalid family") } - type sockaddr struct { - Family uint16 - _ [26]byte - } - var idx uint32 - family := &sockaddr{Family: uint16(af)} - ret, _, err := getBestInterfaceEx.Call(uintptr(unsafe.Pointer(family)), uintptr(unsafe.Pointer(&idx))) + err = windows.GetBestInterfaceEx(family, &idx) runtime.KeepAlive(family) - if ret != windows.NO_ERROR { - if syscall.Errno(ret) == windows.ERROR_NOT_FOUND { - err = ErrNotFound - } + switch err { //nolint:errorlint // These are errno errors. + case nil, windows.ERROR_SUCCESS: + case windows.ERROR_NOT_FOUND: + return "", -1, ErrNotFound + default: return "", -1, err } + var addresses *windows.IpAdapterAddresses const ( workingBufferSize = 15000 maxTries = 3 ) - var buf []byte - outBufLen := workingBufferSize + outBufLen := uint32(workingBufferSize) loop: for i := 0; i < maxTries; i++ { - buf = make([]byte, outBufLen) - ret, _, err = getAdaptersAddresses.Call(uintptr(af), 0, 0, uintptr(unsafe.Pointer(&buf[0])), uintptr(unsafe.Pointer(&outBufLen))) + buf := make([]byte, outBufLen) + addresses = (*windows.IpAdapterAddresses)(unsafe.Pointer(&buf[0])) + err = windows.GetAdaptersAddresses(uint32(af), 0, 0, addresses, &outBufLen) runtime.KeepAlive(outBufLen) - switch syscall.Errno(ret) { + switch err { //nolint:errorlint // These are errno errors. + case nil, windows.ERROR_SUCCESS: + break loop case windows.ERROR_BUFFER_OVERFLOW: continue - case windows.NO_ERROR: - break loop case windows.ERROR_NO_DATA: return "", -1, ErrNotFound default: @@ -86,113 +75,17 @@ loop: } } - addresses := (*ipAdapterAddressesLH)(unsafe.Pointer(&buf[0])) - for ; addresses != nil; addresses = addresses.next { + for ; addresses != nil; addresses = addresses.Next { switch af { case windows.AF_INET: - if addresses.ifIndex != 0 && addresses.ifIndex == idx { - return windows.BytePtrToString(addresses.adapterName), int(idx), nil + if addresses.IfIndex != 0 && addresses.IfIndex == idx { + return windows.BytePtrToString(addresses.AdapterName), int(idx), nil } case windows.AF_INET6: - if addresses.ipv6IfIndex != 0 && addresses.ipv6IfIndex == idx { - return windows.BytePtrToString(addresses.adapterName), int(idx), nil + if addresses.Ipv6IfIndex != 0 && addresses.Ipv6IfIndex == idx { + return windows.BytePtrToString(addresses.AdapterName), int(idx), nil } } } return "", -1, ErrNotFound } - -// https://docs.microsoft.com/en-us/windows/win32/api/ipexport/ns-ipexport-ip_interface_info -type ipInterfaceInfo struct { - numAdapters int32 - adapter ipAdapterIndexMap -} - -// https://docs.microsoft.com/en-us/windows/win32/api/ipexport/ns-ipexport-ip_adapter_index_map -type ipAdapterIndexMap struct { - index uint32 - name [maxAdapterName]uint16 -} - -// https://doxygen.reactos.org/d3/d8d/ipexport_8h_source.html#l00143 -const maxAdapterName = 128 - -// https://docs.microsoft.com/en-us/windows/win32/api/iptypes/ns-iptypes-ip_adapter_addresses_lh -type ipAdapterAddressesLH struct { - length uint32 - ifIndex uint32 - next *ipAdapterAddressesLH - adapterName *byte - firstUnicastAddress *windows.IpAdapterUnicastAddress - firstAnycastAddress *windows.IpAdapterAnycastAddress - firstMulticastAddress *windows.IpAdapterMulticastAddress - firstDnsServerAddress *windows.IpAdapterDnsServerAdapter - dnsSuffix *uint16 - description *uint16 - friendlyName *uint16 - physicalAddress [syscall.MAX_ADAPTER_ADDRESS_LENGTH]byte - physicalAddressLength uint32 - flags uint32 - mtu uint32 - ifType uint32 - operStatus uint32 - ipv6IfIndex uint32 - zoneIndices [16]uint32 - firstPrefix *windows.IpAdapterPrefix - transmitLinkSpeed uint64 - receiveLinkSpeed uint64 - firstWinsServerAddress *ipAdapterWinsServerAddressLH - firstGatewayAddress *ipAdapterGatewayAddressLH - ipv4Metric uint32 - ipv6Metric uint32 - luid uint64 - dhcpv4Server socketAddress - compartmentId uint32 - networkGuid guid - connectionType uint32 - tunnelType uint32 - dhcpv6Server socketAddress - dhcpv6ClientDuid [maxDHCPv6DUIDLength]byte - dhcpv6ClientDuidLength uint32 - dhcpv6Iaid uint32 - firstDnsSuffix *ipAdapterDNSSuffix -} - -// https://doxygen.reactos.org/d2/d14/iptypes_8h_source.html#l00176 -type ipAdapterWinsServerAddressLH struct { - alignment uint64 - next *ipAdapterWinsServerAddressLH - address socketAddress -} - -// https://doxygen.reactos.org/d2/d14/iptypes_8h_source.html#l00190 -type ipAdapterGatewayAddressLH struct { - alignment uint64 - next *ipAdapterGatewayAddressLH - address socketAddress -} - -// https://doxygen.reactos.org/d8/d15/scsiwmi_8h_source.html#l00050 -type guid struct { - data1 uint32 - data2 uint16 - data3 uint16 - data4 [8]byte -} - -// https://doxygen.reactos.org/d1/db0/ws2def_8h_source.html#l00374 -type socketAddress struct { - lpSockaddr int32 - iSockaddrLength int32 -} - -// https://doxygen.reactos.org/d2/d14/iptypes_8h_source.html#l00204 -type ipAdapterDNSSuffix struct { - next *ipAdapterDNSSuffix - string [maxDNSSuffixStringLength]uint16 -} - -const ( - maxDHCPv6DUIDLength = 130 // https://doxygen.reactos.org/d2/d14/iptypes_8h_source.html#l00033 - maxDNSSuffixStringLength = 256 // https://doxygen.reactos.org/d2/d14/iptypes_8h_source.html#l00034 -)