1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-08-02 11:38:30 -04:00
Files
DankMaterialShell/core/internal/server/network/detect.go
T
bbedward 90291bd627 freebsd: add initial support for running on FreeBSD, excluding Bluez,
ppd, and some things. Add a simple wpa_supplicant backend
2026-07-19 10:31:48 -04:00

110 lines
3.1 KiB
Go

package network
import (
"fmt"
"os"
"github.com/godbus/dbus/v5"
)
type BackendType int
const (
BackendNone BackendType = iota
BackendNetworkManager
BackendIwd
BackendConnMan
BackendNetworkd
BackendWpaSupplicant
)
func nameHasOwner(bus *dbus.Conn, name string) (bool, error) {
obj := bus.Object("org.freedesktop.DBus", "/org/freedesktop/DBus")
var owned bool
if err := obj.Call("org.freedesktop.DBus.NameHasOwner", 0, name).Store(&owned); err != nil {
return false, err
}
return owned, nil
}
type DetectResult struct {
Backend BackendType
HasNM bool
HasIwd bool
HasConnMan bool
HasWpaSupp bool
HasNetworkd bool
ChosenReason string
}
func wpaSupplicantCtrlDirPresent() bool {
info, err := os.Stat(wpaSupplicantCtrlDir)
return err == nil && info.IsDir()
}
func DetectNetworkStack() (*DetectResult, error) {
bus, err := dbus.ConnectSystemBus()
if err != nil {
// FreeBSD and minimal Linux systems may run wpa_supplicant with no
// system bus at all; the control directory is the only signal there.
if !wpaSupplicantCtrlDirPresent() {
return nil, fmt.Errorf("connect system bus: %w", err)
}
return &DetectResult{
Backend: BackendWpaSupplicant,
HasWpaSupp: true,
ChosenReason: "System bus unreachable; wpa_supplicant control directory present. Using wpa_ctrl interface.",
}, nil
}
defer bus.Close()
hasNM, _ := nameHasOwner(bus, "org.freedesktop.NetworkManager")
hasIwd, _ := nameHasOwner(bus, "net.connman.iwd")
hasConn, _ := nameHasOwner(bus, "net.connman")
hasWpa, _ := nameHasOwner(bus, "fi.w1.wpa_supplicant1")
hasNetworkd, _ := nameHasOwner(bus, "org.freedesktop.network1")
res := &DetectResult{
HasNM: hasNM,
HasIwd: hasIwd,
HasConnMan: hasConn,
HasWpaSupp: hasWpa,
HasNetworkd: hasNetworkd,
}
switch {
case hasNM:
res.Backend = BackendNetworkManager
if hasIwd {
res.ChosenReason = "NetworkManager present; iwd also running (likely NM's Wi-Fi backend). Using NM API."
} else {
res.ChosenReason = "NetworkManager present. Using NM API."
}
case hasConn && hasIwd:
res.Backend = BackendConnMan
res.ChosenReason = "ConnMan + iwd detected. Use ConnMan API (iwd is its Wi-Fi daemon)."
case hasIwd && hasNetworkd:
res.Backend = BackendNetworkd
res.ChosenReason = "iwd + systemd-networkd detected. Using iwd for Wi-Fi association and networkd for IP/DHCP."
case hasIwd:
res.Backend = BackendIwd
res.ChosenReason = "iwd detected without NM/ConnMan. Using iwd API."
case hasNetworkd:
res.Backend = BackendNetworkd
res.ChosenReason = "systemd-networkd detected (no NM/ConnMan). Using networkd for L3 and wired."
case wpaSupplicantCtrlDirPresent():
res.Backend = BackendWpaSupplicant
res.HasWpaSupp = true
res.ChosenReason = "No NM/ConnMan/iwd/networkd; wpa_supplicant control directory present. Using wpa_ctrl interface."
default:
res.Backend = BackendNone
if hasWpa {
res.ChosenReason = "No NM/ConnMan/iwd; wpa_supplicant D-Bus name present but control directory missing."
} else {
res.ChosenReason = "No known network manager bus names found."
}
}
return res, nil
}