|
@@ -0,0 +1,236 @@
|
|
|
+// +build freebsd
|
|
|
+
|
|
|
+package hardwareinfo
|
|
|
+
|
|
|
+import (
|
|
|
+ "encoding/json"
|
|
|
+ "log"
|
|
|
+ "net/http"
|
|
|
+ "os/exec"
|
|
|
+ "strconv"
|
|
|
+ "strings"
|
|
|
+)
|
|
|
+
|
|
|
+/*
|
|
|
+ System Info
|
|
|
+ author: HyperXraft
|
|
|
+ date: 2021-02-18
|
|
|
+
|
|
|
+ This module get the CPU information on different platform using
|
|
|
+ native terminal commands on FreeBSD platform
|
|
|
+
|
|
|
+ DEFINITIONS
|
|
|
+ ===========
|
|
|
+ CPUModel: Refers to the Marketing name of the CPU, e.g. Intel Xeon E7 8890
|
|
|
+ CPUHardware: Refers to the CPUID name, e.g. GenuineIntel-6-3A-9
|
|
|
+ CPUArch: Refers to the ISA of the CPU, e.g. aarch64
|
|
|
+ CPUFreq: Refers to the CPU frequency in terms of gigahertz, e.g. 0.8GHz
|
|
|
+*/
|
|
|
+
|
|
|
+const UNKNOWN_STRING = "??? "
|
|
|
+const QUERY_FREQUENCY_COMMAND = "sysctl hw.model | awk '{print $NF}'"
|
|
|
+const QUERY_CPUMODEL_COMMAND = "sysctl hw.model | awk '{for(i=1;++i<=NF-3;) printf $i\" \"; print $(NF-2)}'"
|
|
|
+const QUERY_CPUARCH_COMMAND = "sysctl hw.machine_arch | awk '{print $NF}'"
|
|
|
+const QUERY_CPUHARDWARE_COMMAND = "sysctl kern.hwpmc.cpuid | awk '{print $NF}'"
|
|
|
+const QUERY_NETINFO_COMMAND = "ifconfig -a"
|
|
|
+const QUERY_USBINFO_COMMAND = "usbconfig"
|
|
|
+const QUERY_MEMSIZE_COMMAND = "sysctl hw.physmem | awk '{print $NF}'"
|
|
|
+
|
|
|
+// GetCPUFreq() -> String
|
|
|
+// Returns the CPU frequency in the terms of MHz
|
|
|
+func GetCPUFreq() string {
|
|
|
+ cmd := QUERY_FREQUENCY_COMMAND // Query CPUFreq w/ sysctl
|
|
|
+ shell := exec.Command("bash", "-c", cmd) // Run command
|
|
|
+ freqByteArr, err := shell.CombinedOutput() // Response from cmdline
|
|
|
+ if err != nil { // If done w/ errors then
|
|
|
+ log.Println(err)
|
|
|
+ return UNKNOWN_STRING
|
|
|
+ }
|
|
|
+
|
|
|
+ freqStr := strings.ReplaceAll(string(freqByteArr), "GHz", "")
|
|
|
+ freqStr = strings.ReplaceAll(freqStr, "\n", "")
|
|
|
+ freqStr = strings.ReplaceAll(freqStr, " ", "")
|
|
|
+ freqFloat, _ := strconv.ParseFloat(freqStr, 8)
|
|
|
+ freqFloat = freqFloat * 1000
|
|
|
+ freqStrMHz := strconv.FormatFloat(freqFloat, 'f', -1, 64)
|
|
|
+
|
|
|
+ return freqStrMHz
|
|
|
+}
|
|
|
+
|
|
|
+// GetCPUModel -> String
|
|
|
+// Returns the CPU model name string
|
|
|
+func GetCPUModel() string {
|
|
|
+ cmd := QUERY_CPUMODEL_COMMAND // Query CPUModel w/ sysctl
|
|
|
+ shell := exec.Command("bash", "-c", cmd) // Run command
|
|
|
+ modelStr, err := shell.CombinedOutput() // Response from cmdline
|
|
|
+ if err != nil { // If done w/ errors then
|
|
|
+ log.Println(err)
|
|
|
+ return UNKNOWN_STRING
|
|
|
+ }
|
|
|
+
|
|
|
+ return string(modelStr)
|
|
|
+}
|
|
|
+
|
|
|
+// GetCPUHardware -> String
|
|
|
+// Returns the CPU ID string
|
|
|
+func GetCPUHardware() string {
|
|
|
+ cmd := QUERY_CPUHARDWARE_COMMAND // Query CPUHW w/ sysctl
|
|
|
+ shell := exec.Command("bash", "-c", cmd) // Run command
|
|
|
+ hwStr, err := shell.CombinedOutput() // Response from cmdline
|
|
|
+ if err != nil { // If done w/ errors then
|
|
|
+ log.Println(err)
|
|
|
+ return UNKNOWN_STRING
|
|
|
+ }
|
|
|
+
|
|
|
+ return string(hwStr)
|
|
|
+}
|
|
|
+
|
|
|
+// GetCPUArch -> String
|
|
|
+// Returns the CPU architecture string
|
|
|
+func GetCPUArch() string {
|
|
|
+ cmd := QUERY_CPUARCH_COMMAND // Query CPUArch w/ sysctl
|
|
|
+ shell := exec.Command("bash", "-c", cmd) // Run command
|
|
|
+ archStr, err := shell.CombinedOutput() // Response from cmdline
|
|
|
+ if err != nil { // If done w/ errors then
|
|
|
+ log.Println(err)
|
|
|
+ return UNKNOWN_STRING
|
|
|
+ }
|
|
|
+
|
|
|
+ return string(archStr)
|
|
|
+}
|
|
|
+
|
|
|
+// Inherited code from sysinfo_window.go
|
|
|
+func GetCPUInfo(w http.ResponseWriter, r *http.Request) {
|
|
|
+ CPUInfo := CPUInfo{
|
|
|
+ Freq: GetCPUFreq(),
|
|
|
+ Hardware: GetCPUHardware(),
|
|
|
+ Instruction: GetCPUArch(),
|
|
|
+ Model: GetCPUModel(),
|
|
|
+ Revision: "unknown",
|
|
|
+ }
|
|
|
+
|
|
|
+ var jsonData []byte
|
|
|
+ jsonData, err := json.Marshal(CPUInfo)
|
|
|
+ if err != nil {
|
|
|
+ log.Println(err)
|
|
|
+ }
|
|
|
+ sendTextResponse(w, string(jsonData))
|
|
|
+}
|
|
|
+
|
|
|
+// Inherited code from sysinfo.go
|
|
|
+func Ifconfig(w http.ResponseWriter, r *http.Request) {
|
|
|
+ cmdin := QUERY_NETINFO_COMMAND
|
|
|
+ cmd := exec.Command("bash", "-c", cmdin)
|
|
|
+ networkInterfaces, err := cmd.CombinedOutput()
|
|
|
+ if err != nil {
|
|
|
+ networkInterfaces = []byte{}
|
|
|
+ }
|
|
|
+
|
|
|
+ nic := strings.Split(string(networkInterfaces), "\n")
|
|
|
+
|
|
|
+ var arr []string
|
|
|
+ for _, info := range nic {
|
|
|
+ thisInfo := string(info)
|
|
|
+ arr = append(arr, thisInfo)
|
|
|
+ }
|
|
|
+
|
|
|
+ var jsonData []byte
|
|
|
+ jsonData, err = json.Marshal(arr)
|
|
|
+ if err != nil {
|
|
|
+ log.Println(err)
|
|
|
+ }
|
|
|
+ sendTextResponse(w, string(jsonData))
|
|
|
+}
|
|
|
+
|
|
|
+// Inherited code from sysinfo.go
|
|
|
+func GetDriveStat(w http.ResponseWriter, r *http.Request) {
|
|
|
+ //Get drive status using df command
|
|
|
+ cmdin := `df -k | sed -e /Filesystem/d`
|
|
|
+ cmd := exec.Command("bash", "-c", cmdin)
|
|
|
+ dev, err := cmd.CombinedOutput()
|
|
|
+ if err != nil {
|
|
|
+ dev = []byte{}
|
|
|
+ }
|
|
|
+
|
|
|
+ drives := strings.Split(string(dev), "\n")
|
|
|
+
|
|
|
+ if len(drives) == 0 {
|
|
|
+ sendErrorResponse(w, "Invalid disk information")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ var arr []LogicalDisk
|
|
|
+ for _, driveInfo := range drives {
|
|
|
+ if driveInfo == "" {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ for strings.Contains(driveInfo, " ") {
|
|
|
+ driveInfo = strings.Replace(driveInfo, " ", " ", -1)
|
|
|
+ }
|
|
|
+ driveInfoChunk := strings.Split(driveInfo, " ")
|
|
|
+ tmp, _ := strconv.Atoi(driveInfoChunk[3])
|
|
|
+ freespaceInByte := int64(tmp)
|
|
|
+
|
|
|
+ LogicalDisk := LogicalDisk{
|
|
|
+ DriveLetter: driveInfoChunk[5],
|
|
|
+ FileSystem: driveInfoChunk[0],
|
|
|
+ FreeSpace: strconv.FormatInt(freespaceInByte*1024, 10), //df show disk space in 1KB blocks
|
|
|
+ }
|
|
|
+ arr = append(arr, LogicalDisk)
|
|
|
+ }
|
|
|
+
|
|
|
+ var jsonData []byte
|
|
|
+ jsonData, err = json.Marshal(arr)
|
|
|
+ if err != nil {
|
|
|
+ log.Println(err)
|
|
|
+ }
|
|
|
+ sendTextResponse(w, string(jsonData))
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+// GetUSB(ResponseWriter, HttpRequest) -> nil
|
|
|
+// Takes in http.ResponseWriter w and *http.Request r,
|
|
|
+// Send TextResponse containing USB information extracted from shell in JSON
|
|
|
+func GetUSB(w http.ResponseWriter, r *http.Request) {
|
|
|
+ cmdin := QUERY_USBINFO_COMMAND
|
|
|
+ cmd := exec.Command("bash", "-c", cmdin)
|
|
|
+ usbd, err := cmd.CombinedOutput()
|
|
|
+ if err != nil {
|
|
|
+ usbd = []byte{}
|
|
|
+ }
|
|
|
+
|
|
|
+ usbDrives := strings.Split(string(usbd), "\n")
|
|
|
+
|
|
|
+ var arr []string
|
|
|
+ for _, info := range usbDrives {
|
|
|
+ arr = append(arr, info)
|
|
|
+ }
|
|
|
+
|
|
|
+ var jsonData []byte
|
|
|
+ jsonData, err = json.Marshal(arr)
|
|
|
+ if err != nil {
|
|
|
+ log.Println(err)
|
|
|
+ }
|
|
|
+ sendTextResponse(w, string(jsonData))
|
|
|
+}
|
|
|
+
|
|
|
+// GetRamInfo(w ResponseWriter, r *HttpRequest) -> nil
|
|
|
+// Takes in http.ResponseWriter w and *http.Request r,
|
|
|
+// Send TextResponse containing physical memory size
|
|
|
+// extracted from shell in JSON
|
|
|
+func GetRamInfo(w http.ResponseWriter, r *http.Request) {
|
|
|
+ cmd := exec.Command("bash", "-c", QUERY_MEMSIZE_COMMAND)
|
|
|
+ out, _ := cmd.CombinedOutput()
|
|
|
+
|
|
|
+ strOut := string(out)
|
|
|
+ strOut = strings.ReplaceAll(strOut, "\n", "")
|
|
|
+ ramSize, _ := strconv.ParseInt(strOut, 10, 64)
|
|
|
+ ramSizeInt := ramSize
|
|
|
+
|
|
|
+ var jsonData []byte
|
|
|
+ jsonData, err := json.Marshal(ramSizeInt)
|
|
|
+ if err != nil {
|
|
|
+ log.Println(err)
|
|
|
+ }
|
|
|
+ sendTextResponse(w, string(jsonData))
|
|
|
+}
|