From 21c230a0f1ffe56e259c90eea57ff12c958c09fb Mon Sep 17 00:00:00 2001 From: Riccardo Re Date: Fri, 7 Feb 2020 08:29:25 +0100 Subject: [PATCH] Feature: NICs and their configurations (Windows Only) When collecting HW informations about NICs it's also very usefull to know their current configurations. Here a quick example based on my "Windows support: net" https://github.com/jaypipes/ghw/pull/157 --- net.go | 16 +++++++--- net_windows.go | 82 ++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 92 insertions(+), 6 deletions(-) diff --git a/net.go b/net.go index 3c66be7e..fbdd5e4a 100644 --- a/net.go +++ b/net.go @@ -10,6 +10,13 @@ import ( "fmt" ) +type NICConfiguration struct { + DHCPenabled bool `json:"dhcp_enabled"` + Gateway string `json:"gateway"` + IPv4 string `json:"ipv4"` + IPv6 string `json:"ipv6"` +} + type NICCapability struct { Name string `json:"name"` IsEnabled bool `json:"is_enabled"` @@ -17,10 +24,11 @@ type NICCapability struct { } type NIC struct { - Name string `json:"name"` - MacAddress string `json:"mac_address"` - IsVirtual bool `json:"is_virtual"` - Capabilities []*NICCapability `json:"capabilities"` + Name string `json:"name"` + MacAddress string `json:"mac_address"` + IsVirtual bool `json:"is_virtual"` + Capabilities []*NICCapability `json:"capabilities"` + Configurations []*NICConfiguration `json:"configurations"` // TODO(jaypipes): Add PCI field for accessing PCI device information // PCI *PCIDevice `json:"pci"` } diff --git a/net_windows.go b/net_windows.go index 1141a7d2..170ba07c 100644 --- a/net_windows.go +++ b/net_windows.go @@ -26,6 +26,39 @@ type win32NetworkAdapter struct { ServiceName string } +const wqlNetworkAdapterCnofiguration = "SELECT Caption, Description, DefaultIPGateway, DHCPEnabled, Index, InterfaceIndex, IPAddress FROM Win32_NetworkAdapterConfiguration" + +type win32NetworkAdapterConfiguration struct { + Caption string + Description string + DefaultIPGateway []string + DHCPEnabled bool + Index uint32 + InterfaceIndex uint32 + IPAddress []string +} + +const wqlIP4RouteTable = "SELECT Caption, Description, Destination, Information, InterfaceIndex, Mask, Metric1, Metric2, Metric3, Metric4, Metric5, Name, NextHop, Protocol, Status, Type FROM Win32_IP4RouteTable" + +type win32IP4RouteTable struct { + Caption string + Description string + Destination string + Information string + InterfaceIndex int32 + Mask string + Metric1 int32 + Metric2 int32 + Metric3 int32 + Metric4 int32 + Metric5 int32 + Name string + NextHop string + Protocol uint32 + Status string + Type uint32 +} + func (ctx *context) netFillInfo(info *NetworkInfo) error { // Getting info from WMI var win32NetDescriptions []win32NetworkAdapter @@ -33,11 +66,21 @@ func (ctx *context) netFillInfo(info *NetworkInfo) error { return err } - info.NICs = ctx.nics(win32NetDescriptions) + var win32NetConfigurationDescriptions []win32NetworkAdapterConfiguration + if err := wmi.Query(wqlNetworkAdapterCnofiguration, &win32NetConfigurationDescriptions); err != nil { + return err + } + + var win32IP4RouteTableDescriptions []win32IP4RouteTable + if err := wmi.Query(wqlIP4RouteTable, &win32IP4RouteTableDescriptions); err != nil { + return err + } + + info.NICs = ctx.nics(win32NetDescriptions, win32NetConfigurationDescriptions, win32IP4RouteTableDescriptions) return nil } -func (ctx *context) nics(win32NetDescriptions []win32NetworkAdapter) []*NIC { +func (ctx *context) nics(win32NetDescriptions []win32NetworkAdapter, win32NetConfigurationDescriptions []win32NetworkAdapterConfiguration, win32IP4RouteTableDescriptions []win32IP4RouteTable) []*NIC { // Converting into standard structures nics := make([]*NIC, 0) for _, nicDescription := range win32NetDescriptions { @@ -47,6 +90,29 @@ func (ctx *context) nics(win32NetDescriptions []win32NetworkAdapter) []*NIC { IsVirtual: false, Capabilities: []*NICCapability{}, } + // Building NIC configurations + for _, configDescription := range win32NetConfigurationDescriptions { + // Looking for configurations + if nicDescription.InterfaceIndex == configDescription.InterfaceIndex { + ipv4, ipv6 := ctx.netConfigIP(configDescription.IPAddress) + var configuration = &NICConfiguration{ + DHCPenabled: configDescription.DHCPEnabled, + IPv4: ipv4, + IPv6: ipv6, + } + // Looking for gateway + for _, routeDescription := range win32IP4RouteTableDescriptions { + if nicDescription.InterfaceIndex == uint32(routeDescription.InterfaceIndex) { + if routeDescription.Destination == "0.0.0.0" && routeDescription.Mask == "0.0.0.0" { + configuration.Gateway = routeDescription.NextHop + break + } + } + } + // Appending configuration to NIC configurations + nic.Configurations = append(nic.Configurations, configuration) + } + } // Appenging NIC to NICs nics = append(nics, nic) } @@ -63,3 +129,15 @@ func (ctx *context) netDeviceName(description win32NetworkAdapter) string { } return name } + +func (ctx *context) netConfigIP(IPs []string) (string, string) { + var IPv4 string + var IPv6 string + if len(IPs) > 0 { + IPv4 = IPs[0] + } + if len(IPs) > 1 { + IPv6 = IPs[1] + } + return IPv4, IPv6 +}