Initial commit with not a whole lot of coverage.

This commit is contained in:
Tom Wambold 2016-05-24 20:58:18 -04:00
commit 75591bce97
17 changed files with 724 additions and 0 deletions

29
AccessPoint.go Normal file
View file

@ -0,0 +1,29 @@
package gonetworkmanager
import (
"github.com/godbus/dbus"
)
const (
AccessPointInterface = NetworkManagerInterface + ".AccessPoint"
AccessPointPropertySSID = AccessPointInterface + ".Ssid"
)
type AccessPoint interface {
// GetSSID returns the Service Set Identifier identifying the access point.
GetSSID() string
}
func NewAccessPoint(objectPath dbus.ObjectPath) (AccessPoint, error) {
var a accessPoint
return &a, a.init(NetworkManagerInterface, objectPath)
}
type accessPoint struct {
dbusBase
}
func (a *accessPoint) GetSSID() string {
return string(a.getSliceByteProperty(AccessPointPropertySSID))
}

4
ActiveConnection.go Normal file
View file

@ -0,0 +1,4 @@
package gonetworkmanager
type ActiveConnection interface {
}

48
Connection.go Normal file
View file

@ -0,0 +1,48 @@
package gonetworkmanager
import (
"github.com/godbus/dbus"
)
const (
ConnectionInterface = SettingsInterface + ".Connection"
ConnectionGetSettings = ConnectionInterface + ".GetSettings"
)
//type ConnectionSettings map[string]map[string]interface{}
type ConnectionSettings map[string]map[string]interface{}
type Connection interface {
// GetSettings gets the settings maps describing this network configuration.
// This will never include any secrets required for connection to the
// network, as those are often protected. Secrets must be requested
// separately using the GetSecrets() call.
GetSettings() ConnectionSettings
}
func NewConnection(objectPath dbus.ObjectPath) (Connection, error) {
var c connection
return &c, c.init(NetworkManagerInterface, objectPath)
}
type connection struct {
dbusBase
}
func (c *connection) GetSettings() ConnectionSettings {
var settings map[string]map[string]dbus.Variant
c.call(&settings, ConnectionGetSettings)
rv := make(ConnectionSettings)
for k1, v1 := range settings {
rv[k1] = make(map[string]interface{})
for k2, v2 := range v1 {
rv[k1][k2] = v2.Value()
}
}
return rv
}

101
Device.go Normal file
View file

@ -0,0 +1,101 @@
package gonetworkmanager
import (
"github.com/godbus/dbus"
)
const (
DeviceInterface = NetworkManagerInterface + ".Device"
DevicePropertyInterface = DeviceInterface + ".Interface"
DevicePropertyState = DeviceInterface + ".State"
DevicePropertyIP4Config = DeviceInterface + ".Ip4Config"
DevicePropertyDeviceType = DeviceInterface + ".DeviceType"
DevicePropertyAvailableConnections = DeviceInterface + ".AvailableConnections"
)
func DeviceFactory(objectPath dbus.ObjectPath) (Device, error) {
d, err := NewDevice(objectPath)
if err != nil {
return nil, err
}
switch d.GetDeviceType() {
case NmDeviceTypeWifi:
return NewWirelessDevice(objectPath)
}
return d, nil
}
type Device interface {
// GetInterface gets the name of the device's control (and often data)
// interface.
GetInterface() string
// GetState gets the current state of the device.
GetState() NmDeviceState
// GetIP4Config gets the Ip4Config object describing the configuration of the
// device. Only valid when the device is in the NM_DEVICE_STATE_ACTIVATED
// state.
GetIP4Config() IP4Config
// GetDeviceType gets the general type of the network device; ie Ethernet,
// WiFi, etc.
GetDeviceType() NmDeviceType
// GetAvailableConnections gets an array of object paths of every configured
// connection that is currently 'available' through this device.
GetAvailableConnections() []Connection
}
func NewDevice(objectPath dbus.ObjectPath) (Device, error) {
var d device
return &d, d.init(NetworkManagerInterface, objectPath)
}
type device struct {
dbusBase
}
func (d *device) GetInterface() string {
return d.getStringProperty(DevicePropertyInterface)
}
func (d *device) GetState() NmDeviceState {
return NmDeviceState(d.getUint32Property(DevicePropertyState))
}
func (d *device) GetIP4Config() IP4Config {
path := d.getObjectProperty(DevicePropertyIP4Config)
if path == "/" {
return nil
}
cfg, err := NewIP4Config(path)
if err != nil {
panic(err)
}
return cfg
}
func (d *device) GetDeviceType() NmDeviceType {
return NmDeviceType(d.getUint32Property(DevicePropertyDeviceType))
}
func (d *device) GetAvailableConnections() []Connection {
connPaths := d.getSliceObjectProperty(DevicePropertyAvailableConnections)
conns := make([]Connection, len(connPaths))
var err error
for i, path := range connPaths {
conns[i], err = NewConnection(path)
if err != nil {
panic(err)
}
}
return conns
}

102
IP4Config.go Normal file
View file

@ -0,0 +1,102 @@
package gonetworkmanager
import (
"github.com/godbus/dbus"
)
const (
IP4ConfigInterface = NetworkManagerInterface + ".IP4Config"
IP4ConfigPropertyAddresses = IP4ConfigInterface + ".Addresses"
IP4ConfigPropertyRoutes = IP4ConfigInterface + ".Routes"
IP4ConfigPropertyNameservers = IP4ConfigInterface + ".Nameservers"
IP4ConfigPropertyDomains = IP4ConfigInterface + ".Domains"
)
type IP4Address struct {
Address string
Prefix uint8
Gateway string
}
type IP4Route struct {
Route string
Prefix uint8
NextHop string
Metric uint8
}
type IP4Config interface {
// GetAddresses gets an array of tuples of IPv4 address/prefix/gateway. All 3
// elements of each tuple are in network byte order. Essentially: [(addr,
// prefix, gateway), (addr, prefix, gateway), ...]
GetAddresses() []IP4Address
// GetRoutes gets tuples of IPv4 route/prefix/next-hop/metric. All 4 elements
// of each tuple are in network byte order. 'route' and 'next hop' are IPv4
// addresses, while prefix and metric are simple unsigned integers.
// Essentially: [(route, prefix, next-hop, metric), (route, prefix, next-hop,
// metric), ...]
GetRoutes() []IP4Route
// GetNameservers gets the nameservers in use.
GetNameservers() []string
// GetDomains gets a list of domains this address belongs to.
GetDomains() []string
}
func NewIP4Config(objectPath dbus.ObjectPath) (IP4Config, error) {
var c ip4Config
return &c, c.init(NetworkManagerInterface, objectPath)
}
type ip4Config struct {
dbusBase
}
func (c *ip4Config) GetAddresses() []IP4Address {
addresses := c.getSliceSliceUint32Property(IP4ConfigPropertyAddresses)
ret := make([]IP4Address, len(addresses))
for i, parts := range addresses {
ret[i] = IP4Address{
Address: ip4ToString(parts[0]),
Prefix: uint8(parts[1]),
Gateway: ip4ToString(parts[2]),
}
}
return ret
}
func (c *ip4Config) GetRoutes() []IP4Route {
routes := c.getSliceSliceUint32Property(IP4ConfigPropertyRoutes)
ret := make([]IP4Route, len(routes))
for i, parts := range routes {
ret[i] = IP4Route{
Route: ip4ToString(parts[0]),
Prefix: uint8(parts[1]),
NextHop: ip4ToString(parts[2]),
Metric: uint8(parts[3]),
}
}
return ret
}
func (c *ip4Config) GetNameservers() []string {
nameservers := c.getSliceUint32Property(IP4ConfigPropertyNameservers)
ret := make([]string, len(nameservers))
for i, ns := range nameservers {
ret[i] = ip4ToString(ns)
}
return ret
}
func (c *ip4Config) GetDomains() []string {
return c.getSliceStringProperty(IP4ConfigPropertyDomains)
}

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 Bellerophon Mobile
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

54
NetworkManager.go Normal file
View file

@ -0,0 +1,54 @@
package gonetworkmanager
import (
"github.com/godbus/dbus"
)
const (
NetworkManagerInterface = "org.freedesktop.NetworkManager"
NetworkManagerObjectPath = "/org/freedesktop/NetworkManager"
NetworkManagerGetDevices = NetworkManagerInterface + ".GetDevices"
NetworkManagerPropertyState = NetworkManagerInterface + ".state"
)
type NetworkManager interface {
// GetDevices gets the list of network devices.
GetDevices() []Device
// GetState returns the overall networking state as determined by the
// NetworkManager daemon, based on the state of network devices under it's
// management.
GetState() NmState
}
func NewNetworkManager() (NetworkManager, error) {
var nm networkManager
return &nm, nm.init(NetworkManagerInterface, NetworkManagerObjectPath)
}
type networkManager struct {
dbusBase
}
func (n *networkManager) GetDevices() []Device {
var devicePaths []dbus.ObjectPath
n.call(&devicePaths, NetworkManagerGetDevices)
devices := make([]Device, len(devicePaths))
var err error
for i, path := range devicePaths {
devices[i], err = DeviceFactory(path)
if err != nil {
panic(err)
}
}
return devices
}
func (n *networkManager) GetState() NmState {
return NmState(n.getUint32Property(NetworkManagerPropertyState))
}

10
README.md Normal file
View file

@ -0,0 +1,10 @@
gonetworkmanager
================
Go D-Bus bindings for NetworkManager.
Currently tested with NetworkManager 0.9.8.10.
(https://godoc.org/github.com/BellerophonMobile/gonetworkmanager?status.svg)](https://godoc.org/github.com/BellerophonMobile/gonetworkmanager)
[NetworkManager 0.9 D-Bus Spec](https://developer.gnome.org/NetworkManager/0.9/spec.html)

5
Settings.go Normal file
View file

@ -0,0 +1,5 @@
package gonetworkmanager
const (
SettingsInterface = NetworkManagerInterface + ".Settings"
)

47
WirelessDevice.go Normal file
View file

@ -0,0 +1,47 @@
package gonetworkmanager
import (
"github.com/godbus/dbus"
)
const (
WirelessDeviceInterface = DeviceInterface + ".Wireless"
WirelessDeviceGetAccessPoints = WirelessDeviceInterface + ".GetAccessPoints"
)
type WirelessDevice interface {
Device
// GetAccessPoints gets the list of access points visible to this device.
// Note that this list does not include access points which hide their SSID.
// To retrieve a list of all access points (including hidden ones) use the
// GetAllAccessPoints() method.
GetAccessPoints() []AccessPoint
}
func NewWirelessDevice(objectPath dbus.ObjectPath) (WirelessDevice, error) {
var d wirelessDevice
return &d, d.init(NetworkManagerInterface, objectPath)
}
type wirelessDevice struct {
device
}
func (d *wirelessDevice) GetAccessPoints() []AccessPoint {
var apPaths []dbus.ObjectPath
d.call(&apPaths, WirelessDeviceGetAccessPoints)
aps := make([]AccessPoint, len(apPaths))
var err error
for i, path := range apPaths {
aps[i], err = NewAccessPoint(path)
if err != nil {
panic(err)
}
}
return aps
}

67
enums.go Normal file
View file

@ -0,0 +1,67 @@
package gonetworkmanager
//go:generate stringer -type=NmConnectivity
type NmConnectivity uint32
const (
NmConnectivityUnknown NmConnectivity = 0
NmConnectivityNone NmConnectivity = 1
NmConnectivityPortal NmConnectivity = 2
NmConnectivityLimited NmConnectivity = 3
NmConnectivityFull NmConnectivity = 4
)
//go:generate stringer -type=NmState
type NmState uint32
const (
NmStateUnknown NmState = 0
NmStateAsleep NmState = 10
NmStateDisconnected NmState = 20
NmStateDisconnecting NmState = 30
NmStateConnecting NmState = 40
NmStateConnectedLocal NmState = 50
NmStateConnectedSite NmState = 60
NmStateConnectedGlobal NmState = 70
)
//go:generate stringer -type=NmDeviceState
type NmDeviceState uint32
const (
NmDeviceStateUnknown NmDeviceState = 0
NmDeviceStateUnmanaged NmDeviceState = 10
NmDeviceStateUnavailable NmDeviceState = 20
NmDeviceStateDisconnected NmDeviceState = 30
NmDeviceStatePrepare NmDeviceState = 40
NmDeviceStateConfig NmDeviceState = 50
NmDeviceStateNeed_auth NmDeviceState = 60
NmDeviceStateIp_config NmDeviceState = 70
NmDeviceStateIp_check NmDeviceState = 80
NmDeviceStateSecondaries NmDeviceState = 90
NmDeviceStateActivated NmDeviceState = 100
NmDeviceStateDeactivating NmDeviceState = 110
NmDeviceStateFailed NmDeviceState = 120
)
//go:generate stringer -type=NmDeviceType
type NmDeviceType uint32
const (
NmDeviceTypeUnknown NmDeviceType = 0
NmDeviceTypeEthernet NmDeviceType = 1
NmDeviceTypeWifi NmDeviceType = 2
NmDeviceTypeUnused1 NmDeviceType = 3
NmDeviceTypeUnused2 NmDeviceType = 4
NmDeviceTypeBt NmDeviceType = 5
NmDeviceTypeOlpcMesh NmDeviceType = 6
NmDeviceTypeWimax NmDeviceType = 7
NmDeviceTypeModem NmDeviceType = 8
NmDeviceTypeInfiniband NmDeviceType = 9
NmDeviceTypeBond NmDeviceType = 10
NmDeviceTypeVlan NmDeviceType = 11
NmDeviceTypeAdsl NmDeviceType = 12
NmDeviceTypeBridge NmDeviceType = 13
NmDeviceTypeGeneric NmDeviceType = 14
NmDeviceTypeTeam NmDeviceType = 15
)

9
errors.go Normal file
View file

@ -0,0 +1,9 @@
package gonetworkmanager
import (
"errors"
)
var (
ErrVariantType = errors.New("unexpected variant type")
)

16
nmconnectivity_string.go Normal file
View file

@ -0,0 +1,16 @@
// Code generated by "stringer -type=NmConnectivity"; DO NOT EDIT
package gonetworkmanager
import "fmt"
const _NmConnectivity_name = "NmConnectivityUnknownNmConnectivityNoneNmConnectivityPortalNmConnectivityLimitedNmConnectivityFull"
var _NmConnectivity_index = [...]uint8{0, 21, 39, 59, 80, 98}
func (i NmConnectivity) String() string {
if i >= NmConnectivity(len(_NmConnectivity_index)-1) {
return fmt.Sprintf("NmConnectivity(%d)", i)
}
return _NmConnectivity_name[_NmConnectivity_index[i]:_NmConnectivity_index[i+1]]
}

30
nmdevicestate_string.go Normal file
View file

@ -0,0 +1,30 @@
// Code generated by "stringer -type=NmDeviceState"; DO NOT EDIT
package gonetworkmanager
import "fmt"
const _NmDeviceState_name = "NmDeviceStateUnknownNmDeviceStateUnmanagedNmDeviceStateUnavailableNmDeviceStateDisconnectedNmDeviceStatePrepareNmDeviceStateConfigNmDeviceStateNeed_authNmDeviceStateIp_configNmDeviceStateIp_checkNmDeviceStateSecondariesNmDeviceStateActivatedNmDeviceStateDeactivatingNmDeviceStateFailed"
var _NmDeviceState_map = map[NmDeviceState]string{
0: _NmDeviceState_name[0:20],
10: _NmDeviceState_name[20:42],
20: _NmDeviceState_name[42:66],
30: _NmDeviceState_name[66:91],
40: _NmDeviceState_name[91:111],
50: _NmDeviceState_name[111:130],
60: _NmDeviceState_name[130:152],
70: _NmDeviceState_name[152:174],
80: _NmDeviceState_name[174:195],
90: _NmDeviceState_name[195:219],
100: _NmDeviceState_name[219:241],
110: _NmDeviceState_name[241:266],
120: _NmDeviceState_name[266:285],
}
func (i NmDeviceState) String() string {
if str, ok := _NmDeviceState_map[i]; ok {
return str
}
return fmt.Sprintf("NmDeviceState(%d)", i)
}

16
nmdevicetype_string.go Normal file
View file

@ -0,0 +1,16 @@
// Code generated by "stringer -type=NmDeviceType"; DO NOT EDIT
package gonetworkmanager
import "fmt"
const _NmDeviceType_name = "NmDeviceTypeUnknownNmDeviceTypeEthernetNmDeviceTypeWifiNmDeviceTypeUnused1NmDeviceTypeUnused2NmDeviceTypeBtNmDeviceTypeOlpcMeshNmDeviceTypeWimaxNmDeviceTypeModemNmDeviceTypeInfinibandNmDeviceTypeBondNmDeviceTypeVlanNmDeviceTypeAdslNmDeviceTypeBridgeNmDeviceTypeGenericNmDeviceTypeTeam"
var _NmDeviceType_index = [...]uint16{0, 19, 39, 55, 74, 93, 107, 127, 144, 161, 183, 199, 215, 231, 249, 268, 284}
func (i NmDeviceType) String() string {
if i >= NmDeviceType(len(_NmDeviceType_index)-1) {
return fmt.Sprintf("NmDeviceType(%d)", i)
}
return _NmDeviceType_name[_NmDeviceType_index[i]:_NmDeviceType_index[i+1]]
}

50
nmstate_string.go Normal file
View file

@ -0,0 +1,50 @@
// Code generated by "stringer -type=NmState"; DO NOT EDIT
package gonetworkmanager
import "fmt"
const (
_NmState_name_0 = "NmStateUnknown"
_NmState_name_1 = "NmStateAsleep"
_NmState_name_2 = "NmStateDisconnected"
_NmState_name_3 = "NmStateDisconnecting"
_NmState_name_4 = "NmStateConnecting"
_NmState_name_5 = "NmStateConnectedLocal"
_NmState_name_6 = "NmStateConnectedSite"
_NmState_name_7 = "NmStateConnectedGlobal"
)
var (
_NmState_index_0 = [...]uint8{0, 14}
_NmState_index_1 = [...]uint8{0, 13}
_NmState_index_2 = [...]uint8{0, 19}
_NmState_index_3 = [...]uint8{0, 20}
_NmState_index_4 = [...]uint8{0, 17}
_NmState_index_5 = [...]uint8{0, 21}
_NmState_index_6 = [...]uint8{0, 20}
_NmState_index_7 = [...]uint8{0, 22}
)
func (i NmState) String() string {
switch {
case i == 0:
return _NmState_name_0
case i == 10:
return _NmState_name_1
case i == 20:
return _NmState_name_2
case i == 30:
return _NmState_name_3
case i == 40:
return _NmState_name_4
case i == 50:
return _NmState_name_5
case i == 60:
return _NmState_name_6
case i == 70:
return _NmState_name_7
default:
return fmt.Sprintf("NmState(%d)", i)
}
}

115
utils.go Normal file
View file

@ -0,0 +1,115 @@
package gonetworkmanager
import (
"encoding/binary"
"net"
"github.com/godbus/dbus"
)
type dbusBase struct {
conn *dbus.Conn
obj dbus.BusObject
}
func (d *dbusBase) init(iface string, objectPath dbus.ObjectPath) error {
var err error
d.conn, err = dbus.SystemBus()
if err != nil {
return err
}
d.obj = d.conn.Object(iface, objectPath)
return nil
}
func (d *dbusBase) call(value interface{}, method string, args ...interface{}) {
err := d.callError(value, method, args...)
if err != nil {
panic(err)
}
}
func (d *dbusBase) callError(value interface{}, method string, args ...interface{}) error {
return d.obj.Call(method, 0, args...).Store(value)
}
func (d *dbusBase) getProperty(iface string) interface{} {
variant, err := d.obj.GetProperty(iface)
if err != nil {
panic(err)
}
return variant.Value()
}
func (d *dbusBase) getObjectProperty(iface string) dbus.ObjectPath {
value, ok := d.getProperty(iface).(dbus.ObjectPath)
if !ok {
panic(ErrVariantType)
}
return value
}
func (d *dbusBase) getSliceObjectProperty(iface string) []dbus.ObjectPath {
value, ok := d.getProperty(iface).([]dbus.ObjectPath)
if !ok {
panic(ErrVariantType)
}
return value
}
func (d *dbusBase) getStringProperty(iface string) string {
value, ok := d.getProperty(iface).(string)
if !ok {
panic(ErrVariantType)
}
return value
}
func (d *dbusBase) getSliceStringProperty(iface string) []string {
value, ok := d.getProperty(iface).([]string)
if !ok {
panic(ErrVariantType)
}
return value
}
func (d *dbusBase) getUint32Property(iface string) uint32 {
value, ok := d.getProperty(iface).(uint32)
if !ok {
panic(ErrVariantType)
}
return value
}
func (d *dbusBase) getSliceUint32Property(iface string) []uint32 {
value, ok := d.getProperty(iface).([]uint32)
if !ok {
panic(ErrVariantType)
}
return value
}
func (d *dbusBase) getSliceSliceUint32Property(iface string) [][]uint32 {
value, ok := d.getProperty(iface).([][]uint32)
if !ok {
panic(ErrVariantType)
}
return value
}
func (d *dbusBase) getSliceByteProperty(iface string) []byte {
value, ok := d.getProperty(iface).([]byte)
if !ok {
panic(ErrVariantType)
}
return value
}
func ip4ToString(ip uint32) string {
bs := []byte{0, 0, 0, 0}
binary.LittleEndian.PutUint32(bs, ip)
return net.IP(bs).String()
}