You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

150 lines
2.8 KiB
Go

<<<<<<< HEAD:reactor/needs_port/system/hwinfo.go
// package system uses linux commands to get hardware info for identifation
=======
// package system uses linux ip command to get hardware info from devices
>>>>>>> origin/wrapup:internal/pkg/system/hwinfo.go
package system
import (
"bytes"
"encoding/json"
"errors"
"hash/fnv"
"os/exec"
"strings"
)
var (
ErrBusNotFound = errors.New("bus not found for device")
ErrNoNetworkInterface = errors.New("no default network found")
)
var HardwareInfo = &hardwareInfo{}
type hardwareInfo struct {
MAC string
IP string
ID int
Model string
}
// NetInterfaces is a struct to unmarshal the ip command json.
type netInterfaces []network
// Networks holds relevant information for each network interface.
// Used to unmarshal ip command json.
type network struct {
Subnets []netInfo `json:"addr_info"`
Mac string `json:"address"`
Group string `json:"group"`
State string `json:"operstate"`
}
type netInfo struct {
Family string `json:"family"`
Ip string `json:"local"`
}
func getInfo() error {
var stderr, stdout bytes.Buffer
cmd := exec.Command("ip", "-j", "a")
cmd.Stdout = &stdout
cmd.Stderr = &stderr
if err := cmd.Run(); err != nil {
return err
}
var networks netInterfaces
if err := json.Unmarshal(stdout.Bytes(), &networks); err != nil {
return err
}
// loop over found networks finding first default, IPv4 network currently
// UP (active).
// Eventually need to look only at wg interface which simplifies
// implementation.
for _, network := range networks {
if network.Group == "default" && network.State == "UP" {
for _, subnet := range network.Subnets {
if subnet.Family == "inet" {
hash := fnv.New32a()
hash.Write([]byte(network.Mac))
id := hash.Sum32()
HardwareInfo.MAC = network.Mac
HardwareInfo.IP = subnet.Ip
HardwareInfo.ID = int(id)
return nil
}
}
}
}
return nil
}
func GetID() (int, error) {
if HardwareInfo.ID == 0 {
if err := getInfo(); err != nil {
return 0, err
}
}
return HardwareInfo.ID, nil
}
func GetIP() (string, error) {
if HardwareInfo.IP == "" {
if err := getInfo(); err != nil {
return "", err
}
}
return HardwareInfo.IP, nil
}
func GetModel() (string, error) {
if HardwareInfo.Model == "" {
var stderr, out bytes.Buffer
cmd := exec.Command("uname", "-n")
cmd.Stdout = &out
cmd.Stderr = &stderr
if err := cmd.Run(); err != nil {
return "", err
}
b := out.String()
HardwareInfo.Model = strings.Trim(b, " \n")
}
return HardwareInfo.Model, nil
}
func GetBus() (int, error) {
// preset busses
busList := map[string]int{"raspberrypi": 1, "beaglebone": 2}
// vars
var bus int
var ok bool
if name, err := GetModel(); err != nil {
return bus, err
} else if bus, ok = busList[name]; !ok {
return 0, ErrBusNotFound
}
return bus, nil
}