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: get npcap usable windows network device names #35095

Open
acecase opened this issue Oct 23, 2019 · 5 comments
Open

net: get npcap usable windows network device names #35095

acecase opened this issue Oct 23, 2019 · 5 comments
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. OS-Windows
Milestone

Comments

@acecase
Copy link

acecase commented Oct 23, 2019

net.Interfaces(), net.InterfaceByName(), and net.InterfaceByIndex() return an Interface struct with a Name variable. On Linux, this will tend to be the name (eth0, wlan0, en0, etc) that can be passed to pcap functions/methods (eg. "github.com/google/gopacket/pcap".OpenLive() )

However, that isn't the case on Windows 10.

On my box net.InterfaceByIndex(5), for example returns a Interface.Name "Ethernet" and what I need for pcap.OpenLive() is "\Device\NPF_{13044533-0543-4AF5-9E3C-85EBBC7C04BB}"

gopacket and gopacket/pcap are really promising. ~as simple as scappy, and ~as fast as c, and I can write it once and run it on Windows and Linux. Except, not quite yet.

@agnivade agnivade changed the title Feature Request: get npcap usable windows network device names net: get npcap usable windows network device names Oct 23, 2019
@agnivade agnivade added NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. OS-Windows labels Oct 23, 2019
@agnivade agnivade added this to the Unplanned milestone Oct 23, 2019
@networkimprov
Copy link

cc @alexbrainman @mattn @zx2c4

@mattn
Copy link
Member

mattn commented Oct 23, 2019

On my box net.InterfaceByIndex(5), for example returns a Interface.Name "Ethernet" and what I need for pcap.OpenLive() is "\Device\NPF_{13044533-0543-4AF5-9E3C-85EBBC7C04BB}"

Current implementation of net package have some differences for Name field.

Linux, BSD, AIX: interface name like "eth0"
Windows: Friendly Name like "Ethernet1"
Plan9: path to the device like "/net/ipifc/1"

On Windows, the path prefiexed with \Device\NPF_ is device volume. This is not interface name.

To get device volume, you need to call SetupDiGetDeviceInterfaceDetail.

I suggest to add new field Device to be set identity of the interface.

@zx2c4
Copy link
Contributor

zx2c4 commented Oct 23, 2019

FWIW, I'll probably upstream WireGuard's Windows networking wrappers to x/sys or x/net somewhat soon. It does all the things:

https://godoc.org/golang.zx2c4.com/wireguard/windows/tunnel/winipcfg

@acecase
Copy link
Author

acecase commented Oct 23, 2019

On my box net.InterfaceByIndex(5), for example returns a Interface.Name "Ethernet" and what I need for pcap.OpenLive() is "\Device\NPF_{13044533-0543-4AF5-9E3C-85EBBC7C04BB}"

Current implementation of net package have some differences for Name field.

Linux, BSD, AIX: interface name like "eth0"
Windows: Friendly Name like "Ethernet1"
Plan9: path to the device like "/net/ipifc/1"

On Windows, the path prefiexed with \Device\NPF_ is device volume. This is not interface name.

To get device volume, you need to call SetupDiGetDeviceInterfaceDetail.

I suggest to add new field Device to be set identity of the interface.

I like this idea. If .Name was meant to be a friendly/display name, a separate .Device value that would give us what we tend to need to "act on" a device would be great. It would be good to not have to start writing "am I running in Windows" code, and there is no doubt code in production that is using this to display device names. This is a good common ground approach.

@guyharris
Copy link

Libpcap's pcap_findalldevs() API currently provides, for each device, a name value that is the name to use when opening the device and a description value that's a human-readable description of some sort.

On most UN*Xes, the description is usually non-existent.

On Windows, it's either a hardware description or something extraordinarily useful and precisely descriptive such as "Microsoft".

That needs to be redone.

Wireshark works around this by using, for its description, a string intended for human consumption, fetched by various platform-dependent mechanisms. On Windows, it fetches the "friendly name", which might be "Local Area Connection 17" or might be "Ethernet0" or whatever.

See capture/capture_win_ifnames.c in the Wireshark for an example of how to fetch the "friendly name" for an interface, given its GUID (which is the ugly blob in the name value), on Windows.

It would probably be wisest to name Name always be the name used to open it, so that it'd be "\Device\NPF_{ugly GUID blob}" on Windows. If a device has no description, as is likely to be the case on UN*Xes, using the interface name would be a workaround, for the benefit of programs that want to let the user choose from a list of names - they'd show the description and use the name corresponding to that description.

(For extra credit, get friendly names on macOS using the code in add_unix_interface_ifinfo() in in capture/capture-pcap-util.c.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. OS-Windows
Projects
None yet
Development

No branches or pull requests

6 participants