From patchwork Sun Jan 2 11:31:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Lindner X-Patchwork-Id: 18436 X-Patchwork-Delegate: sw@simonwunderlich.de Return-Path: X-Original-To: patchwork@open-mesh.org Delivered-To: patchwork@open-mesh.org Received: from diktynna.open-mesh.org (localhost [IPv6:::1]) by diktynna.open-mesh.org (Postfix) with ESMTP id E4F5683E75; Sun, 2 Jan 2022 12:31:59 +0100 (CET) Received: from s2.neomailbox.net (s2.neomailbox.net [5.148.176.60]) by diktynna.open-mesh.org (Postfix) with ESMTPS id 33E7181240 for ; Sun, 2 Jan 2022 12:31:57 +0100 (CET) From: Marek Lindner To: b.a.t.m.a.n@lists.open-mesh.org Subject: [PATCH 1/4] alfred: remove meaningless printf() call Date: Sun, 2 Jan 2022 12:31:33 +0100 Message-Id: <20220102113136.470299-1-mareklindner@neomailbox.ch> In-Reply-To: <3748133.vRqKQLy7FI@rousseau> References: <3748133.vRqKQLy7FI@rousseau> MIME-Version: 1.0 ARC-Authentication-Results: i=1; diktynna.open-mesh.org; dkim=none; spf=pass (diktynna.open-mesh.org: domain of mareklindner@neomailbox.ch designates 5.148.176.60 as permitted sender) smtp.mailfrom=mareklindner@neomailbox.ch; dmarc=none ARC-Seal: i=1; s=20121; d=open-mesh.org; t=1641123117; a=rsa-sha256; cv=none; b=cJP6Bwei/UUlL/txjZslA+GOPmPLdRXYAYQ5g5OQPUJvYWFoeqbD1hy7kfeb3qTiT3RXKA S+/F5u6yhUhDbHthvSeTAgjehezL3nXkc95V79fjdg4/E/GGi1QhTdofwMLKdLoQzLZgNz wck2NY3su4Oe2Vx8r+PNSDBgdvqao5w= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=open-mesh.org; s=20121; t=1641123117; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Kzq8qIfB9LH6xYnykw6shJvXnb8uHPONBhJRbe0nUcI=; b=h/R9d1zuFC/J2UFsgRzmHJQmwgL5QzleX4ddI5qJ2FX5cy0jEHkHGH9lVCEYRSNCQ4rKDI tHIA1y5nXcz2JLE+EbmWDiIMU+aepv6arRU1gSEVt+hy6bgrNLAnj6nqZ4/0Bb94/fGNN1 goeDnpAHoNg/BpGq2ZGtbejIXnEAVEA= Message-ID-Hash: IHJ35BMCY26UXW6V66LFROSI4TY2KVWE X-Message-ID-Hash: IHJ35BMCY26UXW6V66LFROSI4TY2KVWE X-MailFrom: mareklindner@neomailbox.ch X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-b.a.t.m.a.n.lists.open-mesh.org-0; header-match-b.a.t.m.a.n.lists.open-mesh.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header CC: Marek Lindner X-Mailman-Version: 3.2.1 Precedence: list Reply-To: The list for a Better Approach To Mobile Ad-hoc Networking List-Id: The list for a Better Approach To Mobile Ad-hoc Networking Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: Signed-off-by: Marek Lindner --- server.c | 1 - 1 file changed, 1 deletion(-) diff --git a/server.c b/server.c index b4925e7..85bf453 100644 --- a/server.c +++ b/server.c @@ -442,7 +442,6 @@ int alfred_server(struct globals *globals) netsock_check_error(globals, &errfds); if (FD_ISSET(globals->unix_sock, &fds)) { - printf("read unix socket\n"); unix_sock_read(globals); continue; } else { From patchwork Sun Jan 2 11:31:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Lindner X-Patchwork-Id: 18437 X-Patchwork-Delegate: sw@simonwunderlich.de Return-Path: X-Original-To: patchwork@open-mesh.org Delivered-To: patchwork@open-mesh.org Received: from diktynna.open-mesh.org (localhost [IPv6:::1]) by diktynna.open-mesh.org (Postfix) with ESMTP id 0A6D083E8D; Sun, 2 Jan 2022 12:32:10 +0100 (CET) Received: from s2.neomailbox.net (s2.neomailbox.net [5.148.176.60]) by diktynna.open-mesh.org (Postfix) with ESMTPS id E887883E8B for ; Sun, 2 Jan 2022 12:32:06 +0100 (CET) From: Marek Lindner To: b.a.t.m.a.n@lists.open-mesh.org Subject: [PATCH 2/4] alfred: Allow operating without any interface specified Date: Sun, 2 Jan 2022 12:31:34 +0100 Message-Id: <20220102113136.470299-2-mareklindner@neomailbox.ch> In-Reply-To: <20220102113136.470299-1-mareklindner@neomailbox.ch> References: <3748133.vRqKQLy7FI@rousseau> <20220102113136.470299-1-mareklindner@neomailbox.ch> MIME-Version: 1.0 ARC-Authentication-Results: i=1; diktynna.open-mesh.org; dkim=none; spf=pass (diktynna.open-mesh.org: domain of mareklindner@neomailbox.ch designates 5.148.176.60 as permitted sender) smtp.mailfrom=mareklindner@neomailbox.ch; dmarc=none ARC-Seal: i=1; s=20121; d=open-mesh.org; t=1641123127; a=rsa-sha256; cv=none; b=lUOAOUgh4SujOiOsIjI0T398jfch9d+UGpCdYHxKbAVt+1u/SuBalQ9DOtxR5yh7/iE03i 1DEIVP+Qc0b4fOzXnr9GAqcMFApJQl/6rGRS8nPSRjRpStF2wb9Um/aSGLES4oYVQPSGjX TyHG00RetmwXFnzW/oX002QbC05mS0E= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=open-mesh.org; s=20121; t=1641123127; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=CJZLnxR5yxGwTxDBbxc6v6ppVbyEExquS8yjEheveQM=; b=ZbAKlQw6ZPd+WQXqQBgE81ju1xtuTS8WI0xJlRFIsbGs4EgS2PMiG2a//3e3jzXmnXIDFJ XkUOq4/aUuXu/h7FKeL2isf7fgS6Cn0iXlGaaubLZbE4fpysFqziAOXYJFsX/oIhR81xCF Qqsr7RFsA2I8MkTQ92blrJgQicguH9E= Message-ID-Hash: 67UQP5BSN3HUSE2AA4MXBZTHKPL6TYR4 X-Message-ID-Hash: 67UQP5BSN3HUSE2AA4MXBZTHKPL6TYR4 X-MailFrom: mareklindner@neomailbox.ch X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-b.a.t.m.a.n.lists.open-mesh.org-0; header-match-b.a.t.m.a.n.lists.open-mesh.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header CC: Marek Lindner X-Mailman-Version: 3.2.1 Precedence: list Reply-To: The list for a Better Approach To Mobile Ad-hoc Networking List-Id: The list for a Better Approach To Mobile Ad-hoc Networking Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: The '-i' commandline parameter to specify interface names no longer is mandatory. Specifying interface 'none' or sending a 'none' interface string within the ALFRED_CHANGE_INTERFACE unix socket command disables all interfaces operations at runtime. Signed-off-by: Marek Lindner --- README.rst | 6 +++++- alfred.h | 1 - man/alfred.8 | 6 +++++- netsock.c | 23 ++++------------------- server.c | 12 ------------ 5 files changed, 14 insertions(+), 34 deletions(-) diff --git a/README.rst b/README.rst index 33200e4..7f44db6 100644 --- a/README.rst +++ b/README.rst @@ -82,7 +82,8 @@ documentation how to configure alfred in this case. In any event, you can still run alfred from the command line. The relevant options are (for a full list of options, run alfred -h): - -i, --interface specify the interface to listen on + -i, --interface specify the interface to listen on. use 'none' + to disable interface operations -b specify the batman-adv interface configured on the system (default: bat0). use 'none' to disable the batman-adv based best server selection @@ -90,6 +91,9 @@ list of options, run alfred -h): accepts data from secondaries and syncs it with other primaries +The interface option '-i' is optional. If interface 'none' is specified, the +alfred daemon will not communicate with other alfred instances on the +network unless the interface list is modified at runtime via the unix socket. The -b option is optional, and only needed if you run alfred on a batman-adv interface not called bat0, or if you don't use batman-adv at all (use '-b none'). In this case, alfred will still work but will not be able to diff --git a/alfred.h b/alfred.h index d844261..57d7daf 100644 --- a/alfred.h +++ b/alfred.h @@ -182,7 +182,6 @@ int unix_sock_req_data_finish(struct globals *globals, /* vis.c */ int vis_update_data(struct globals *globals); /* netsock.c */ -int netsock_open_all(struct globals *globals); size_t netsocket_count_interfaces(struct globals *globals); void netsock_close_all(struct globals *globals); int netsock_set_interfaces(struct globals *globals, char *interfaces); diff --git a/man/alfred.8 b/man/alfred.8 index 18e008e..ff9b315 100644 --- a/man/alfred.8 +++ b/man/alfred.8 @@ -95,12 +95,16 @@ Change the alfred server to use the new \fBinterface\fP(s) .SH SERVER OPTIONS .TP \fB\-i\fP, \fB\-\-interface\fP \fIiface\fP -Specify the interface (or comma separated list of interfaces) to listen on +Specify the interface (or comma separated list of interfaces) to listen on. +Use 'none' to disable interface operations. .TP \fB\-b\fP \fIbatmanif\fP Specify the batman-adv interface configured on the system (default: bat0). Use 'none' to disable the batman-adv based best server selection. +The interface option \fB\-i\fP is optional. If interface 'none' is specified, the +alfred daemon will not communicate with other alfred instances on the +network unless the interface list is modified at runtime via the unix socket. The \fB\-b\fP option is optional, and only needed if you run alfred on a batman-adv interface not called bat0, or if you don't use batman-adv at all (use '\fB\-b\fP none'). In this case, alfred will still work but will not be diff --git a/netsock.c b/netsock.c index 84b0ec3..7bc49b4 100644 --- a/netsock.c +++ b/netsock.c @@ -116,6 +116,10 @@ int netsock_set_interfaces(struct globals *globals, char *interfaces) netsock_close_all(globals); + /* interface 'none' disables all interface operations */ + if (strcmp(interfaces, "none") == 0) + return 0; + input = interfaces; while ((token = strtok_r(input, ",", &saveptr))) { input = NULL; @@ -452,25 +456,6 @@ err: return -1; } -int netsock_open_all(struct globals *globals) -{ - int num_socks = 0; - int ret; - struct interface *interface; - - list_for_each_entry(interface, &globals->interfaces, list) { - if (globals->ipv4mode) - ret = netsock_open4(interface); - else - ret = netsock_open(interface); - - if (ret >= 0) - num_socks++; - } - - return num_socks; -} - size_t netsocket_count_interfaces(struct globals *globals) { struct interface *interface; diff --git a/server.c b/server.c index 85bf453..39206bf 100644 --- a/server.c +++ b/server.c @@ -372,7 +372,6 @@ int alfred_server(struct globals *globals) struct timespec last_check, now, tv; fd_set fds, errfds; size_t num_interfaces; - int num_socks; if (create_hashes(globals)) return -1; @@ -380,11 +379,6 @@ int alfred_server(struct globals *globals) if (unix_sock_open_daemon(globals)) return -1; - if (list_empty(&globals->interfaces)) { - fprintf(stderr, "Can't start server: interface missing\n"); - return -1; - } - if (strcmp(globals->mesh_iface, "none") != 0 && batadv_interface_check(globals->mesh_iface) < 0 && !globals->force) { @@ -393,12 +387,6 @@ int alfred_server(struct globals *globals) return -1; } - num_socks = netsock_open_all(globals); - if (num_socks <= 0 && !globals->force) { - fprintf(stderr, "Failed to open interfaces\n"); - return -1; - } - num_interfaces = netsocket_count_interfaces(globals); if (num_interfaces > 1 && globals->opmode == OPMODE_SECONDARY) { fprintf(stderr, "More than one interface specified in secondary mode\n"); From patchwork Sun Jan 2 11:31:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Lindner X-Patchwork-Id: 18438 X-Patchwork-Delegate: sw@simonwunderlich.de Return-Path: X-Original-To: patchwork@open-mesh.org Delivered-To: patchwork@open-mesh.org Received: from diktynna.open-mesh.org (localhost [IPv6:::1]) by diktynna.open-mesh.org (Postfix) with ESMTP id 87EC983EA5; Sun, 2 Jan 2022 12:32:30 +0100 (CET) Received: from s2.neomailbox.net (s2.neomailbox.net [5.148.176.60]) by diktynna.open-mesh.org (Postfix) with ESMTPS id C078A83E4F for ; Sun, 2 Jan 2022 12:32:26 +0100 (CET) From: Marek Lindner To: b.a.t.m.a.n@lists.open-mesh.org Subject: [PATCH 3/4] alfred: introduce 'change batman-adv interface' IPC call Date: Sun, 2 Jan 2022 12:31:35 +0100 Message-Id: <20220102113136.470299-3-mareklindner@neomailbox.ch> In-Reply-To: <20220102113136.470299-1-mareklindner@neomailbox.ch> References: <3748133.vRqKQLy7FI@rousseau> <20220102113136.470299-1-mareklindner@neomailbox.ch> MIME-Version: 1.0 ARC-Authentication-Results: i=1; diktynna.open-mesh.org; dkim=none; spf=pass (diktynna.open-mesh.org: domain of mareklindner@neomailbox.ch designates 5.148.176.60 as permitted sender) smtp.mailfrom=mareklindner@neomailbox.ch; dmarc=none ARC-Seal: i=1; s=20121; d=open-mesh.org; t=1641123147; a=rsa-sha256; cv=none; b=KEZ/uPVEgfT6NX56GVNgYkarM2pd73bIRznbKkKmRGwNEdr4I3Kz7tGs9zjkemV/JOehHV +eVA07ctShQbHMQATcoq8CRXFnPTv2hPE0Cvn+YNvKboCkycEPpvjqVn5RnjcTUXkoqGmc YUg4FeSpRDSsJByXkKwUWg/X60uaB8g= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=open-mesh.org; s=20121; t=1641123147; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=J2KkfWWEMjXIJvlCOcfJAz638xf1rnGLP24QdM1pI8U=; b=C6OUn4iHFXYu6grzBDoeCocTwycJn6CXoJMytTBQQTTftS17BBnk9l5hqO8Q5wjlDvr301 0lR9kx9AMkGBB+LNn7e979BiXVvTXJ27MTfVaPoc2FrMfJSOJAT5o9t9jfgpb7oDkT2RHl H/YzLEx8mIzAL5os4u4219rypsi+dxo= Message-ID-Hash: 3JHEEIZJFNFSOX4ID5ICWKXSVYWO2K6L X-Message-ID-Hash: 3JHEEIZJFNFSOX4ID5ICWKXSVYWO2K6L X-MailFrom: mareklindner@neomailbox.ch X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-b.a.t.m.a.n.lists.open-mesh.org-0; header-match-b.a.t.m.a.n.lists.open-mesh.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header CC: Marek Lindner X-Mailman-Version: 3.2.1 Precedence: list Reply-To: The list for a Better Approach To Mobile Ad-hoc Networking List-Id: The list for a Better Approach To Mobile Ad-hoc Networking Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: The batman-adv interface used by alfred can be changed at runtime by sending the CHANGE_BAT_IFACE command via unix socket. Signed-off-by: Marek Lindner --- alfred.h | 4 +++- client.c | 37 +++++++++++++++++++++++++++++++++++++ main.c | 10 +++++++++- man/alfred.8 | 3 +++ packet.h | 14 ++++++++++++++ unix_sock.c | 27 ++++++++++++++++++++++++++- 6 files changed, 92 insertions(+), 3 deletions(-) diff --git a/alfred.h b/alfred.h index 57d7daf..0fc6dc6 100644 --- a/alfred.h +++ b/alfred.h @@ -89,6 +89,7 @@ enum clientmode { CLIENT_SET_DATA, CLIENT_MODESWITCH, CLIENT_CHANGE_INTERFACE, + CLIENT_CHANGE_BAT_IFACE, }; struct interface { @@ -110,7 +111,7 @@ struct globals { char *change_interface; struct server *best_server; /* NULL if we are a server ourselves */ - const char *mesh_iface; + char *mesh_iface; enum opmode opmode; enum clientmode clientmode; int clientmode_arg; @@ -150,6 +151,7 @@ int alfred_client_request_data(struct globals *globals); int alfred_client_set_data(struct globals *globals); int alfred_client_modeswitch(struct globals *globals); int alfred_client_change_interface(struct globals *globals); +int alfred_client_change_bat_iface(struct globals *globals); /* recv.c */ int recv_alfred_packet(struct globals *globals, struct interface *interface, int recv_sock); diff --git a/client.c b/client.c index dc643f3..e1107bf 100644 --- a/client.c +++ b/client.c @@ -296,3 +296,40 @@ int alfred_client_change_interface(struct globals *globals) return 0; } + +int alfred_client_change_bat_iface(struct globals *globals) +{ + unsigned char buf[MAX_PAYLOAD]; + struct alfred_change_bat_iface_v0 *change_bat_iface; + int ret, len; + size_t interface_len; + + if (unix_sock_open_client(globals)) + return -1; + + interface_len = strlen(globals->mesh_iface); + if (interface_len > sizeof(change_bat_iface->bat_iface)) { + fprintf(stderr, "%s: batman-adv interface name list too long, not changing\n", + __func__); + return 0; + } + + change_bat_iface = (struct alfred_change_bat_iface_v0 *)buf; + len = sizeof(*change_bat_iface); + + change_bat_iface->header.type = ALFRED_CHANGE_BAT_IFACE; + change_bat_iface->header.version = ALFRED_VERSION; + change_bat_iface->header.length = htons(len - sizeof(change_bat_iface->header)); + strncpy(change_bat_iface->bat_iface, globals->mesh_iface, + sizeof(change_bat_iface->bat_iface)); + change_bat_iface->bat_iface[sizeof(change_bat_iface->bat_iface) - 1] = '\0'; + + ret = write(globals->unix_sock, buf, len); + if (ret != len) + fprintf(stderr, "%s: only wrote %d of %d bytes: %s\n", + __func__, ret, len, strerror(errno)); + + unix_sock_close(globals); + + return 0; +} diff --git a/main.c b/main.c index ad317cf..2cb6d44 100644 --- a/main.c +++ b/main.c @@ -37,6 +37,7 @@ static void alfred_usage(void) printf(" -M, --modeswitch primary switch daemon to mode primary\n"); printf(" secondary switch daemon to mode secondary\n"); printf(" -I, --change-interface [interface] change to the specified interface(s)\n"); + printf(" -B, --change-bat-iface [interface] change to the specified batman-adv interface\n"); printf("\n"); printf("server mode options:\n"); printf(" -i, --interface specify the interface (or comma separated list of interfaces) to listen on\n"); @@ -160,6 +161,7 @@ static struct globals *alfred_init(int argc, char *argv[]) {"req-version", required_argument, NULL, 'V'}, {"modeswitch", required_argument, NULL, 'M'}, {"change-interface", required_argument, NULL, 'I'}, + {"change-bat-iface", required_argument, NULL, 'B'}, {"unix-path", required_argument, NULL, 'u'}, {"update-command", required_argument, NULL, 'c'}, {"version", no_argument, NULL, 'v'}, @@ -194,7 +196,7 @@ static struct globals *alfred_init(int argc, char *argv[]) time_random_seed(); - while ((opt = getopt_long(argc, argv, "ms:r:hi:b:vV:M:I:u:dc:p:4:f", long_options, + while ((opt = getopt_long(argc, argv, "ms:r:hi:b:vV:M:I:B:u:dc:p:4:f", long_options, &opt_ind)) != -1) { switch (opt) { case 'r': @@ -252,6 +254,10 @@ static struct globals *alfred_init(int argc, char *argv[]) globals->clientmode = CLIENT_CHANGE_INTERFACE; globals->change_interface = strdup(optarg); break; + case 'B': + globals->clientmode = CLIENT_CHANGE_BAT_IFACE; + globals->mesh_iface = strdup(optarg); + break; case 'u': globals->unix_path = optarg; break; @@ -313,6 +319,8 @@ int main(int argc, char *argv[]) return alfred_client_modeswitch(globals); case CLIENT_CHANGE_INTERFACE: return alfred_client_change_interface(globals); + case CLIENT_CHANGE_BAT_IFACE: + return alfred_client_change_bat_iface(globals); } return 0; diff --git a/man/alfred.8 b/man/alfred.8 index ff9b315..74814e0 100644 --- a/man/alfred.8 +++ b/man/alfred.8 @@ -91,6 +91,9 @@ to 0 ('\fB\-V\fP 0'). .TP \fB\-I\fP, \fB\-\-change\-interface\fP \fIinterface\fP Change the alfred server to use the new \fBinterface\fP(s) +.TP +\fB\-B\fP, \fB\-\-change\-bat\-iface\fP \fIinterface\fP +Change the alfred server to use the new \fBbatman-adv interface\fP . .SH SERVER OPTIONS .TP diff --git a/packet.h b/packet.h index 678f939..94c6a77 100644 --- a/packet.h +++ b/packet.h @@ -68,6 +68,7 @@ enum alfred_packet_type { ALFRED_STATUS_ERROR = 4, ALFRED_MODESWITCH = 5, ALFRED_CHANGE_INTERFACE = 6, + ALFRED_CHANGE_BAT_IFACE = 7, }; /* packets */ @@ -147,6 +148,19 @@ struct alfred_change_interface_v0 { char ifaces[IFNAMSIZ * 16]; } __packed; +/** + * struct alfred_change_bat_iface_v0 - Request to change the + * batman-adv interface + * @header: TLV header describing the complete packet + * @bat_iface: interface to be changed to + * + * Sent to the daemon by client + */ +struct alfred_change_bat_iface_v0 { + struct alfred_tlv header; + char bat_iface[IFNAMSIZ]; +} __packed; + /** * struct alfred_status_v0 - Status info of a transaction * @header: TLV header describing the complete packet diff --git a/unix_sock.c b/unix_sock.c index d9ad07b..bc39199 100644 --- a/unix_sock.c +++ b/unix_sock.c @@ -345,6 +345,27 @@ err: return ret; } +static int +unix_sock_change_bat_iface(struct globals *globals, + struct alfred_change_bat_iface_v0 *change_bat_iface, + int client_sock) +{ + int len, ret = -1; + + len = ntohs(change_bat_iface->header.length); + + if (len < (int)(sizeof(*change_bat_iface) - sizeof(change_bat_iface->header))) + goto err; + + free(globals->mesh_iface); + globals->mesh_iface = strdup(change_bat_iface->bat_iface); + + ret = 0; +err: + close(client_sock); + return ret; +} + int unix_sock_read(struct globals *globals) { int client_sock; @@ -402,7 +423,11 @@ int unix_sock_read(struct globals *globals) (struct alfred_change_interface_v0 *)packet, client_sock); break; - + case ALFRED_CHANGE_BAT_IFACE: + ret = unix_sock_change_bat_iface(globals, + (struct alfred_change_bat_iface_v0 *)packet, + client_sock); + break; default: /* unknown packet type */ ret = -1; From patchwork Sun Jan 2 11:31:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Lindner X-Patchwork-Id: 18439 X-Patchwork-Delegate: sw@simonwunderlich.de Return-Path: X-Original-To: patchwork@open-mesh.org Delivered-To: patchwork@open-mesh.org Received: from diktynna.open-mesh.org (localhost [IPv6:::1]) by diktynna.open-mesh.org (Postfix) with ESMTP id 189FE83EC7; Sun, 2 Jan 2022 12:32:41 +0100 (CET) Received: from s2.neomailbox.net (s2.neomailbox.net [5.148.176.60]) by diktynna.open-mesh.org (Postfix) with ESMTPS id 5E66A83E7C for ; Sun, 2 Jan 2022 12:32:38 +0100 (CET) From: Marek Lindner To: b.a.t.m.a.n@lists.open-mesh.org Subject: [PATCH 4/4] alfred: introduce 'server status' IPC call Date: Sun, 2 Jan 2022 12:31:36 +0100 Message-Id: <20220102113136.470299-4-mareklindner@neomailbox.ch> In-Reply-To: <20220102113136.470299-1-mareklindner@neomailbox.ch> References: <3748133.vRqKQLy7FI@rousseau> <20220102113136.470299-1-mareklindner@neomailbox.ch> MIME-Version: 1.0 ARC-Authentication-Results: i=1; diktynna.open-mesh.org; dkim=none; spf=pass (diktynna.open-mesh.org: domain of mareklindner@neomailbox.ch designates 5.148.176.60 as permitted sender) smtp.mailfrom=mareklindner@neomailbox.ch; dmarc=none ARC-Seal: i=1; s=20121; d=open-mesh.org; t=1641123158; a=rsa-sha256; cv=none; b=T5p5MKjmoEh3IHmUulKbH+mkG5uAYAQ/G80uqfmx76LYwksHcJSWVluBnLQA/logXvv0qV DQe/jRZAlQARgNXX293lkacyyjjYIXbyFvF99RjY7UEERHH3U3JhWUFdW3fICzX2IOKkqF +AtjlGcd1qjCon6X1+eKA9ghbuFojDw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=open-mesh.org; s=20121; t=1641123158; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=YlKSHDHKcX/W4MbGRt8y7KI5R/GfDahgwGzQFgRyKk4=; b=URWtjwh0y64ES0B/Kd5PGyBOgjYXsHSJKg/E/9x/0zfDOjfzvg3Nc8MFhq1dkZMu4SC2rt RatMh8sTBOHRP6TFi0Cry5kG6Wklo7yI4CzNGlktwoHfGKXfXm7VlQTNwTxwBi4i50H64q 7LLpzhU7G9di61ga+8AFsxVR9Ld96Rg= Message-ID-Hash: CHJL7G3FDBUKHNKKK7J5MGWPCPXONXA4 X-Message-ID-Hash: CHJL7G3FDBUKHNKKK7J5MGWPCPXONXA4 X-MailFrom: mareklindner@neomailbox.ch X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-b.a.t.m.a.n.lists.open-mesh.org-0; header-match-b.a.t.m.a.n.lists.open-mesh.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header CC: Marek Lindner X-Mailman-Version: 3.2.1 Precedence: list Reply-To: The list for a Better Approach To Mobile Ad-hoc Networking List-Id: The list for a Better Approach To Mobile Ad-hoc Networking Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: The 'server status' call exports the 'mode' as well as interface status via IPC. Both parameters can be modified at runtime via the IPC and as such, the current configuration is dynamic and not necessarily obvious. The server status 'request' and 'reply' packet types are added to allow the IPC client to initiate the status retrieval. The server will respond with the 'reply' message. Signed-off-by: Marek Lindner --- alfred.h | 2 ++ client.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++ main.c | 9 +++++- man/alfred.8 | 3 ++ packet.h | 26 ++++++++++++++++ unix_sock.c | 50 ++++++++++++++++++++++++++++++ 6 files changed, 176 insertions(+), 1 deletion(-) diff --git a/alfred.h b/alfred.h index 0fc6dc6..8ee7b21 100644 --- a/alfred.h +++ b/alfred.h @@ -90,6 +90,7 @@ enum clientmode { CLIENT_MODESWITCH, CLIENT_CHANGE_INTERFACE, CLIENT_CHANGE_BAT_IFACE, + CLIENT_SERVER_STATUS, }; struct interface { @@ -152,6 +153,7 @@ int alfred_client_set_data(struct globals *globals); int alfred_client_modeswitch(struct globals *globals); int alfred_client_change_interface(struct globals *globals); int alfred_client_change_bat_iface(struct globals *globals); +int alfred_client_server_status(struct globals *globals); /* recv.c */ int recv_alfred_packet(struct globals *globals, struct interface *interface, int recv_sock); diff --git a/client.c b/client.c index e1107bf..d540a9f 100644 --- a/client.c +++ b/client.c @@ -333,3 +333,90 @@ int alfred_client_change_bat_iface(struct globals *globals) return 0; } + +int alfred_client_server_status(struct globals *globals) +{ + unsigned char buf[MAX_PAYLOAD]; + struct alfred_server_status_req_v0 *status_req; + struct alfred_server_status_rep_v0 *status_rep; + struct alfred_tlv *packet; + int ret, len, headsize, i; + + if (unix_sock_open_client(globals)) + return -1; + + status_req = (struct alfred_server_status_req_v0 *)buf; + len = sizeof(*status_req); + + status_req->header.type = ALFRED_SERVER_STATUS; + status_req->header.version = ALFRED_VERSION; + status_req->header.length = 0; + + ret = write(globals->unix_sock, buf, len); + if (ret != len) + fprintf(stderr, "%s: only wrote %d of %d bytes: %s\n", + __func__, ret, len, strerror(errno)); + + len = read(globals->unix_sock, buf, sizeof(buf)); + if (len <= 0) { + perror("read from unix socket failed"); + goto err; + } + + ret = -1; + + /* drop too small packets */ + headsize = sizeof(*packet); + if (len < headsize) { + perror("unexpected header size received from unix socket"); + goto err; + } + + packet = (struct alfred_tlv *)buf; + + if ((len - headsize) < ((int)ntohs(packet->length))) { + perror("unexpected packet size received from unix socket"); + goto err; + } + + if (packet->version != ALFRED_VERSION) { + perror("alfred version mismatch"); + goto err; + } + + status_rep = (struct alfred_server_status_rep_v0 *)buf; + headsize = ntohs(status_rep->header.length); + + if (headsize < (int)(sizeof(*status_rep) - sizeof(status_rep->header))) + goto err; + + fprintf(stdout, "alfred status:\n"); + + switch (status_rep->mode) { + case ALFRED_MODESWITCH_SECONDARY: + fprintf(stdout, "- mode: secondary\n"); + break; + case ALFRED_MODESWITCH_PRIMARY: + fprintf(stdout, "- mode: primary\n"); + break; + default: + fprintf(stderr, "- mode: unknown\n"); + break; + } + + fprintf(stderr, "- interfaces:\n"); + + for (i = 0; i < 16; i++) { + if (strlen(status_rep->ifaces[i].name) == 0) + continue; + + fprintf(stderr, "\t- name: %s\n", + status_rep->ifaces[i].name); + } + + fprintf(stdout, "- batman-adv interface: %s\n", status_rep->bat_iface); + +err: + unix_sock_close(globals); + return 0; +} diff --git a/main.c b/main.c index 2cb6d44..e2ac576 100644 --- a/main.c +++ b/main.c @@ -38,6 +38,7 @@ static void alfred_usage(void) printf(" secondary switch daemon to mode secondary\n"); printf(" -I, --change-interface [interface] change to the specified interface(s)\n"); printf(" -B, --change-bat-iface [interface] change to the specified batman-adv interface\n"); + printf(" -S, --server-status request server status info such as mode & interfaces\n"); printf("\n"); printf("server mode options:\n"); printf(" -i, --interface specify the interface (or comma separated list of interfaces) to listen on\n"); @@ -162,6 +163,7 @@ static struct globals *alfred_init(int argc, char *argv[]) {"modeswitch", required_argument, NULL, 'M'}, {"change-interface", required_argument, NULL, 'I'}, {"change-bat-iface", required_argument, NULL, 'B'}, + {"server-status", required_argument, NULL, 'S'}, {"unix-path", required_argument, NULL, 'u'}, {"update-command", required_argument, NULL, 'c'}, {"version", no_argument, NULL, 'v'}, @@ -196,7 +198,7 @@ static struct globals *alfred_init(int argc, char *argv[]) time_random_seed(); - while ((opt = getopt_long(argc, argv, "ms:r:hi:b:vV:M:I:B:u:dc:p:4:f", long_options, + while ((opt = getopt_long(argc, argv, "ms:r:hi:b:vV:M:I:B:Su:dc:p:4:f", long_options, &opt_ind)) != -1) { switch (opt) { case 'r': @@ -258,6 +260,9 @@ static struct globals *alfred_init(int argc, char *argv[]) globals->clientmode = CLIENT_CHANGE_BAT_IFACE; globals->mesh_iface = strdup(optarg); break; + case 'S': + globals->clientmode = CLIENT_SERVER_STATUS; + break; case 'u': globals->unix_path = optarg; break; @@ -321,6 +326,8 @@ int main(int argc, char *argv[]) return alfred_client_change_interface(globals); case CLIENT_CHANGE_BAT_IFACE: return alfred_client_change_bat_iface(globals); + case CLIENT_SERVER_STATUS: + return alfred_client_server_status(globals); } return 0; diff --git a/man/alfred.8 b/man/alfred.8 index 74814e0..cf0eafc 100644 --- a/man/alfred.8 +++ b/man/alfred.8 @@ -94,6 +94,9 @@ Change the alfred server to use the new \fBinterface\fP(s) .TP \fB\-B\fP, \fB\-\-change\-bat\-iface\fP \fIinterface\fP Change the alfred server to use the new \fBbatman-adv interface\fP +.TP +\fB\-S\fP, \fB\-\-server\-status\fP +Request server status information such as mode & interfaces\fP . .SH SERVER OPTIONS .TP diff --git a/packet.h b/packet.h index 94c6a77..b9e1f2e 100644 --- a/packet.h +++ b/packet.h @@ -69,6 +69,7 @@ enum alfred_packet_type { ALFRED_MODESWITCH = 5, ALFRED_CHANGE_INTERFACE = 6, ALFRED_CHANGE_BAT_IFACE = 7, + ALFRED_SERVER_STATUS = 8, }; /* packets */ @@ -159,6 +160,31 @@ struct alfred_change_interface_v0 { struct alfred_change_bat_iface_v0 { struct alfred_tlv header; char bat_iface[IFNAMSIZ]; +}; + +/** + * struct alfred_server_status_req_v0 - server status request + * @header: TLV header describing the complete packet + * + * Sent to the daemon by client + */ +struct alfred_server_status_req_v0 { + struct alfred_tlv header; +} __packed; + +/** + * struct alfred_server_status_req_v0 - server status reply + * @header: TLV header describing the complete packet + * + * Sent by the daemon to client in response to status request + */ +struct alfred_server_status_rep_v0 { + struct alfred_tlv header; + uint8_t mode; + struct { + char name[IFNAMSIZ]; + } ifaces[16]; + char bat_iface[IFNAMSIZ]; } __packed; /** diff --git a/unix_sock.c b/unix_sock.c index bc39199..22a6805 100644 --- a/unix_sock.c +++ b/unix_sock.c @@ -366,6 +366,53 @@ err: return ret; } +static int unix_sock_server_status(struct globals *globals, int client_sock) +{ + unsigned char buf[MAX_PAYLOAD]; + struct alfred_server_status_rep_v0 *status_rep; + struct interface *interface; + int ret, len, iface_count; + + status_rep = (struct alfred_server_status_rep_v0 *)buf; + len = sizeof(*status_rep); + + status_rep->header.type = ALFRED_SERVER_STATUS; + status_rep->header.version = ALFRED_VERSION; + status_rep->header.length = htons(len - sizeof(status_rep->header)); + + switch (globals->opmode) { + case OPMODE_SECONDARY: + status_rep->mode = ALFRED_MODESWITCH_SECONDARY; + break; + case OPMODE_PRIMARY: + status_rep->mode = ALFRED_MODESWITCH_PRIMARY; + break; + default: + break; + } + + iface_count = 0; + + list_for_each_entry(interface, &globals->interfaces, list) { + strncpy(status_rep->ifaces[iface_count].name, + interface->interface, + sizeof(status_rep->ifaces[iface_count].name)); + + iface_count++; + } + + strncpy(status_rep->bat_iface, globals->mesh_iface, + sizeof(status_rep->bat_iface)); + + ret = write(client_sock, buf, len); + if (ret == len) + return 0; + + fprintf(stderr, "%s: only wrote %d of %d bytes: %s\n", + __func__, ret, len, strerror(errno)); + return -1; +} + int unix_sock_read(struct globals *globals) { int client_sock; @@ -428,6 +475,9 @@ int unix_sock_read(struct globals *globals) (struct alfred_change_bat_iface_v0 *)packet, client_sock); break; + case ALFRED_SERVER_STATUS: + ret = unix_sock_server_status(globals, client_sock); + break; default: /* unknown packet type */ ret = -1;