wifx / gonetworkmanager Goto Github PK
View Code? Open in Web Editor NEWThis project forked from bellerophonmobile/gonetworkmanager
Go D-Bus bindings for NetworkManager
License: Other
This project forked from bellerophonmobile/gonetworkmanager
Go D-Bus bindings for NetworkManager
License: Other
Device.Reapply
should accept ConnectionSettings
, not Connection
.
I'm currently working with this library to manage the connections on my Raspberry.
I'm able to add and activate a connection with no problem.
However, eventhough I'm able to update some fields of the connection previously created like id, route-metric, etc. I can't seem to set new "ipv4.routes".
I have tried updating "routes" and "route-data" but none of them had any effect on my connection.
Am I missing something? Is there any other property I need to change in order to be able to set the routes?
Thank you in advance
How to get notified about coming and going connections? (e.g., Ethernet cable was plugged in or unplugged)
The GetConnectionByUuid method appears not be implemented yet.
As a workaround I wrote:
func getConnection(wantedUUID string) (gonetworkmanager.Connection, error) {
settings, err := gonetworkmanager.NewSettings()
if err != nil {
return nil, fmt.Errorf("NewSettings failed: %v", err)
}
connections, err := settings.ListConnections()
for _, c := range connections {
settings, err := c.GetSettings()
if err != nil {
return nil, fmt.Errorf("GetSettings failed: %v", err)
}
uuid, ok := settings["connection"]["uuid"].(string)
if !ok {
return nil, fmt.Errorf("got data of type %T, but wanted string", uuid)
}
if uuid == wantedUUID {
return c, nil
}
}
return nil, fmt.Errorf("connection with uuid: %s not found, exiting", wantedUUID)
}
Hello!
There are a lot of getters for almost all properties of NetworkManager. But there are almost no setters.
In my case i would need the property to set a device managed or unmanaged.
Is this a design decision to not include setters or simply a lack of time?
Would you take pull requests if i provide the patches in the latter case?
Greetings
I'm trying to change the SSID for a connection and have written the following code:
func setSSID(conn gonetworkmanager.Connection, ssid string) error {
settings, err := conn.GetSettings()
if err != nil {
return fmt.Errorf("GetSettings failed: %v", err)
}
for k1, v1 := range settings {
for k2, v2 := range v1 {
log.Printf("[\"%s\"][\"%s\"] = \"%T\", \"%v\"", k1, k2, v2, v2)
}
}
settings["802-11-wireless"]["ssid"] = []byte(ssid)
// TODO: determine why these keys don't round trip correctly.
delete(settings["ipv6"], "addresses")
delete(settings["ipv6"], "routes")
err = conn.Update(settings)
if err != nil {
return fmt.Errorf("Update failed: %v", err)
}
return nil
}
If I remove the two lines marked TODO
I get this failure:
2020/06/28 15:07:16 Update failed: ipv6.addresses: can't set property of type 'a(ayuay)' from value of type 'aav'
or this failure:
2020/06/28 15:19:39 Update failed: ipv6.routes: can't set property of type 'a(ayuayu)' from value of type 'aav'
The output from the program is:
2020/06/28 16:36:16 ["802-11-wireless-security"]["proto"] = "[]string", "[rsn]"
2020/06/28 16:36:16 ["802-11-wireless-security"]["group"] = "[]string", "[ccmp]"
2020/06/28 16:36:16 ["802-11-wireless-security"]["key-mgmt"] = "string", "wpa-psk"
2020/06/28 16:36:16 ["802-11-wireless-security"]["pairwise"] = "[]string", "[ccmp]"
2020/06/28 16:36:16 ["ipv4"]["address-data"] = "[]map[string]dbus.Variant", "[]"
2020/06/28 16:36:16 ["ipv4"]["addresses"] = "[][]uint32", "[]"
2020/06/28 16:36:16 ["ipv4"]["dns"] = "[]uint32", "[]"
2020/06/28 16:36:16 ["ipv4"]["dns-search"] = "[]string", "[]"
2020/06/28 16:36:16 ["ipv4"]["method"] = "string", "shared"
2020/06/28 16:36:16 ["ipv4"]["route-data"] = "[]map[string]dbus.Variant", "[]"
2020/06/28 16:36:16 ["ipv4"]["routes"] = "[][]uint32", "[]"
2020/06/28 16:36:16 ["ipv6"]["address-data"] = "[]map[string]dbus.Variant", "[]"
2020/06/28 16:36:16 ["ipv6"]["addresses"] = "[][]interface {}", "[]"
2020/06/28 16:36:16 ["ipv6"]["dns"] = "[][]uint8", "[]"
2020/06/28 16:36:16 ["ipv6"]["dns-search"] = "[]string", "[]"
2020/06/28 16:36:16 ["ipv6"]["method"] = "string", "ignore"
2020/06/28 16:36:16 ["ipv6"]["route-data"] = "[]map[string]dbus.Variant", "[]"
2020/06/28 16:36:16 ["ipv6"]["routes"] = "[][]interface {}", "[]"
2020/06/28 16:36:16 ["connection"]["timestamp"] = "uint64", "1593362134"
2020/06/28 16:36:16 ["connection"]["uuid"] = "string", "833d47c1-fb7f-4dc8-9a73-51fc4337deb3"
2020/06/28 16:36:16 ["connection"]["type"] = "string", "802-11-wireless"
2020/06/28 16:36:16 ["connection"]["id"] = "string", "Hotspot"
2020/06/28 16:36:16 ["connection"]["permissions"] = "[]string", "[]"
2020/06/28 16:36:16 ["802-11-wireless"]["seen-bssids"] = "[]string", "[DC:A6:32:81:8C:72]"
2020/06/28 16:36:16 ["802-11-wireless"]["ssid"] = "[]uint8", "[84 69 77 83 45 67 84 82 76 45 72 85 66 45 66 65 76 69 78 65]"
2020/06/28 16:36:16 ["802-11-wireless"]["mac-address-blacklist"] = "[]string", "[]"
2020/06/28 16:36:16 ["802-11-wireless"]["mode"] = "string", "ap"
2020/06/28 16:36:16 ["802-11-wireless"]["security"] = "string", "802-11-wireless-security"
Looking at the documentation it appears ["ipv6"]["addresses"]
and ["ipv6"]["routes"]
are both marked Deprecated
.
I'm not familiar with the code, but I suspect a bug somewhere.
{
conn := map[string]map[string]interface{}{
"802-11-wireless": map[string]interface{}{
"ssid": "HELLO",
"mode": []string{"s", "ap"},
"security": "802-11-wireless-security",
},
"802-11-wireless-security": map[string]interface{}{
"psk": "HELLO",
"key-mgmt": []string{"s", "wpa-psk"},
},
}
var ap gnm.AccessPoint
if ap, err = gnm.NewAccessPoint(gnm.NetworkManagerObjectPath + "/AccessPoint/0"); err != nil {
return fmt.Errorf(LP+"Could not make access point: %v", err)
}
var activeConn gnm.ActiveConnection
if activeConn, err = nm.AddAndActivateWirelessConnection(conn, device, ap); err != nil {
return fmt.Errorf(LP+"Could not make access point: %v", err)
}
log.Infof(LP+"New Access Point: %s", activeConn.GetPath())
}
yields...
{"level":"info","msg":"WIFI Manager: Found the following network devices...","time":"2022-05-02T15:05:13-07:00"}
{"level":"info","msg":"WIFI Manager: lo - /org/freedesktop/NetworkManager/Devices/1","time":"2022-05-02T15:05:13-07:00"}
{"level":"info","msg":"WIFI Manager: eth0 - /org/freedesktop/NetworkManager/Devices/2","time":"2022-05-02T15:05:13-07:00"}
{"level":"info","msg":"WIFI Manager: wlan0 - /org/freedesktop/NetworkManager/Devices/3","time":"2022-05-02T15:05:13-07:00"}
{"level":"info","msg":"WIFI Manager: p2p-dev-wlan0 - /org/freedesktop/NetworkManager/Devices/4","time":"2022-05-02T15:05:13-07:00"}
2022-05-02T15:05:14-07:00 error layer=debugger error loading binary "/lib/aarch64-linux-gnu/libc.so.6": could not parse .eh_frame section: pointer encoding not supported 0x9b at 0x5a24
{"level":"fatal","msg":"WIFI Manager: Could not make access point: The access point /org/freedesktop/NetworkManager/AccessPoint/0 was not in the scan list.","time":"2022-05-02T15:05:20-07:00"}
Process 23015 has exited with status 1
Hello!
I have been playing around with your library and think it's quite nice, as i need similar functionality.
I did, however run into a problem: When calling GetSettings()
on the Connection object:
I do get the error
wire format error: variant signature is empty
After i get the error the dbus connection also seems to be flawed.
disclaimer: I'm using NetworkManager 1.20.0
All other functions are working fine.
I don't think the dbus interface changed from nm 1.16 to 1.20, so it should be able to parse the dbus response
Any idea on this?
Checkpoints are created for all devices:
nm, _ := gnm.NewNetworkManager()
device, _ := nm.GetDeviceByIpIface("wlp0s20f3")
newCheckpoint, _ := nm.CheckpointCreate([]gnm.Device{device}, 3, 0)
devices, _ := newCheckpoint.GetPropertyDevices()
ifaces := make([]string, len(devices))
for _, device := range devices {
iface, _ := device.GetPropertyInterface()
ifaces = append(ifaces, iface)
}
fmt.Println(newCheckpoint.GetPath(), ifaces)
Expected output:
/org/freedesktop/NetworkManager/Checkpoint/1 [wlp0s20f3]
Actual output:
/org/freedesktop/NetworkManager/Checkpoint/20 [ lo docker0 enp0s31f6 vethdba3724 wlp0s20f3 p2p-dev-wlp0s20f3 tun0]
Hi there!
So far the the gonetworkmanager works fine from my side!
I encounter 1 problem.
I want to have the SSID from my activeConnection
I tried the following:
nm, err :=gonetworkmanager.NewNetworkManager()
if err != nil {
fmt.Println("Could not create networkManager instance:")
fmt.Println(err.Error())
}
activeConnections, err := nm.GetPropertyActiveConnections()
if err != nil {
fmt.Println("Could not create activeConnections instance:")
fmt.Println(err.Error())
}
for _, activeConnection := range activeConnections {
accessPoint, err := activeConnection.GetPropertySpecificObject()
if err != nil {
fmt.Println("Could not create access point instance:")
fmt.Println(err.Error())
}
ssid, err := accessPoint.GetPropertySSID()
if err != nil {
fmt.Println("typeOf---")
fmt.Println(reflect.TypeOf(accessPoint))
fmt.Println("---")
fmt.Println("Could not access the ssid:")
fmt.Println(err.Error())
}
}
This outputs:
typeOf---
*gonetworkmanager.accessPoint
---
Could not access the ssid:
No such interface “org.freedesktop.DBus.Properties” on object at path /org/freedesktop/NetworkManager/AccessPoint/3
What Do I miss?
Thanks alot!
The NetworkManager.PrimaryConnect
property contains:
The object path of the "primary" active connection being used to access the network.
However the NetworkManager.GetPropertyPrimaryConnection
binding is:
GetPropertyPrimaryConnection() (Connection, error)
Which is incorrect, it should be ActiveConnection
I believe.
package main
import (
"fmt"
nm "github.com/Wifx/gonetworkmanager"
)
func main() {
// https://pkg.go.dev/github.com/Wifx/gonetworkmanager#NetworkManager
nmManager, err := nm.NewNetworkManager()
if err != nil {
panic(err)
}
// Returns https://pkg.go.dev/github.com/Wifx/gonetworkmanager#Connection
p, err := nmManager.GetPropertyPrimaryConnection()
if err != nil {
panic(err)
}
// This fails with "No such interface" because the underlying object is an "ActiveConnection" but we try to treat it as a "Connection"
if s, err := p.GetSettings(); err != nil {
// No such interface “org.freedesktop.NetworkManager.Settings.Connection” on object at path /org/freedesktop/NetworkManager/ActiveConnection/330
fmt.Printf("GetSettings: %v\n", err)
} else {
fmt.Printf("GetSettings: settings has %d keys\n", len(s))
}
// Convert to a https://pkg.go.dev/github.com/Wifx/gonetworkmanager#ActiveConnection
ac, err := nm.NewActiveConnection(p.GetPath())
if err != nil {
panic(err)
}
if t, err := ac.GetPropertyType(); err != nil {
panic(err)
} else {
fmt.Printf("GetPropertyType: %v\n", t)
}
p, err = ac.GetPropertyConnection()
if err != nil {
panic(err)
}
if s, err := p.GetSettings(); err != nil {
// No such interface “org.freedesktop.NetworkManager.Settings.Connection” on object at path /org/freedesktop/NetworkManager/ActiveConnection/330
fmt.Printf("GetSettings: %v\n", err)
} else {
fmt.Printf("GetSettings: settings has %d keys\n", len(s))
}
}
The output is:
$ go run ./
GetSettings: No such interface “org.freedesktop.NetworkManager.Settings.Connection” on object at path /org/freedesktop/NetworkManager/ActiveConnection/330
GetPropertyType: 802-3-ethernet
GetSettings: settings has 5 keys
The first p.GetSettings()
(line 23) fails with "No such interface" but after conversion to a ActiveConnection
methods work and we can then obtain an actual connection from it and the second p.GetSettings()
(line 47) on the right object type works.
go.mod
and all source files should be updated to point to dbus/v5
I want to know how to configure IPv6 addresses, but the example provided only has methods for configuring IPv4 addresses. Could you please show how to configure IPv6 addresses?
How do you update ConnectionSettings? I want to be able to update the IPV4 address-data, but I do not see any way of doing it other than recreating the ConnectingSettings Map.
activeDevConn, _ := device.GetPropertyActiveConnection()
conn, _ := activeDevConn.GetPropertyConnection()
settings, _ := conn.GetSettings()
// If I simply write back the config obtained by the GetSettings method, the following error is called when calling conn.Update()
err := conn.Update(settings)
fmt.Println(err.Error())
//ipv6.addresses: can't set property of type 'a(ayuay)' from value of type 'aav'
My guess is we need to call the DbusVariant method? Any ideas?
The C library has a bunch of #define
s for keys used in various maps. e.g. from nm-setting-wireless.h
:
#define NM_SETTING_WIRELESS_SETTING_NAME "802-11-wireless"
...
#define NM_SETTING_WIRELESS_SSID "ssid"
#define NM_SETTING_WIRELESS_MODE "mode"
#define NM_SETTING_WIRELESS_BAND "band"
#define NM_SETTING_WIRELESS_CHANNEL "channel"
#define NM_SETTING_WIRELESS_BSSID "bssid"
Could these bindings define a similar set of Go const
s to reduce the possibility of typos? Or would specific getter methods be more appropriate?
There are also various defines and enums etc for values, such as:
#define NM_SETTING_WIRELESS_MODE_ADHOC "adhoc"
....
typedef enum { /*< flags >*/
NM_SETTING_WIRELESS_WAKE_ON_WLAN_NONE = 0, /*< skip >*/
NM_SETTING_WIRELESS_WAKE_ON_WLAN_ANY = 0x2,
NM_SETTING_WIRELESS_WAKE_ON_WLAN_DISCONNECT = 0x4,
NM_SETTING_WIRELESS_WAKE_ON_WLAN_MAGIC = 0x8,
...
} NMSettingWirelessWakeOnWLan;
There are lots of nm-setting-*.h
though and it would be a lot to maintain all of them, but perhaps ad-hoc/as needed coverage could be acceptable?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.