0

This post has two questions. 1. network interface up/down notification on a specific network device 2. list the network devices.

See below for the answers provided by me. (Thanks to Velkan for helping me in arriving at this)

I am looking for a c++ library which receives the network interface up/down event notification with interface name on Ubuntu machine. I have been asked by my colleagues to use dbus interfaces for the same. Used the link below for the same, which just notifies about any interface up/down event without interface name.

https://cgit.freedesktop.org/NetworkManager/NetworkManager/tree/examples/C/glib/monitor-nm-state-gdbus.c

I am googling around for a quite sometime now, I could not find right examples and even the dbus documentation is not straight forward or not providing the information what I am looking for.

Any help on this would be greatly helpful.

Thanks in Advance

2 Answers2

1

I've looked a bit with the d-feet utility.

On the 'System Bus' there is an /org/freedesktop/NetworkManager with a DeviceAdded signal.

The /org/freedesktop/NetworkManager/Devices/1 things have:

  • Interface string in org.freedesktop.NetworkManager.Device
  • Carrier boolean and PropertiesChanged signal in org.freedesktop.NetworkManager.Device.Wired, org.freedesktop.NetworkManager.Device.Bridge, org.freedesktop.NetworkManager.Device.Adsl...

So, get the NetworkManager object, listen to the modifications to the device lists, subscribe to the PropertiesChanged of the current devices and devices that will appear, watch for the Carrier property.

Look into other properties if you want to detect that the interface is up, but has no IP assigned (or maybe it's in some other intermediate state).

If you're using the Server version of Ubuntu (you're not) then I think that it doesn't use the NetworkManager, so it has a somewhat less usable D-Bus interface - org.freedesktop.network1.

Shell example of DeviceAdded/DeviceRemoved:

$ dbus-monitor --system "type='signal',interface='org.freedesktop.NetworkManager'"

When a Wi-Fi USB key is plugged in:

signal time=1509615532.227067 sender=:1.8 -> destination=(null destination) serial=2051 path=/org/freedesktop/NetworkManager; interface=org.freedesktop.NetworkManager; member=DeviceAdded
   object path "/org/freedesktop/NetworkManager/Devices/10"
signal time=1509615532.228150 sender=:1.8 -> destination=(null destination) serial=2056 path=/org/freedesktop/NetworkManager; interface=org.freedesktop.NetworkManager; member=PropertiesChanged
   array [
      dict entry(
         string "AllDevices"
         variant             array [
               object path "/org/freedesktop/NetworkManager/Devices/0"
               object path "/org/freedesktop/NetworkManager/Devices/1"
               object path "/org/freedesktop/NetworkManager/Devices/2"
               object path "/org/freedesktop/NetworkManager/Devices/3"
               object path "/org/freedesktop/NetworkManager/Devices/4"
               object path "/org/freedesktop/NetworkManager/Devices/5"
               object path "/org/freedesktop/NetworkManager/Devices/6"
               object path "/org/freedesktop/NetworkManager/Devices/8"
               object path "/org/freedesktop/NetworkManager/Devices/10"
            ]
      )
      dict entry(
         string "Devices"
         variant             array [
               object path "/org/freedesktop/NetworkManager/Devices/0"
               object path "/org/freedesktop/NetworkManager/Devices/1"
               object path "/org/freedesktop/NetworkManager/Devices/2"
               object path "/org/freedesktop/NetworkManager/Devices/3"
               object path "/org/freedesktop/NetworkManager/Devices/4"
               object path "/org/freedesktop/NetworkManager/Devices/5"
               object path "/org/freedesktop/NetworkManager/Devices/6"
               object path "/org/freedesktop/NetworkManager/Devices/8"
               object path "/org/freedesktop/NetworkManager/Devices/10"
            ]
      )
   ]
signal time=1509615533.253596 sender=:1.8 -> destination=(null destination) serial=2072 path=/org/freedesktop/NetworkManager; interface=org.freedesktop.NetworkManager; member=PropertiesChanged
   array [
      dict entry(
         string "WirelessEnabled"
         variant             boolean false
      )
   ]
signal time=1509615533.287235 sender=:1.8 -> destination=(null destination) serial=2080 path=/org/freedesktop/NetworkManager; interface=org.freedesktop.NetworkManager; member=PropertiesChanged
   array [
      dict entry(
         string "ActiveConnections"
         variant             array [
               object path "/org/freedesktop/NetworkManager/ActiveConnection/3"
               object path "/org/freedesktop/NetworkManager/ActiveConnection/2"
               object path "/org/freedesktop/NetworkManager/ActiveConnection/1"
               object path "/org/freedesktop/NetworkManager/ActiveConnection/0"
            ]
      )
   ]

Several signals are fired. So, if we were subscribed to the DeviceAdded or PropertiesChanged, we can deduce that we need to watch the device #10 too.

When it's removed:

signal time=1509615612.892305 sender=:1.8 -> destination=(null destination) serial=2086 path=/org/freedesktop/NetworkManager; interface=org.freedesktop.NetworkManager; member=DeviceRemoved
   object path "/org/freedesktop/NetworkManager/Devices/10"
signal time=1509615612.893697 sender=:1.8 -> destination=(null destination) serial=2089 path=/org/freedesktop/NetworkManager; interface=org.freedesktop.NetworkManager; member=PropertiesChanged
   array [
      dict entry(
         string "ActiveConnections"
         variant             array [
               object path "/org/freedesktop/NetworkManager/ActiveConnection/3"
               object path "/org/freedesktop/NetworkManager/ActiveConnection/2"
               object path "/org/freedesktop/NetworkManager/ActiveConnection/1"
               object path "/org/freedesktop/NetworkManager/ActiveConnection/0"
            ]
      )
      dict entry(
         string "AllDevices"
         variant             array [
               object path "/org/freedesktop/NetworkManager/Devices/0"
               object path "/org/freedesktop/NetworkManager/Devices/1"
               object path "/org/freedesktop/NetworkManager/Devices/2"
               object path "/org/freedesktop/NetworkManager/Devices/3"
               object path "/org/freedesktop/NetworkManager/Devices/4"
               object path "/org/freedesktop/NetworkManager/Devices/5"
               object path "/org/freedesktop/NetworkManager/Devices/6"
               object path "/org/freedesktop/NetworkManager/Devices/8"
            ]
      )
      dict entry(
         string "Devices"
         variant             array [
               object path "/org/freedesktop/NetworkManager/Devices/0"
               object path "/org/freedesktop/NetworkManager/Devices/1"
               object path "/org/freedesktop/NetworkManager/Devices/2"
               object path "/org/freedesktop/NetworkManager/Devices/3"
               object path "/org/freedesktop/NetworkManager/Devices/4"
               object path "/org/freedesktop/NetworkManager/Devices/5"
               object path "/org/freedesktop/NetworkManager/Devices/6"
               object path "/org/freedesktop/NetworkManager/Devices/8"
            ]
      )
   ]
signal time=1509615612.910829 sender=:1.8 -> destination=(null destination) serial=2095 path=/org/freedesktop/NetworkManager; interface=org.freedesktop.NetworkManager; member=PropertiesChanged
   array [
      dict entry(
         string "WirelessEnabled"
         variant             boolean true
      )
   ]

Same signals: #10 has disappeared.

Or subscribe to DeviceAddedand DeviceRemoved to be getting only them:

$ dbus-monitor --system type=signal,interface=org.freedesktop.NetworkManager,member=Device{Added,Removed}
Velkan
  • 7,067
  • 6
  • 43
  • 87
  • Thank you so much Velkan. This helps a lot. – Murali Kothandaraman Oct 31 '17 at 11:36
  • I am a newbie to linux and finding difficulties in getting code samples for this. I was able to listen for one of the interface up/down event changes from below code shared by me. But i am interested in what you had mentioned above (i.e listen for all devices properties changed signal). Could you please share me any sample code available for this? – Murali Kothandaraman Nov 02 '17 at 09:17
  • In the D-Bus GLib bindings that you're using it's most certainly the `g_dbus_connection_signal_subscribe()` function. I can't immediately see any code examples. The function takes a pointer to a function, so it's a pretty usual C-style callback installer. – Velkan Nov 02 '17 at 10:07
  • Thanks again Velkan. I took a different approach, first get list of devices and listen for their up/down events. I used GetDevices method in NetworkManager to get the devices list and used then used approach discussed below for up/down event notification listening. – Murali Kothandaraman Nov 03 '17 at 09:41
  • I need some more inputs from you. I would like to know how to fetch the property of a particular interface in DBus. Especially I am interested in Interface property of org.freedesktop.NetworkManager.Device. Any code snippet would be of great help. – Murali Kothandaraman Nov 03 '17 at 09:42
  • The high-level class `GDBusProxy` looks alright. It has `g_dbus_proxy_get_cached_property()` for getting the value of a property and `g-properties-changed` signal for getting notification when any of the properties is changed. You may want to move your answer into your question and also unaccept my answer - that way you'll have a larger probability of someone else looking into the question. – Velkan Nov 03 '17 at 10:36
  • Thanks for inputs again Velkan. I tried two approaches 1. g_dbus_proxy_get_cached_property but it is always returning null. 2.g_dbus_proxy_call_sync - this one says "org.freedesktop.networkmanager" isn't exported (or may not exist), can't access property "Interface". I will probably post this as a separate question. – Murali Kothandaraman Nov 03 '17 at 11:31
0

Anyone who wants a working code sample, can replace similar line given below, in the link shared in the question (https://cgit.freedesktop.org/NetworkManager/NetworkManager/tree/examples/C/glib/monitor-nm-state-gdbus.c).

Code snippet for listening up/down event on a specific device Here I have just changed the object path parm value to

  • /org/freedesktop/NetworkManager/Devices/0
  • /org/freedesktop/NetworkManager/Devices/1

    proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, flags, NULL, /* GDBusInterfaceInfo / "org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager/Devices/1", "org.freedesktop.NetworkManager.Device", NULL, / GCancellable */ &error);

Code snippet for list the devices available.

proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
                                       flags,
                                       NULL, /* GDBusInterfaceInfo */
                                       "org.freedesktop.NetworkManager",
                                       "/org/freedesktop/NetworkManager",
                                       "org.freedesktop.NetworkManager",
                                       NULL, /* GCancellable */
                                       &error);

ret = g_dbus_proxy_call_sync (proxy,
                              "GetDevices",
                              NULL,
                              G_DBUS_CALL_FLAGS_NONE, -1,
                              NULL, &error);
if (!ret) {
    g_dbus_error_strip_remote_error (error);
    g_print ("ListConnections failed: %s\n", error->message);
    g_error_free (error);
    return;
}

g_variant_get (ret, "(^ao)", &paths);
g_variant_unref (ret);

for (i = 0; paths[i]; i++)
    g_print ("%s\n", paths[i]);

Output for list of network devices (I have 2 nic cards in my machine)

/org/freedesktop/NetworkManager/Devices/0

/org/freedesktop/NetworkManager/Devices/1