--- /dev/null
+/*#############################################################################
+# #
+# 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#include <systemd/sd-bus.h>
+
+#include "command.h"
+#include "zone.h"
+
+typedef int (*networkctl_zone_walk_callback)
+ (sd_bus* bus, const char* path, const char* name, void* data);
+
+static int networkctl_zone_walk(sd_bus* bus,
+ networkctl_zone_walk_callback callback, void* data) {
+ sd_bus_message* reply = NULL;
+ sd_bus_error error = SD_BUS_ERROR_NULL;
+ int r;
+
+ // Call ListZones
+ r = sd_bus_call_method(bus, "org.ipfire.network1", "/org/ipfire/network1",
+ "org.ipfire.network1", "ListZones", &error, &reply, "");
+ if (r < 0) {
+ fprintf(stderr, "ListZones 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 zones
+ 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_zone_list(sd_bus* bus, const char* path, const char* name, void* data) {
+ printf("%s\n", name);
+
+ return 0;
+}
+
+static int networkctl_zone_list(sd_bus* bus, int argc, char* argv[]) {
+ return networkctl_zone_walk(bus, __networkctl_zone_list, NULL);
+}
+
+int networkctl_zone(sd_bus* bus, int argc, char* argv[]) {
+ static const struct command commands[] = {
+ { "list", 0, networkctl_zone_list },
+ { NULL },
+ };
+
+ return command_dispatch(bus, commands, argc, argv);
+}
--- /dev/null
+/*#############################################################################
+# #
+# 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#ifndef NETWORKCTL_ZONE_H
+#define NETWORKCTL_ZONE_H
+
+int networkctl_zone(sd_bus* bus, int argc, char* argv[]);
+
+#endif /* NETWORKCTL_ZONE_H */