1 /*#############################################################################
3 # IPFire.org - A linux based firewall #
4 # Copyright (C) 2023 IPFire Network Development Team #
6 # This program is free software: you can redistribute it and/or modify #
7 # it under the terms of the GNU General Public License as published by #
8 # the Free Software Foundation, either version 3 of the License, or #
9 # (at your option) any later version. #
11 # This program is distributed in the hope that it will be useful, #
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
14 # GNU General Public License for more details. #
16 # You should have received a copy of the GNU General Public License #
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
19 #############################################################################*/
24 #include <systemd/sd-bus.h>
26 #include "../networkd/json.h"
27 #include "../networkd/string.h"
32 typedef int (*networkctl_port_walk_callback
)
33 (sd_bus
* bus
, const char* path
, const char* name
, void* data
);
35 static int networkctl_port_walk(sd_bus
* bus
,
36 networkctl_port_walk_callback callback
, void* data
) {
37 sd_bus_message
* reply
= NULL
;
38 sd_bus_error error
= SD_BUS_ERROR_NULL
;
42 r
= sd_bus_call_method(bus
, "org.ipfire.network1", "/org/ipfire/network1",
43 "org.ipfire.network1", "ListPorts", &error
, &reply
, "");
45 fprintf(stderr
, "ListPorts call failed: %m\n");
49 const char* name
= NULL
;
50 const char* path
= NULL
;
53 r
= sd_bus_message_enter_container(reply
, 'a', "(so)");
55 fprintf(stderr
, "Could not open container: %m\n");
59 // Iterate over all ports
61 r
= sd_bus_message_read(reply
, "(so)", &name
, &path
);
65 // Break if we reached the end of the container
70 r
= callback(bus
, path
, name
, data
);
75 // Close the container
76 sd_bus_message_exit_container(reply
);
80 sd_bus_message_unref(reply
);
81 sd_bus_error_free(&error
);
86 static int networkctl_port_describe(sd_bus
* bus
, const char* name
, char** text
) {
87 sd_bus_message
* reply
= NULL
;
88 sd_bus_error error
= SD_BUS_ERROR_NULL
;
98 r
= nw_string_format(path
, "/org/ipfire/network1/port/%s", name
);
103 r
= sd_bus_call_method(bus
, "org.ipfire.network1", path
,
104 "org.ipfire.network1.Port", "Describe", &error
, &reply
, "");
106 fprintf(stderr
, "Describe() call failed: %m\n");
111 r
= sd_bus_message_read(reply
, "s", &t
);
113 fprintf(stderr
, "Could not parse bus message: %s\n", strerror(-r
));
124 sd_bus_message_unref(reply
);
131 static int networkctl_port_dump(sd_bus
* bus
, int argc
, char* argv
[]) {
136 fprintf(stderr
, "Port required\n");
141 r
= networkctl_port_describe(bus
, argv
[0], &text
);
146 printf("%s\n", text
);
156 static int __networkctl_port_list(sd_bus
* bus
, const char* path
, const char* name
, void* data
) {
157 printf("%s\n", name
);
162 static int networkctl_port_list(sd_bus
* bus
, int argc
, char* argv
[]) {
163 return networkctl_port_walk(bus
, __networkctl_port_list
, NULL
);
168 #define SHOW_LINE " %-12s : %s\n"
170 static int __networkctl_port_show(sd_bus
* bus
, const char* path
, const char* name
, void* data
) {
171 struct json_object
* object
= NULL
;
172 enum json_tokener_error json_error
;
173 char* describe
= NULL
;
176 // Describe this port
177 r
= networkctl_port_describe(bus
, name
, &describe
);
182 object
= json_tokener_parse_verbose(describe
, &json_error
);
184 fprintf(stderr
, "Could not parse port %s: %s\n",
185 name
, json_tokener_error_desc(json_error
));
190 printf("Port %s%s%s\n", color_highlight(), name
, color_reset());
193 const char* type
= json_object_fetch_string(object
, "Type");
195 printf(SHOW_LINE
, "Type", type
);
198 const char* address
= json_object_fetch_string(object
, "Address");
200 printf(SHOW_LINE
, "Address", address
);
202 // Show an empty line at the end
212 json_object_unref(object
);
217 static int networkctl_port_show(sd_bus
* bus
, int argc
, char* argv
[]) {
220 return networkctl_port_walk(bus
, __networkctl_port_show
, NULL
);
223 return __networkctl_port_show(bus
, NULL
, argv
[0], NULL
);
226 fprintf(stderr
, "Too many arguments\n");
231 int networkctl_port(sd_bus
* bus
, int argc
, char* argv
[]) {
232 static const struct command commands
[] = {
233 { "dump", 0, networkctl_port_dump
},
234 { "list", 0, networkctl_port_list
},
235 { "show", 0, networkctl_port_show
},
239 return command_dispatch(bus
, commands
, argc
, argv
);