Repository : ssh://git@diktynna/alfred
On branch : master
>---------------------------------------------------------------
commit b96cc742ef3e09f3357051783d449d542749970c
Author: Marek Lindner <mareklindner(a)neomailbox.ch>
Date: Sun Jan 2 12:31:35 2022 +0100
alfred: introduce 'change batman-adv interface' IPC call
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(a)neomailbox.ch>
Signed-off-by: Sven Eckelmann <sven(a)narfation.org>
>---------------------------------------------------------------
b96cc742ef3e09f3357051783d449d542749970c
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 d844261..26eb157 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 18e008e..4e002f0 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;