From: Michael Tremer Date: Sun, 4 Jun 2023 16:50:35 +0000 (+0000) Subject: ports: Implement listing ports over DBus X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4c99b8ed5da20ba81845486bbcb9a841b7cd2119;p=network.git ports: Implement listing ports over DBus Signed-off-by: Michael Tremer --- diff --git a/Makefile.am b/Makefile.am index aafa59c0..273302b3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -392,6 +392,8 @@ dist_networkctl_SOURCES = \ src/networkctl/command.c \ src/networkctl/command.h \ src/networkctl/main.c \ + src/networkctl/port.c \ + src/networkctl/port.h \ src/networkctl/zone.c \ src/networkctl/zone.h diff --git a/src/networkctl/main.c b/src/networkctl/main.c index a08256ce..73908f8f 100644 --- a/src/networkctl/main.c +++ b/src/networkctl/main.c @@ -26,6 +26,7 @@ #include #include "command.h" +#include "port.h" #include "zone.h" static int networkctl_status(sd_bus* bus, int argc, char* argv[]) { @@ -35,6 +36,7 @@ static int networkctl_status(sd_bus* bus, int argc, char* argv[]) { static int networkctl_main(sd_bus* bus, int argc, char* argv[]) { static const struct command commands[] = { + { "port", 0, networkctl_port }, { "status", 0, networkctl_status }, { "zone", 0, networkctl_zone }, { NULL }, diff --git a/src/networkctl/port.c b/src/networkctl/port.c new file mode 100644 index 00000000..689e2f1d --- /dev/null +++ b/src/networkctl/port.c @@ -0,0 +1,97 @@ +/*############################################################################# +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2023 IPFire Network Development Team # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +#############################################################################*/ + +#include + +#include "command.h" +#include "port.h" + +typedef int (*networkctl_port_walk_callback) + (sd_bus* bus, const char* path, const char* name, void* data); + +static int networkctl_port_walk(sd_bus* bus, + networkctl_port_walk_callback callback, void* data) { + sd_bus_message* reply = NULL; + sd_bus_error error = SD_BUS_ERROR_NULL; + int r; + + // Call Listports + r = sd_bus_call_method(bus, "org.ipfire.network1", "/org/ipfire/network1", + "org.ipfire.network1", "ListPorts", &error, &reply, ""); + if (r < 0) { + fprintf(stderr, "Listports call failed: %m\n"); + goto ERROR; + } + + const char* name = NULL; + const char* path = NULL; + + // Open the container + r = sd_bus_message_enter_container(reply, 'a', "(so)"); + if (r < 0) { + fprintf(stderr, "Could not open container: %m\n"); + goto ERROR; + } + + // Iterate over all ports + for (;;) { + r = sd_bus_message_read(reply, "(so)", &name, &path); + if (r < 0) + goto ERROR; + + // Break if we reached the end of the container + if (r == 0) + break; + + // Call the callback + r = callback(bus, path, name, data); + if (r) + goto ERROR; + } + + // Close the container + sd_bus_message_exit_container(reply); + +ERROR: + if (reply) + sd_bus_message_unref(reply); + sd_bus_error_free(&error); + + return r; +} + +static int __networkctl_port_list(sd_bus* bus, const char* path, const char* name, void* data) { + printf("%s\n", name); + + return 0; +} + +static int networkctl_port_list(sd_bus* bus, int argc, char* argv[]) { + return networkctl_port_walk(bus, __networkctl_port_list, NULL); +} + +int networkctl_port(sd_bus* bus, int argc, char* argv[]) { + static const struct command commands[] = { + { "list", 0, networkctl_port_list }, + { NULL }, + }; + + return command_dispatch(bus, commands, argc, argv); +} diff --git a/src/networkctl/port.h b/src/networkctl/port.h new file mode 100644 index 00000000..2326ce68 --- /dev/null +++ b/src/networkctl/port.h @@ -0,0 +1,26 @@ +/*############################################################################# +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2023 IPFire Network Development Team # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +#############################################################################*/ + +#ifndef NETWORKCTL_PORT_H +#define NETWORKCTL_PORT_H + +int networkctl_port(sd_bus* bus, int argc, char* argv[]); + +#endif /* NETWORKCTL_PORT_H */ diff --git a/src/networkd/daemon-bus.c b/src/networkd/daemon-bus.c index 7620eed8..4de8c0fb 100644 --- a/src/networkd/daemon-bus.c +++ b/src/networkd/daemon-bus.c @@ -39,6 +39,55 @@ static int nw_daemon_bus_reload(sd_bus_message* m, void* data, sd_bus_error* err return sd_bus_reply_method_return(m, NULL); } +static int __nw_daemon_bus_list_ports(nw_daemon* daemon, nw_port* port, void* data) { + sd_bus_message* reply = (sd_bus_message*)data; + int r; + + // Fetch port name + const char* name = nw_port_name(port); + + // Fetch bus path + char* path = nw_port_bus_path(port); + + r = sd_bus_message_append(reply, "(so)", name, path); + + free(path); + + return r; +} + +static int nw_daemon_bus_list_ports(sd_bus_message* m, void* data, sd_bus_error* error) { + nw_daemon* daemon = (nw_daemon*)data; + sd_bus_message* reply = NULL; + int r; + + // Form a reply message + r = sd_bus_message_new_method_return(m, &reply); + if (r < 0) + goto ERROR; + + r = sd_bus_message_open_container(reply, 'a', "(so)"); + if (r < 0) + goto ERROR; + + r = nw_daemon_ports_walk(daemon, __nw_daemon_bus_list_ports, reply); + if (r < 0) + goto ERROR; + + r = sd_bus_message_close_container(reply); + if (r < 0) + goto ERROR; + + // Send the reply + r = sd_bus_send(NULL, reply, NULL); + +ERROR: + if (reply) + sd_bus_message_unref(reply); + + return r; +} + static int __nw_daemon_bus_list_zones(nw_daemon* daemon, nw_zone* zone, void* data) { sd_bus_message* reply = (sd_bus_message*)data; int r; @@ -90,6 +139,8 @@ ERROR: static const sd_bus_vtable daemon_vtable[] = { SD_BUS_VTABLE_START(0), + SD_BUS_METHOD_WITH_ARGS("ListPorts", SD_BUS_NO_ARGS, SD_BUS_RESULT("a(so)", links), + nw_daemon_bus_list_ports, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD_WITH_ARGS("ListZones", SD_BUS_NO_ARGS, SD_BUS_RESULT("a(so)", links), nw_daemon_bus_list_zones, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("Reload", SD_BUS_NO_ARGS, SD_BUS_NO_RESULT,