[systemd-devel] sd-bus example code for SetLinkDNS()
Lennart Poettering
lennart at poettering.net
Fri Jul 21 12:35:41 UTC 2017
On Wed, 19.07.17 11:20, Tilman Baumann (tilman at baumann.name) wrote:
> Hi folks,
>
> I'm trying to teach a vpn software (openfortivpn) how to properly set up
> DNS in a systemd-resolve environment.
>
> I'm trying to set up a equivalent to this in C.
> busctl call org.freedesktop.resolve1 /org/freedesktop/resolve1
> org.freedesktop.resolve1.Manager SetLinkDNS 'ia(iay)' 16 2 2 4 10 10 10
> 10 2 4 10 10 10 11
> [https://gist.github.com/tbaumann/d484efb2e27613654a52dbe11cfe53b8]
>
> I came up with this quick proof of concept code based on the example
> code in the sd-bus docu.
> Of course it segfaults. No surprise, I have done nothing to hint at the
> length of the inner byte array. (ay)
>
> I was unable to find any example code that would give me a hint on how
> to pass such more complex data structures into sd_bus_call_method()
>
> int SetLinkDNSv4(sd_bus *bus, int if_index, struct in_addr ns1, struct
> in_addr ns2) {
> sd_bus_error error = SD_BUS_ERROR_NULL;
> sd_bus_message *m = NULL;
> int r;
> struct dns_address {
> int sin_family;
> struct in_addr ip_addr;
> };
> struct dns_address addresses[2];
>
>
> addresses[0].sin_family = AF_INET;
> addresses[0].ip_addr = ns1;
> addresses[1].sin_family = AF_INET;
> addresses[1].ip_addr = ns2;
>
> r = sd_bus_call_method(bus,
> "org.freedesktop.resolve1", /*
> service to contact */
> "/org/freedesktop/resolve1", /* object
> path */
> "org.freedesktop.resolve1.Manager", /*
> interface name */
> "SetLinkDNS", /* method
> name */
> &error, /* object
> to return error in */
> &m, /* return
> message on success */
> "ia(iay)", /* input
> signature */
> if_index,
> 2, /* Array
> size */
> addresses);
> }
>
> [Full code:
> https://gist.github.com/tbaumann/0f466c984c858767c966458d53483697]
>
> My guess is that I can have it easier if I somehow use
> sd_bus_message_append() to assemble the message. But I don't see a clear
> path either.
You have to do something like this:
sd_bus_message_new_method(..., &m);
sd_bus_message_append(m, "i", ifindex);
sd_bus_message_open_container(m, 'a', '(iay)');
for (i = 0; i < n_addresses; i++) {
sd_bus_message_open_container(m, '(', "iay"));
sd_bus_message_append(m, "i", addresses[i].sin_family);
sd_bus_message_append_array(m, 'y', &addresses[i].ip_addr, sizeof(addresses[i].ip_addr));
sd_bus_message_close_container(m);
}
sd_bus_message_close_container(m);
sd_bus_message_send(..., m);
sd_bus_message_unref(m);
(not tested, just written down from the top of my head, and of course,
don't forget to add proper error checking)
Lennart
--
Lennart Poettering, Red Hat
More information about the systemd-devel
mailing list