From 67b7d823bc3dce78f035629bd19d1509804b125c Mon Sep 17 00:00:00 2001 From: Sourabh Choure <36518515+saviourcode@users.noreply.github.com> Date: Fri, 2 Oct 2020 21:05:26 +0530 Subject: [PATCH 1/5] Add Get PCI Devices, Add Bold Green Color, Rename White Color --- go.mod | 1 + main.go | 22 +++++++++++++--------- memory.go | 5 ++--- network.go | 4 ++-- pci.go | 26 ++++++++++++++++++++++++++ 5 files changed, 44 insertions(+), 14 deletions(-) create mode 100644 pci.go diff --git a/go.mod b/go.mod index 1dcfccb..ad6ee47 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.14 require ( github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect github.com/go-ole/go-ole v1.2.4 // indirect + github.com/jaypipes/pcidb v0.5.0 github.com/shirou/gopsutil v2.20.8+incompatible golang.org/x/sys v0.0.0-20200929083018-4d22bbb62b3c // indirect ) diff --git a/main.go b/main.go index 767f4ac..1bf66bf 100644 --- a/main.go +++ b/main.go @@ -10,19 +10,21 @@ const ( BannerBlueColor = "\033[1;36m%s\033[0m" WarningYellowColor = "\033[1;33m%s\033[0m" ErrorRedColor = "\033[1;31m%s\033[0m" - BoldWhite = "\033[1;37m%s\033[0m" + BoldGreenColor = "\033[1;32m%s\033[0m" + BoldWhiteColor = "\033[1;37m%s\033[0m" None = "\033[0m%s\033[0m" ) var ( - showCPUInfo *bool - showCPUUsage *bool - showRAM *bool - showDisk *bool - showLocalIP *bool - showPublicIP *bool - showAll *bool - show5TopRAM *bool + showCPUInfo *bool + showCPUUsage *bool + showRAM *bool + showDisk *bool + showLocalIP *bool + showPublicIP *bool + showAll *bool + show5TopRAM *bool + showPCIDevices *bool ) func main() { @@ -34,6 +36,7 @@ func main() { showLocalIP = flag.Bool("local-ip", false, "Show local IP address") showPublicIP = flag.Bool("public-ip", false, "Show public IP address") show5TopRAM = flag.Bool("top5-ram", false, "Show top 5 process that consume the most memory") + showPCIDevices = flag.Bool("pci-devices", false, "Show all PCI Devices") showAll = flag.Bool("all", false, "Show all stats") flag.Parse() @@ -50,6 +53,7 @@ func main() { GetLocalIPAddress() GetPublicIPAddress() GetTopProcesses() + GetPCIDevices() } func printBanner() { diff --git a/memory.go b/memory.go index 953b697..0e26cb7 100644 --- a/memory.go +++ b/memory.go @@ -2,11 +2,11 @@ package main import ( "fmt" - "sort" - "runtime" "github.com/shirou/gopsutil/disk" "github.com/shirou/gopsutil/mem" "github.com/shirou/gopsutil/process" + "runtime" + "sort" ) func getReadableSize(sizeInBytes uint64) (readableSizeString string) { @@ -53,7 +53,6 @@ func GetTopProcesses() { } //Windows Compatiblilty(Leave out the System Idle Process), for more info refer #30 - if runtime.GOOS == "windows" { if processes[0].Pid == 0 { processes = processes[1:] diff --git a/network.go b/network.go index 857caed..12e2077 100644 --- a/network.go +++ b/network.go @@ -35,8 +35,8 @@ func GetLocalIPAddress() { } ResultPrinter("Local IP Address:", "") for _, networkInterface := range networkInterfaces { //Iterate over each Network Interface Card - StandardPrinter(BoldWhite, "\t["+string(networkInterface.Name)+"] "+networkInterface.HardwareAddr.String()) // Print Name and Hardware Address - interfaceAddresses, err := networkInterface.Addrs() //Get the Internet Addresses of a Network Interface + StandardPrinter(BoldWhiteColor, "\t["+string(networkInterface.Name)+"] "+networkInterface.HardwareAddr.String()) // Print Name and Hardware Address + interfaceAddresses, err := networkInterface.Addrs() //Get the Internet Addresses of a Network Interface if err == nil { for _, interfaceAddress := range interfaceAddresses { if strings.Contains(interfaceAddress.String(), ".") { //Check for IPv4 Address diff --git a/pci.go b/pci.go new file mode 100644 index 0000000..4edba9d --- /dev/null +++ b/pci.go @@ -0,0 +1,26 @@ +package main + +import ( + "github.com/jaypipes/pcidb" +) + +func GetPCIDevices() { + if *showPCIDevices { + ResultPrinter("PCI Bus Devices:", "") + pci, err := pcidb.New() + if err != nil { + StandardPrinter(ErrorRedColor, "Error getting PCI Devices Data") + panic(err) + } + + for _, deviceClass := range pci.Classes { + StandardPrinter(BoldWhiteColor, "\tDevice class: [" + string(deviceClass.Name) + "] "+ string(deviceClass.ID)) + for _, deviceSubclass := range deviceClass.Subclasses { + StandardPrinter(None, "\t\tDevice subclass:" + string(deviceSubclass.Name) + " "+ string(deviceSubclass.ID)) + for _, programmingInterface := range deviceSubclass.ProgrammingInterfaces { + StandardPrinter(BoldGreenColor, "\t\t\tProgramming interface" + string(programmingInterface.Name) + " " + string(programmingInterface.ID)) + } + } + } + } +} From f8d405c1b4d579c5c72111a62542e8c2fd770e23 Mon Sep 17 00:00:00 2001 From: Sourabh Choure <36518515+saviourcode@users.noreply.github.com> Date: Fri, 2 Oct 2020 21:33:13 +0530 Subject: [PATCH 2/5] Removing flags from network.go --- main.go | 30 ++++++++++++++++++--------- network.go | 60 +++++++++++++++++++++++++----------------------------- 2 files changed, 48 insertions(+), 42 deletions(-) diff --git a/main.go b/main.go index 1bf66bf..cd89adc 100644 --- a/main.go +++ b/main.go @@ -44,16 +44,26 @@ func main() { *showAll = true } - printBanner() - StandardPrinter(WarningYellowColor, "v1.0") - GetCpuInfo() - GetCpuUsage() - GetRamUsage() - GetDiskUsage() - GetLocalIPAddress() - GetPublicIPAddress() - GetTopProcesses() - GetPCIDevices() + var functionsWithConditions = []struct { + condition bool + function func() + }{ + {true, printBanner}, + {true, func() { StandardPrinter(WarningYellowColor, "v1.0") }}, + {*showCPUInfo, GetCpuInfo}, + {*showCPUUsage, GetCpuUsage}, + {*showRAM, GetRamUsage}, + {*showDisk, GetDiskUsage}, + {*showLocalIP, GetLocalIPAddress}, + {*showPublicIP, GetPublicIPAddress}, + {*show5TopRAM, GetTopProcesses}, + {*showPCIDevices, GetPCIDevices}, + } + for _, pair := range functionsWithConditions { + if *showAll || pair.condition { + pair.function() + } + } } func printBanner() { diff --git a/network.go b/network.go index 12e2077..6df75b2 100644 --- a/network.go +++ b/network.go @@ -8,42 +8,38 @@ import ( ) func GetPublicIPAddress() { - if *showAll || *showPublicIP { - URL := "https://api.ipify.org" //Using Third Party Service to Ping - resp, err := http.Get(URL) //Get the JSON Response - if err != nil { - StandardPrinter(ErrorRedColor, "Could not get response from "+URL) - StandardPrinter(WarningYellowColor, "Check your Internet Connection") - panic(err) //Exit upon error, below code must not be executed - } - defer resp.Body.Close() //The client must close the response body when finished with it - IP, err := ioutil.ReadAll(resp.Body) //Reading all data from a io.Reader until EOF - if err != nil { - StandardPrinter(ErrorRedColor, "Could not find IPv4 Address") - panic(err) //Exit upon error, below code must not be executed - } - ResultPrinter("Public IPv4 Address: ", string(IP)) //Cast []bByte to String and return + URL := "https://api.ipify.org" //Using Third Party Service to Ping + resp, err := http.Get(URL) //Get the JSON Response + if err != nil { + StandardPrinter(ErrorRedColor, "Could not get response from "+URL) + StandardPrinter(WarningYellowColor, "Check your Internet Connection") + panic(err) //Exit upon error, below code must not be executed + } + defer resp.Body.Close() //The client must close the response body when finished with it + IP, err := ioutil.ReadAll(resp.Body) //Reading all data from a io.Reader until EOF + if err != nil { + StandardPrinter(ErrorRedColor, "Could not find IPv4 Address") + panic(err) //Exit upon error, below code must not be executed } + ResultPrinter("Public IPv4 Address: ", string(IP)) //Cast []bByte to String and return } func GetLocalIPAddress() { - if *showAll || *showLocalIP { - networkInterfaces, err := net.Interfaces() //Get the name of all Network Interface Cards - if err != nil { //Error Handling - StandardPrinter(ErrorRedColor, "Unfortunately it is not possible to get your local IP") - panic(err) //Exit upon error, below code must not be executed - } - ResultPrinter("Local IP Address:", "") - for _, networkInterface := range networkInterfaces { //Iterate over each Network Interface Card - StandardPrinter(BoldWhiteColor, "\t["+string(networkInterface.Name)+"] "+networkInterface.HardwareAddr.String()) // Print Name and Hardware Address - interfaceAddresses, err := networkInterface.Addrs() //Get the Internet Addresses of a Network Interface - if err == nil { - for _, interfaceAddress := range interfaceAddresses { - if strings.Contains(interfaceAddress.String(), ".") { //Check for IPv4 Address - StandardPrinter(None, "\t\t"+"IPv4"+" -> "+interfaceAddress.String()) - } else if strings.Contains(interfaceAddress.String(), ":") { //Check for IPv6 Address - StandardPrinter(None, "\t\t"+"IPv6"+" -> "+interfaceAddress.String()) - } + networkInterfaces, err := net.Interfaces() //Get the name of all Network Interface Cards + if err != nil { //Error Handling + StandardPrinter(ErrorRedColor, "Unfortunately it is not possible to get your local IP") + panic(err) //Exit upon error, below code must not be executed + } + ResultPrinter("Local IP Address:", "") + for _, networkInterface := range networkInterfaces { //Iterate over each Network Interface Card + StandardPrinter(BoldWhiteColor, "\t["+string(networkInterface.Name)+"] "+networkInterface.HardwareAddr.String()) // Print Name and Hardware Address + interfaceAddresses, err := networkInterface.Addrs() //Get the Internet Addresses of a Network Interface + if err == nil { + for _, interfaceAddress := range interfaceAddresses { + if strings.Contains(interfaceAddress.String(), ".") { //Check for IPv4 Address + StandardPrinter(None, "\t\t"+"IPv4"+" -> "+interfaceAddress.String()) + } else if strings.Contains(interfaceAddress.String(), ":") { //Check for IPv6 Address + StandardPrinter(None, "\t\t"+"IPv6"+" -> "+interfaceAddress.String()) } } } From 2b463653143471a019512a45087f0ec70e147f8d Mon Sep 17 00:00:00 2001 From: Sourabh Choure <36518515+saviourcode@users.noreply.github.com> Date: Fri, 2 Oct 2020 21:37:03 +0530 Subject: [PATCH 3/5] Removed flags from pci.go --- pci.go | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/pci.go b/pci.go index 4edba9d..c99806f 100644 --- a/pci.go +++ b/pci.go @@ -5,21 +5,19 @@ import ( ) func GetPCIDevices() { - if *showPCIDevices { - ResultPrinter("PCI Bus Devices:", "") - pci, err := pcidb.New() - if err != nil { - StandardPrinter(ErrorRedColor, "Error getting PCI Devices Data") - panic(err) - } + ResultPrinter("PCI Bus Devices:", "") + pci, err := pcidb.New() + if err != nil { + StandardPrinter(ErrorRedColor, "Error getting PCI Devices Data") + panic(err) + } - for _, deviceClass := range pci.Classes { - StandardPrinter(BoldWhiteColor, "\tDevice class: [" + string(deviceClass.Name) + "] "+ string(deviceClass.ID)) - for _, deviceSubclass := range deviceClass.Subclasses { - StandardPrinter(None, "\t\tDevice subclass:" + string(deviceSubclass.Name) + " "+ string(deviceSubclass.ID)) - for _, programmingInterface := range deviceSubclass.ProgrammingInterfaces { - StandardPrinter(BoldGreenColor, "\t\t\tProgramming interface" + string(programmingInterface.Name) + " " + string(programmingInterface.ID)) - } + for _, deviceClass := range pci.Classes { + StandardPrinter(BoldWhiteColor, "\tDevice class: ["+string(deviceClass.Name)+"] "+string(deviceClass.ID)) + for _, deviceSubclass := range deviceClass.Subclasses { + StandardPrinter(None, "\t\tDevice subclass:"+string(deviceSubclass.Name)+" "+string(deviceSubclass.ID)) + for _, programmingInterface := range deviceSubclass.ProgrammingInterfaces { + StandardPrinter(BoldGreenColor, "\t\t\tProgramming interface"+string(programmingInterface.Name)+" "+string(programmingInterface.ID)) } } } From 5a7afc655a6223a5232c04d8fdc80a887c66c599 Mon Sep 17 00:00:00 2001 From: Sourabh Choure <36518515+saviourcode@users.noreply.github.com> Date: Sun, 4 Oct 2020 13:16:24 +0530 Subject: [PATCH 4/5] List PCI Devices in Windows and Linux --- go.mod | 4 ++-- main.go | 14 +++++++++++- pci.go | 60 ++++++++++++++++++++++++++++++++++++++++---------- pci_windows.go | 53 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 116 insertions(+), 15 deletions(-) create mode 100644 pci_windows.go diff --git a/go.mod b/go.mod index ad6ee47..1188237 100644 --- a/go.mod +++ b/go.mod @@ -3,9 +3,9 @@ module termiboard go 1.14 require ( - github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect + github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d github.com/go-ole/go-ole v1.2.4 // indirect - github.com/jaypipes/pcidb v0.5.0 + github.com/jaypipes/ghw v0.6.1 // indirect github.com/shirou/gopsutil v2.20.8+incompatible golang.org/x/sys v0.0.0-20200929083018-4d22bbb62b3c // indirect ) diff --git a/main.go b/main.go index cd89adc..0431332 100644 --- a/main.go +++ b/main.go @@ -57,13 +57,25 @@ func main() { {*showLocalIP, GetLocalIPAddress}, {*showPublicIP, GetPublicIPAddress}, {*show5TopRAM, GetTopProcesses}, - {*showPCIDevices, GetPCIDevices}, } for _, pair := range functionsWithConditions { if *showAll || pair.condition { pair.function() } } + + //For Function called using their flags only + var functionCallArgs = []struct { + condition bool + function func() + }{ + {*showPCIDevices, GetPCIDevices}, + } + for _, pair := range functionCallArgs { + if pair.condition { + pair.function() + } + } } func printBanner() { diff --git a/pci.go b/pci.go index c99806f..c7450af 100644 --- a/pci.go +++ b/pci.go @@ -1,24 +1,60 @@ +// +build !windows + package main import ( - "github.com/jaypipes/pcidb" + "fmt" + "os" + "text/tabwriter" + + "github.com/jaypipes/ghw" ) func GetPCIDevices() { - ResultPrinter("PCI Bus Devices:", "") - pci, err := pcidb.New() + + ResultPrinter("Host PCI devices:", "") + + //Create a Tab writer to STDout with padding of 3, space between column and Left Align column + const padding = 3 + w := tabwriter.NewWriter(os.Stdout, 0, 0, padding, ' ', 0) + //Always Flush the Tab Writer because it is line buffered + defer w.Flush() + + //TODO: Implement StandardPrinter for tabwriter + //Print Header Row of the table + fmt.Fprintln(w, "Class\tManufacturer\tName\t") + + ////TODO: Implement StandardPrinter for tabwriter + //Print Seperator for Header and Data of the table + fmt.Fprintln(w, "-----\t------------\t----\t") + + pci, err := ghw.PCI() if err != nil { - StandardPrinter(ErrorRedColor, "Error getting PCI Devices Data") - panic(err) + fmt.Printf("Error getting PCI info: %v", err) + } + + devices := pci.ListDevices() + if len(devices) == 0 { + fmt.Printf("error: could not retrieve PCI devices\n") + return } - for _, deviceClass := range pci.Classes { - StandardPrinter(BoldWhiteColor, "\tDevice class: ["+string(deviceClass.Name)+"] "+string(deviceClass.ID)) - for _, deviceSubclass := range deviceClass.Subclasses { - StandardPrinter(None, "\t\tDevice subclass:"+string(deviceSubclass.Name)+" "+string(deviceSubclass.ID)) - for _, programmingInterface := range deviceSubclass.ProgrammingInterfaces { - StandardPrinter(BoldGreenColor, "\t\t\tProgramming interface"+string(programmingInterface.Name)+" "+string(programmingInterface.ID)) - } + for _, device := range devices { + vendor := device.Vendor + vendorName := vendor.Name + if len(vendor.Name) > 20 { + //Product Name Shorten + vendorName = string([]byte(vendorName)[0:17]) + "..." } + product := device.Product + productName := product.Name + if len(product.Name) > 40 { + //Product Name Shorten + productName = string([]byte(productName)[0:37]) + "..." + } + //TODO: Implement StandardPrinter for tabwriter + //Print Data Row of the table + fmt.Fprintln(w, device.Class.Name+"\t"+vendorName+"\t"+productName+"\t") } + } diff --git a/pci_windows.go b/pci_windows.go new file mode 100644 index 0000000..7dcf239 --- /dev/null +++ b/pci_windows.go @@ -0,0 +1,53 @@ +// Reference Documentation: https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-pnpentity +package main + +import ( + "fmt" + "os" + "text/tabwriter" + + "github.com/StackExchange/wmi" +) + +//Parameters are selected such that they match with Linux Counterpart as well +type PnPEntity struct { + PNPClass string + Name string + Manufacturer string +} + +func GetPCIDevices() { + + ResultPrinter("Host PCI devices:", "") + + //Create a Tab writer to STDout with padding of 3, space between column and Left Align column + const padding = 3 + w := tabwriter.NewWriter(os.Stdout, 0, 0, padding, ' ', 0) + //Always Flush the Tab Writer because it is line buffered + defer w.Flush() + + //Create a slice for holding info about PCIDevices with PnPEntity properties + var PCIDevices []PnPEntity + //Query to select only the PCI Devices from Win32_PnPEntity + err := wmi.Query("Select * from Win32_PnPEntity where PNPDeviceID like '%PCI%'", &PCIDevices) + if err != nil { + StandardPrinter(ErrorRedColor, "Could not retrieve PCI Devices") + panic(err) + return + } + + //TODO: Implement StandardPrinter for tabwriter + //Print Header Row of the table + fmt.Fprintln(w, "Class\tManufacturer\tName\t") + + //TODO: Implement StandardPrinter for tabwriter + //Print Seperator for Header and Data of the table + fmt.Fprintln(w, "-----\t------------\t----\t") + + for _, PCIDevice := range PCIDevices { + //TODO: Implement StandardPrinter for tabwriter + //Print Data Row of the table + fmt.Fprintln(w, PCIDevice.PNPClass+"\t"+PCIDevice.Manufacturer+"\t"+PCIDevice.Name+"\t") + } + +} From b7a513dbe8a8500a386af4335160ba02780ca9a3 Mon Sep 17 00:00:00 2001 From: Sourabh Choure <36518515+saviourcode@users.noreply.github.com> Date: Sun, 4 Oct 2020 13:17:51 +0530 Subject: [PATCH 5/5] Removed Unused Green Color --- main.go | 1 - 1 file changed, 1 deletion(-) diff --git a/main.go b/main.go index 0431332..2e12e1d 100644 --- a/main.go +++ b/main.go @@ -10,7 +10,6 @@ const ( BannerBlueColor = "\033[1;36m%s\033[0m" WarningYellowColor = "\033[1;33m%s\033[0m" ErrorRedColor = "\033[1;31m%s\033[0m" - BoldGreenColor = "\033[1;32m%s\033[0m" BoldWhiteColor = "\033[1;37m%s\033[0m" None = "\033[0m%s\033[0m" )