RE: Change IP address with libnm



Hello again Thomas.

After read more documentation and follow your guidelines, I achieved my objective but if you can, I would 
appreciate a second opinion in the developed code, if you don't mind...

#include <glib.h>
#include <stdio.h>
#include <stdlib.h>

#include <NetworkManager.h>
#include <networkManagement.h>

NMClient *client;

static void
connection_updated (GObject      *connection,
                    GAsyncResult *result,
                    gpointer      op)
{
        GError *error = NULL;
        nm_remote_connection_commit_changes_finish (NM_REMOTE_CONNECTION (connection), result, &error);
    printf("Connection Updated successfully\n");
    g_object_unref(op);
        g_clear_error (&error);
}

static void
changeIpAddress(NMConnection *connection)
{
    GError *error = NULL;
        NMSettingIPConfig *s_ip4;
    NMIPAddress *address;
    
        /* Build up the 'ipv4' Setting */
        s_ip4 = NM_SETTING_IP_CONFIG(nm_setting_ip4_config_new());
    if (s_ip4) 
    {
        printf("IPv4 settings found\n");
    }
    else
    {
        printf("Created IPv4 settings\n");
    }
    
    address = nm_ip_address_new (AF_INET, "192.168.123.2", 24, &error);
    if(address != NULL)
    {
        g_object_set (G_OBJECT (s_ip4),
                NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
                NM_SETTING_IP_CONFIG_GATEWAY, "192.168.123.254",
                NULL);
                        


        nm_setting_ip_config_clear_addresses(s_ip4); //clear all addresses
        

        printf("%s\n", nm_ip_address_get_address(address));

        nm_setting_ip_config_add_address(s_ip4, address);
        


        g_object_set (G_OBJECT (s_ip4),
        NM_SETTING_IP_CONFIG_GATEWAY, "192.168.123.254",
        NULL);

        nm_connection_add_setting(connection, nm_setting_duplicate(NM_SETTING(s_ip4)));

        nm_remote_connection_commit_changes_async(NM_REMOTE_CONNECTION (connection),
                                    TRUE, NULL, connection_updated, NULL);                      
        nm_ip_address_unref (address);
    }
}

/* Print details of connection */
static void
show_connection (NMConnection *connection)
{
        NMSettingConnection *s_con;
        guint64 timestamp;
        char *timestamp_str;
        char timestamp_real_str[64];
        const char *val1, *val2, *val3, *val4, *val5;

        s_con = nm_connection_get_setting_connection (connection);
        if (s_con) {
        changeIpAddress(connection);
                /* Get various info from NMSettingConnection and show it */
                timestamp = nm_setting_connection_get_timestamp (s_con);
                timestamp_str = g_strdup_printf ("%" G_GUINT64_FORMAT, timestamp);
                strftime (timestamp_real_str, sizeof (timestamp_real_str), "%c", localtime ((time_t *) 
&timestamp));
                val1 = nm_setting_connection_get_id (s_con);
                val2 = nm_setting_connection_get_uuid (s_con);
                val3 = nm_setting_connection_get_connection_type (s_con);
                val4 = nm_connection_get_path (connection);
                val5 = timestamp ? timestamp_real_str : "never";

                printf ("%-25s | %s | %-15s | %-43s | %s\n", val1, val2, val3, val4, val5);

                g_free (timestamp_str);
        }
}

void networkManager()
{
        GError *error = NULL;
        NMConnection *connections;
        
        if (!(client = nm_client_new (NULL, &error))) {
                g_message ("Error: Could not connect to NetworkManager: %s.", error->message);
                g_error_free (error);
                return;
        }

        if (!nm_client_get_nm_running (client)) {
                g_message ("Error: Can't obtain connections: NetworkManager is not running.");
                return;
        }

        /* Now the connections can be listed. */
        connections = (NMConnection *)nm_client_get_connection_by_id (client, "Wired connection 2");

        printf ("Connections:\n===================\n");

        show_connection (connections);

        g_object_unref (client);

        return;
}

Thanks in advance,
António Pontinha Mendes
________________________________________
From: Thomas Haller <thaller redhat com>
Sent: 26 February 2020 10:20
To: António Mendes; networkmanager-list gnome org
Subject: Re: Change IP address with libnm

On Wed, 2020-02-26 at 10:08 +0000, António Mendes wrote:
Hi Thomas.

Thank you for your help. I am new using this library so, your help is
much appreciated.
That's really what I was looking for because, right now, I am simply
calling system("nmcli con mod Wired\ connection\ 1 ...") in my test
application to modify settings and I wanted to replace that part.
I will keep you informed.

btw, libnm is glib based, so you can also use it via GObject
introspection, for example from Python or Javascript (gjs).

That tends to be faster for prototyping. See examples
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/tree/9add51ef16356da81a0fd5a8f3f0ddebeb093636/examples/python/gi

This is also what is done by various other projects:
https://github.com/linux-system-roles/network
https://github.com/nmstate/nmstate
https://github.com/rhinstaller/anaconda/tree/master/pyanaconda



For larger examples how to use libnm natively, look at
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/tree/9add51ef16356da81a0fd5a8f3f0ddebeb093636/clients
https://gitlab.gnome.org/GNOME/libnma
https://gitlab.gnome.org/GNOME/network-manager-applet


best,
Thomas



Thanks again,
António Pontinha Mendes
________________________________________
From: Thomas Haller <thaller redhat com>
Sent: 25 February 2020 17:34
To: António Mendes; networkmanager-list gnome org
Subject: Re: Change IP address with libnm

On Tue, 2020-02-25 at 17:02 +0000, António Mendes wrote:
Hi.
I tried to use the example add-connection-libnm-glib.c and adapt to
my case but without success...
I wanted to change an IP address from a connection already created
and add some 802.1X configurations.

Hi,

add-connection adds a new profile.
Basically, what `nmcli connection add ...` does.

The example you refer to is about usage of libnm. So, the
corresponding
API is nm_remote_connection_update2() ([1]). This maps to the D-Bus
call Update2 ([2]). This is what `nmcli connection modify ...` does.

[1]
https://developer.gnome.org/libnm/1.22/NMRemoteConnection.html#nm-remote-connection-update2
[2]
https://developer.gnome.org/NetworkManager/1.22/gdbus-org.freedesktop.NetworkManager.Settings.Connection.html#gdbus-method-org-freedesktop-NetworkManager-Settings-Connection.Update2


As always, connection profiles in NetworkManager are really just a
bunch of nested
dictionaries, that is the plain settings. There is no further logic
involved, just
create a suitable profile. If you use libnm, you probably create the
profile using the
NMConnection and NMSetting types. These represent the nested
dictionaries.

After you modify a profile, you usually need to activate it so that
your actual networking
configuration (`nmcli device`, `ip link`) changes.



best,
Thomas
www.eid.pt

EID, S.A.
Capital Social €1.100.000
N° de matricula unico 501 400 699

DISCLAIMER

www.eid.pt

EID, S.A.
Capital Social €1.100.000
N° de matricula unico 501 400 699

DISCLAIMER



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]