diff --git a/alfred.h b/alfred.h
index 9ab92a2..598d38b 100644
--- a/alfred.h
+++ b/alfred.h
@@ -33,6 +33,9 @@
 #define FIXED_TLV_LEN(__tlv_type) \
 	htons(sizeof(__tlv_type) - sizeof(__tlv_type.header))
 
+#define FIXED_TLV_LEN_PTR(__tlv_type) \
+	htons(sizeof(*__tlv_type) - sizeof(__tlv_type->header))
+
 enum data_source {
 	SOURCE_LOCAL = 0,
 	SOURCE_FIRST_HAND = 1,
@@ -93,6 +96,7 @@ enum clientmode {
 	CLIENT_MODESWITCH,
 	CLIENT_CHANGE_INTERFACE,
 	CLIENT_CHANGE_BAT_IFACE,
+	CLIENT_SERVER_STATUS,
 };
 
 struct interface {
@@ -155,6 +159,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 b5d8943..ab4bba6 100644
--- a/client.c
+++ b/client.c
@@ -325,3 +325,123 @@ int alfred_client_change_bat_iface(struct globals *globals)
 
 	return 0;
 }
+
+int alfred_client_server_status(struct globals *globals)
+{
+	struct alfred_server_status_net_iface_v0 *status_net_iface;
+	struct alfred_server_status_bat_iface_v0 *status_bat_iface;
+	struct alfred_server_status_op_mode_v0 *status_op_mode;
+	struct alfred_server_status_req_v0 status_req;
+	struct alfred_server_status_rep_v0 *status_rep;
+	int ret, tlvsize, headsize, len, consumed;
+	struct alfred_tlv *status_tlv;
+	uint8_t buf[MAX_PAYLOAD];
+
+	if (unix_sock_open_client(globals))
+		return -1;
+
+	len = sizeof(status_req);
+	memset(&status_req, 0, len);
+
+	status_req.header.type = ALFRED_SERVER_STATUS;
+	status_req.header.version = ALFRED_VERSION;
+	status_req.header.length = 0;
+
+	ret = write(globals->unix_sock, (unsigned char *)&status_req, 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;
+	status_rep = (struct alfred_server_status_rep_v0 *)buf;
+
+	/* drop too small packets */
+	headsize = sizeof(status_rep->header);
+	if (len < headsize) {
+		perror("unexpected header size received from unix socket");
+		goto err;
+	}
+
+	if ((len - headsize) < ((int)ntohs(status_rep->header.length))) {
+		perror("unexpected packet size received from unix socket");
+		goto err;
+	}
+
+	if (status_rep->header.version != ALFRED_VERSION) {
+		perror("alfred version mismatch");
+		goto err;
+	}
+
+	headsize = ntohs(status_rep->header.length);
+
+	if (headsize < (int)(sizeof(*status_rep) - sizeof(status_rep->header)))
+		goto err;
+
+	consumed = sizeof(*status_rep);
+
+	while (len - consumed > 0) {
+		if (len - consumed < (int)sizeof(*status_tlv))
+			break;
+
+		status_tlv = (struct alfred_tlv *)(buf + consumed);
+
+		if (status_tlv->version != ALFRED_VERSION)
+			break;
+
+		tlvsize = ntohs(status_tlv->length);
+		tlvsize += sizeof(*status_tlv);
+
+		if (len - consumed < tlvsize)
+			break;
+
+		switch (status_tlv->type) {
+		case ALFRED_SERVER_OP_MODE:
+			if (tlvsize != sizeof(*status_op_mode))
+				break;
+
+			status_op_mode = (struct alfred_server_status_op_mode_v0 *)(buf + consumed);
+
+			switch (status_op_mode->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;
+			}
+
+			break;
+		case ALFRED_SERVER_NET_IFACE:
+			if (tlvsize != sizeof(*status_net_iface))
+				break;
+
+			status_net_iface = (struct alfred_server_status_net_iface_v0 *)(buf + consumed);
+			fprintf(stdout, "- interface: %s\n", status_net_iface->net_iface);
+			fprintf(stdout, "\t- status: %s\n",
+				status_net_iface->active == 1 ? "active" : "inactive");
+			break;
+		case ALFRED_SERVER_BAT_IFACE:
+			if (tlvsize != sizeof(*status_bat_iface))
+				break;
+
+			status_bat_iface = (struct alfred_server_status_bat_iface_v0 *)(buf + consumed);
+			fprintf(stdout, "- batman-adv interface: %s\n", status_bat_iface->bat_iface);
+			break;
+		}
+
+		consumed += tlvsize;
+	}
+
+err:
+	unix_sock_close(globals);
+	return 0;
+}
diff --git a/main.c b/main.c
index d40a0cc..68d6efd 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..0c1a2eb 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,73 @@ struct alfred_change_interface_v0 {
 struct alfred_change_bat_iface_v0 {
 	struct alfred_tlv header;
 	char bat_iface[IFNAMSIZ];
+};
+
+/**
+ * enum alfred_packet_type - Types of packet stored in the main alfred_tlv
+ * @ALFRED_SERVER_MODE: Contains alfred mode information*
+ * @ALFRED_SERVER_NET_IFACE: Contains alfred network interface information*
+ * @ALFRED_SERVER_BAT_IFACE: Contains alfred batman interface information*
+ */
+enum alfred_server_status_type {
+	ALFRED_SERVER_OP_MODE = 0,
+	ALFRED_SERVER_NET_IFACE = 1,
+	ALFRED_SERVER_BAT_IFACE = 2,
+};
+
+/**
+ * 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_op_mode_v0 - server op mode status information
+ * @op_mode: active op mode
+ *
+ * Sent to the client by daemon in response to status request
+ */
+struct alfred_server_status_op_mode_v0 {
+	struct alfred_tlv header;
+	uint8_t mode;
+} __packed;
+
+/**
+ * struct alfred_server_status_net_iface_v0 - server net iface status information
+ * @net_iface: configured network interface
+ * @active: network interface active/inactive status info
+ *
+ * Sent to the client by daemon in response to status request
+ */
+struct alfred_server_status_net_iface_v0 {
+	struct alfred_tlv header;
+	char net_iface[IFNAMSIZ];
+	uint8_t active;
+} __packed;
+
+/**
+ * struct alfred_server_status_bat_iface_v0 - server bat iface status information
+ * @op_mode: configured batman interface
+ *
+ * Sent to the client by daemon in response to status request
+ */
+struct alfred_server_status_bat_iface_v0 {
+	struct alfred_tlv header;
+	char bat_iface[IFNAMSIZ];
+} __packed;
+
+/**
+ * struct alfred_server_status_rep_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;
 } __packed;
 
 /**
diff --git a/unix_sock.c b/unix_sock.c
index bc39199..a5a0196 100644
--- a/unix_sock.c
+++ b/unix_sock.c
@@ -366,6 +366,109 @@ err:
 	return ret;
 }
 
+static int unix_sock_server_status(struct globals *globals, int client_sock)
+{
+	struct alfred_server_status_net_iface_v0 *status_net_iface;
+	struct alfred_server_status_bat_iface_v0 *status_bat_iface;
+	struct alfred_server_status_op_mode_v0 *status_op_mode;
+	struct alfred_server_status_rep_v0 *status_rep;
+	struct interface *interface;
+	uint8_t buf[MAX_PAYLOAD];
+	int ret = -1;
+	int len = 0;
+
+	/* too large? - should never happen */
+	if (sizeof(*status_rep) + len > sizeof(buf)) {
+		fprintf(stderr, "ERROR: send buffer too small for server_status\n");
+		goto err;
+	}
+
+	status_rep = (struct alfred_server_status_rep_v0 *)buf;
+	status_rep->header.type = ALFRED_SERVER_STATUS;
+	status_rep->header.version = ALFRED_VERSION;
+
+	len += sizeof(*status_rep);
+
+	/* too large? - should never happen */
+	if (sizeof(*status_op_mode) + len > sizeof(buf)) {
+		fprintf(stderr, "ERROR: send buffer too small for server_status op_mode\n");
+		goto err;
+	}
+
+	status_op_mode = (struct alfred_server_status_op_mode_v0 *)(buf + len);
+	status_op_mode->header.type = ALFRED_SERVER_OP_MODE;
+	status_op_mode->header.version = ALFRED_VERSION;
+	status_op_mode->header.length = FIXED_TLV_LEN_PTR(status_op_mode);
+
+	switch (globals->opmode) {
+	case OPMODE_SECONDARY:
+		status_op_mode->mode = ALFRED_MODESWITCH_SECONDARY;
+		break;
+	case OPMODE_PRIMARY:
+		status_op_mode->mode = ALFRED_MODESWITCH_PRIMARY;
+		break;
+	default:
+		break;
+	}
+
+	len += sizeof(*status_op_mode);
+
+	list_for_each_entry(interface, &globals->interfaces, list) {
+		/* too large? - should never happen */
+		if (sizeof(*status_net_iface) + len > sizeof(buf)) {
+			fprintf(stderr, "ERROR: send buffer too small for server_status iface\n");
+			goto err;
+		}
+
+		status_net_iface = (struct alfred_server_status_net_iface_v0 *)(buf + len);
+		status_net_iface->header.type = ALFRED_SERVER_NET_IFACE;
+		status_net_iface->header.version = ALFRED_VERSION;
+		status_net_iface->header.length = FIXED_TLV_LEN_PTR(status_net_iface);
+
+		strncpy(status_net_iface->net_iface, interface->interface,
+			sizeof(status_net_iface->net_iface));
+		status_net_iface->net_iface[sizeof(status_net_iface->net_iface) - 1] = '\0';
+		if (interface->netsock > -1)
+			status_net_iface->active = 1;
+		else
+			status_net_iface->active = 0;
+
+		len += sizeof(*status_net_iface);
+	}
+
+	/* too large? - should never happen */
+	if (sizeof(*status_bat_iface) + len > sizeof(buf)) {
+		fprintf(stderr, "ERROR: send buffer too small for server_status bat_iface\n");
+		goto err;
+	}
+
+	status_bat_iface = (struct alfred_server_status_bat_iface_v0 *)(buf + len);
+	status_bat_iface->header.type = ALFRED_SERVER_BAT_IFACE;
+	status_bat_iface->header.version = ALFRED_VERSION;
+	status_bat_iface->header.length = FIXED_TLV_LEN_PTR(status_bat_iface);
+
+	strncpy(status_bat_iface->bat_iface, globals->mesh_iface,
+		sizeof(status_bat_iface->bat_iface));
+	status_bat_iface->bat_iface[sizeof(status_bat_iface->bat_iface) - 1] = '\0';
+
+	len += sizeof(*status_bat_iface);
+	status_rep->header.length = htons(len - sizeof(status_rep->header));
+
+	ret = write(client_sock, buf, len);
+	if (ret != len) {
+		fprintf(stderr, "%s: only wrote %d of %d bytes: %s\n",
+			__func__, ret, len, strerror(errno));
+		ret = -1;
+		goto err;
+	}
+
+	ret = 0;
+
+err:
+	close(client_sock);
+	return ret;
+}
+
 int unix_sock_read(struct globals *globals)
 {
 	int client_sock;
@@ -428,6 +531,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;
