b.a.t.m.a.n.lists.open-mesh.org archive mirror
 help / color / mirror / Atom feed
From: Marek Lindner <mareklindner@neomailbox.ch>
To: b.a.t.m.a.n@lists.open-mesh.org
Cc: Marek Lindner <mareklindner@neomailbox.ch>
Subject: [PATCH 3/4] alfred: introduce 'change batman-adv interface' IPC call
Date: Sun,  2 Jan 2022 12:31:35 +0100	[thread overview]
Message-ID: <20220102113136.470299-3-mareklindner@neomailbox.ch> (raw)
In-Reply-To: <20220102113136.470299-1-mareklindner@neomailbox.ch>

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 <mareklindner@neomailbox.ch>
---
 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;
-- 
2.32.0.rc0

  parent reply	other threads:[~2022-01-02 11:31 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-02 11:30 alfred: runtime configuration Marek Lindner
2022-01-02 11:31 ` [PATCH 1/4] alfred: remove meaningless printf() call Marek Lindner
2022-01-02 11:31   ` [PATCH 2/4] alfred: Allow operating without any interface specified Marek Lindner
2022-01-02 14:20     ` Sven Eckelmann
2022-01-02 19:01       ` Marek Lindner
2022-01-03  8:54         ` Sven Eckelmann
2022-01-02 11:31   ` Marek Lindner [this message]
2022-01-02 11:31   ` [PATCH 4/4] alfred: introduce 'server status' IPC call Marek Lindner
2022-01-02 14:43     ` Sven Eckelmann
2022-01-12 21:14       ` Marek Lindner
2022-01-20  8:25         ` Sven Eckelmann
2022-01-03  9:09     ` Sven Eckelmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220102113136.470299-3-mareklindner@neomailbox.ch \
    --to=mareklindner@neomailbox.ch \
    --cc=b.a.t.m.a.n@lists.open-mesh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).