Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net: missing interfaces on Windows #12301

Closed
AudriusButkevicius opened this issue Aug 24, 2015 · 32 comments
Closed

net: missing interfaces on Windows #12301

AudriusButkevicius opened this issue Aug 24, 2015 · 32 comments

Comments

@AudriusButkevicius
Copy link
Contributor

package main

import(
    "fmt"
    "net"
)

func main(){
    ifs, err := net.Interfaces()
    if err != nil {
        fmt.Println(err)
    }
    for _, inf := range ifs {
        x, _ := inf.Addrs()
        fmt.Printf("%#v %s", inf, x)
    }
}

In 1.4.1 returns:

net.Interface{Index:5, MTU:1500, Name:"{E36EC396-D578-48C0-82D5-F55217877570}", HardwareAddr:net.HardwareAddr{0x94, 0xde, 0x80, 0xaf, 0x4b, 0x62}, Flags:0x0} [192.168.1.70]

In 1.5 returns:

net.Interface{Index:1, MTU:4294967295, Name:"Loopback Pseudo-Interface 1", HardwareAddr:net.HardwareAddr{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, Flags:0x15} [::1/28 127.0.0.1/16]

Any code relying on net.Interfaces() breaks (for example making multicasts to all interfaces, since Windows by default multicasts to some single interface)

What version of Go are you using (go version)?
go version go1.5 windows/amd64

What operating system and processor architecture are you using?
Windows 8.1 x64

What did you do?
Called net.Interfaces()

What did you expect to see?
My one external interface

What did you see instead?
My one loopback interface

ipconfig /all

c:\Go\src\net>ipconfig /all

Windows IP Configuration

   Host Name . . . . . . . . . . . . : Audrius
   Primary Dns Suffix  . . . . . . . :
   Node Type . . . . . . . . . . . . : Hybrid
   IP Routing Enabled. . . . . . . . : No
   WINS Proxy Enabled. . . . . . . . : No
   DNS Suffix Search List. . . . . . : lan

Ethernet adapter Ethernet 5:

   Connection-specific DNS Suffix  . : lan
   Description . . . . . . . . . . . : Hyper-V Virtual Ethernet Adapter #2
   Physical Address. . . . . . . . . : 94-DE-80-AF-4B-62
   DHCP Enabled. . . . . . . . . . . : Yes
   Autoconfiguration Enabled . . . . : Yes
   Link-local IPv6 Address . . . . . : fe80::58d9:707e:1173:32c%5(Preferred)
   IPv4 Address. . . . . . . . . . . : 192.168.1.70(Preferred)
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Lease Obtained. . . . . . . . . . : 23 August 2015 13:46:11
   Lease Expires . . . . . . . . . . : 25 August 2015 13:46:22
   Default Gateway . . . . . . . . . : 192.168.1.254
   DHCP Server . . . . . . . . . . . : 192.168.1.254
   DHCPv6 IAID . . . . . . . . . . . : 1150606976
   DHCPv6 Client DUID. . . . . . . . : 00-01-00-01-1D-3C-8E-0C-94-DE-80-AF-4B-62
   DNS Servers . . . . . . . . . . . : fe80::9e97:26ff:fe78:cec2%5
                                       8.8.8.8
                                       4.4.8.8
   NetBIOS over Tcpip. . . . . . . . : Enabled

Tunnel adapter isatap.lan:

   Media State . . . . . . . . . . . : Media disconnected
   Connection-specific DNS Suffix  . : lan
   Description . . . . . . . . . . . : Microsoft ISATAP Adapter #4
   Physical Address. . . . . . . . . : 00-00-00-00-00-00-00-E0
   DHCP Enabled. . . . . . . . . . . : No
   Autoconfiguration Enabled . . . . : Yes

netsh interface show interface


Admin State    State          Type             Interface Name
-------------------------------------------------------------------------
Enabled        Connected      Dedicated        Ethernet 3
Enabled        Connected      Dedicated        Ethernet 5

Test output:

c:\Go\src\net>go test -v -run=Interface
=== RUN   TestInterfaces
--- PASS: TestInterfaces (0.00s)
        interface_test.go:79: "Loopback Pseudo-Interface 1": flags "up|loopback|multicast", ifindex 1, mtu 4294967295
        interface_test.go:80: hardware address "00:00:00:00:00:00:00:00"
        interface_test.go:202: interface address "::1/28"
        interface_test.go:202: interface address "127.0.0.1/16"
        interface_test.go:223: joined group address "ff02::c"
        interface_test.go:223: joined group address "239.255.255.250"
=== RUN   TestInterfaceAddrs
--- PASS: TestInterfaceAddrs (0.00s)
        interface_test.go:202: interface address "fe80::58d9:707e:1173:32c/28"
        interface_test.go:202: interface address "192.168.1.70/16"
        interface_test.go:202: interface address "::1/28"
        interface_test.go:202: interface address "127.0.0.1/16"
        interface_test.go:202: interface address "fe80::5efe:c0a8:146/28"
PASS
Socket statistical information:
(inet4, datagram, udp): opened=4, connected=0, listened=0, accepted=0, closed=4, openfailed=0, connectfailed=0, listenfailed=0, acceptfailed=0, closefailed=0

ok      net     0.124s
@AudriusButkevicius
Copy link
Contributor Author

Strangely, net.InterfaceAddrs() returns the correct addresses, though net.InterfaceByIndex() nor net.InterfaceByName() does not.

@AudriusButkevicius
Copy link
Contributor Author

Seems that it has been broken by ea22a08 by @mattn.

The problem seems to lie in getInterfaceInfos() which only returns info for the loopback adapter.
Though it's not obvious to me why that happens.

@mikioh mikioh added this to the Go1.5.1 milestone Aug 24, 2015
@mikioh
Copy link
Contributor

mikioh commented Aug 24, 2015

@AudriusButkevicius,

Please take a look at https://github.com/golang/go/blob/master/CONTRIBUTING.md and let us know your environment information. Also can you show us the output of "go test -v -run=Interface at $GOROOT/src/net" and "ipconfig? ifconfig? netsh interfaces show?" on the node? (Please anonymize IDs in the output if necessary)

@mikioh mikioh changed the title net: Interfaces() regression in 1.5 net: Interfaces, InterfaceByIndex, InterfaceByName regression in 1.5 on windows Aug 24, 2015
@AudriusButkevicius
Copy link
Contributor Author

I edited my original post.

@mikioh
Copy link
Contributor

mikioh commented Aug 25, 2015

Thanks. Just skimmed interface_windows.go and looks like the code is broken. At least about the following:

@AudriusButkevicius
Copy link
Contributor Author

Re 1, it does, because of for ; paddr != nil; paddr = paddr.Next {

In my case:
https://github.com/golang/go/blob/master/src/net/interface_windows.go#L93
chain contains 3 interfaces, but https://github.com/golang/go/blob/master/src/net/interface_windows.go#L98 contains only one info, hence interfaces get skipped at
https://github.com/golang/go/blob/master/src/net/interface_windows.go#L112

@alexbrainman
Copy link
Member

@mikioh feel free to change. I know nothing about these. Happy to test / review if you need my help.

Alex

@mikioh
Copy link
Contributor

mikioh commented Aug 25, 2015

@AudriusButkevicius,

Feel free to send a fix if you have a spare time. Unfortunately I'm not a windows user, have no windows box.

@mikioh
Copy link
Contributor

mikioh commented Aug 25, 2015

Ah... @AudriusButkevicius, after you.

@AudriusButkevicius
Copy link
Contributor Author

Well the win32 api is not clear to me, why it would return only info for a single interface, hence I am not sure what the right answer here is, hence pinging @mattn in hopes for comments.

@mattn
Copy link
Member

mattn commented Aug 25, 2015

I can reproduce. I'll look into it in later. But I don't have the old environment windowns XP 32bit that I made the change.no longer. Currently, I'm on windows 64bit.

@AudriusButkevicius
Copy link
Contributor Author

Well for me I can reproduce on win8.1 x64, so shouldn't be a problem.

@mattn
Copy link
Member

mattn commented Aug 25, 2015

Hmm, I'm trying this on another 64bit windows. But test are passed. I'm confusing.

@rsc
Copy link
Contributor

rsc commented Aug 25, 2015

Why did this change from 1.4?

@AudriusButkevicius
Copy link
Contributor Author

So tests are passing on my machine too, but they are not testing against ipconfig for example. So the output the tests produce is just wrong. As you can see in my case it only returns loopback addresses, though I have an 192 ip address too.

@alexbrainman
Copy link
Member

Why did this change from 1.4?

http://golang.org/cl/3024

I don't understand most details. We just tried to make tests pass.

Alex

@mikioh
Copy link
Contributor

mikioh commented Aug 27, 2015

@mattn,

If you have no spare time for now, I'll take a look a bit this weekend.

Why did this change from 1.4?

Old windows APIs used in the previous versions don't support IPv6 entirely.

@mattn
Copy link
Member

mattn commented Aug 28, 2015

Old windows APIs used in the previous versions don't support IPv6 entirely.

Yes, And some APIs doesn't support wide character set.

If you have no spare time for now, I'll take a look a bit this weekend.

Do it please. But I'll look if it possible.

@ianlancetaylor ianlancetaylor modified the milestones: Go1.5.2, Go1.5.1 Sep 8, 2015
@0086
Copy link

0086 commented Sep 14, 2015

The function getInterfaceInfos() in "src/net/interface_windows.go" return a incorrect slice,

return iia[:iilen-1], nil

This line code should be

return iia[:iilen], nil

@gopherbot
Copy link

CL https://golang.org/cl/14574 mentions this issue.

@AudriusButkevicius
Copy link
Contributor Author

I'll test this later tonight.

@AudriusButkevicius
Copy link
Contributor Author

👍 this fixes it.
So sad that it has missed 1.5.1

@calmh
Copy link
Contributor

calmh commented Sep 14, 2015

❤️ Thank you.

@mattn
Copy link
Member

mattn commented Sep 14, 2015

@AudriusButkevicius sorry and sad :(

@gopherbot
Copy link

CL https://golang.org/cl/14747 mentions this issue.

@AudriusButkevicius
Copy link
Contributor Author

I see this hasn't been closed yet, though the changeset looked complete. Any issues along the way?

I really hope this makes it for 1.5.2.

@alexbrainman
Copy link
Member

see this hasn't been closed yet, though the changeset looked complete. Any issues along the way?

CL https://golang.org/cl/14747 needs a test that won't let us break that code again. Also @mikioh proposed an alternative solution https://go-review.googlesource.com/#/c/14747/

Alex

@AudriusButkevicius
Copy link
Contributor Author

Any way I can help you guys (@mikioh, @mattn) to get this fixed? I don't want to miss the 1.5.2 train.

@gopherbot
Copy link

CL https://golang.org/cl/16751 mentions this issue.

@rsc
Copy link
Contributor

rsc commented Nov 13, 2015

OK for Go 1.5.2.

@rsc rsc changed the title net: Interfaces, InterfaceByIndex, InterfaceByName regression in 1.5 on windows net: missing interfaces on Windows Nov 13, 2015
@gopherbot
Copy link

CL https://golang.org/cl/16984 mentions this issue.

alexbrainman added a commit that referenced this issue Nov 17, 2015
…faces on windows

Fixes #12301

Change-Id: I8d01ec9551c6cff7e6129e06a7deb36a3be9de41
Reviewed-on: https://go-review.googlesource.com/16751
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-on: https://go-review.googlesource.com/16984
Run-TryBot: Austin Clements <austin@google.com>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Reviewed-by: Russ Cox <rsc@golang.org>
@gopherbot
Copy link

CL https://golang.org/cl/17412 mentions this issue.

mikioh pushed a commit that referenced this issue Dec 10, 2015
…on 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>
@mikioh mikioh modified the milestones: Go1.6, Go1.5.2 Feb 3, 2016
@golang golang locked and limited conversation to collaborators Feb 3, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

9 participants