diff --git a/src/cntlr_commands_impl.c b/src/cntlr_commands_impl.c
index ad811de684f6f263645e0f1241f15d59eeac24c2..f3ca59109e30c8ffa2700ee48f746f2f908d4321 100644
--- a/src/cntlr_commands_impl.c
+++ b/src/cntlr_commands_impl.c
@@ -3328,31 +3328,134 @@ int COMMAND(disassociate_sta)(void *priv, void *args, void *out)
 }
 #endif
 
+
+static struct bh_topology_dev *topology_get_dev(struct controller *c, uint8_t *mac)
+{
+	struct bh_topology_dev *dev;
+
+	list_for_each_entry(dev, &c->topology.dev_list, list) {
+		if (!memcmp(dev->al_macaddr, mac, 6))
+			return dev;
+	}
+
+	return NULL;
+}
+
+static bool topology_dev_any_leaf(struct controller *c, struct bh_topology_dev *dev)
+{
+	int i, j;
+
+	for (i = 0; i < dev->number_of_interfaces; i++) {
+		if (dev->ifaces[i].number_of_neighbors == 0)
+			continue;
+		for (j = 0; j < dev->ifaces[i].number_of_neighbors; j++) {
+			struct bh_topology_dev *subdev;
+			subdev = topology_get_dev(c, dev->ifaces[i].neighbors_al_macs[j]);
+			if (subdev && subdev->bh.parent == dev)
+				return true;
+		}
+	}
+
+	return false;
+}
+
+static void topology_print_radio(struct controller *c, struct netif_radio *r, struct blob_buf *bb)
+{
+	char radio[256] = {};
+
+	/* Keep it short, user friendly */
+	snprintf(radio, sizeof(radio), "%u/%u",
+		 ctrl_radio_cur_opclass_ctrl_chan(r->radio_el),
+		 ctrl_radio_cur_opclass_max_bw(r->radio_el));
+
+	switch(r->radio_el->band) {
+	case BAND_2:
+		blobmsg_add_string(bb, "2g", radio);
+		break;
+	case BAND_5:
+		blobmsg_add_string(bb, "5g", radio);
+		break;
+	case BAND_6:
+		blobmsg_add_string(bb, "6g", radio);
+		break;
+	default:
+		break;
+	}
+}
+
+static void topology_print_node(struct controller *c, uint8_t *alid, struct blob_buf *bb)
+{
+	struct netif_radio *r = NULL;
+	struct node *n;
+
+	n = cntlr_find_node(c, alid);
+	if (!n)
+		return;
+
+	list_for_each_entry(r, &n->radiolist, list)
+		topology_print_radio(c, r, bb);
+}
+
+static void topology_add_hostname(struct bh_topology_dev *dev, struct blob_buf *bb)
+{
+	char buf[255] = {};
+	char macaddr[18] = {};
+
+	hwaddr_ntoa(dev->al_macaddr, macaddr);
+	if (dev->bh.depth == 0)
+		chrCmd(buf, sizeof(buf), "uci get system.@system[0].hostname");
+	else
+		chrCmd(buf, sizeof(buf), "grep %s /tmp/dhcp.leases | awk '{print $4}'", &macaddr[3]);
+
+	if (strlen(buf))
+		blobmsg_add_string(bb, "hostname", buf);
+}
+
+static void topology_print_dev(struct controller *c, struct bh_topology_dev *dev,
+			       struct blob_buf *bb)
+{
+	void *t, *a;
+	int i, j;
+
+	t = blobmsg_open_table(bb, "");
+	blobmsg_add_macaddr(bb, "alid", dev->al_macaddr);
+	topology_add_hostname(dev, bb);
+	if (dev->bh.own_iface)
+		blobmsg_add_string(bb, "media", i1905_media_type_to_str(dev->bh.own_iface->media_type));
+	topology_print_node(c, dev->al_macaddr, bb);
+
+	if (topology_dev_any_leaf(c, dev)) {
+		a = blobmsg_open_array(bb, "leafs");
+		for (i = 0; i < dev->number_of_interfaces; i++) {
+			if (dev->ifaces[i].number_of_neighbors == 0)
+				continue;
+
+			for (j = 0; j < dev->ifaces[i].number_of_neighbors; j++) {
+				struct bh_topology_dev *subdev;
+
+				subdev = topology_get_dev(c, dev->ifaces[i].neighbors_al_macs[j]);
+				if (subdev && subdev->bh.parent == dev)
+					topology_print_dev(c, subdev, bb);
+			}
+		}
+		blobmsg_close_array(bb, a);
+	}
+
+	blobmsg_close_table(bb, t);
+}
+
 int COMMAND(dump_topology)(void *priv, void *args, void *out)
 {
 	struct controller *c = (struct controller *)priv;
 	struct blob_buf *bb = (struct blob_buf *)out;
 	struct bh_topology_dev *dev = NULL;
-	void *t, *a;
 
-	t = blobmsg_open_table(bb, "topology");
-	blobmsg_add_u32(bb, "num_nodes", c->topology.num_devs);
-
-	a = blobmsg_open_array(bb, "node");
 	list_for_each_entry(dev, &c->topology.dev_list, list) {
-		void *tt;
-
-		tt = blobmsg_open_table(bb, "");
-		blobmsg_add_macaddr(bb, "alid", dev->al_macaddr);
-		blobmsg_add_u32(bb, "depth", dev->bh.depth);
-		blobmsg_add_u32(bb, "depth_wifi", dev->bh.wifi_hops_from_root);
-		if (dev->bh.parent)
-			blobmsg_add_macaddr(bb, "parent", dev->bh.parent->al_macaddr);
-
-		blobmsg_close_table(bb, tt);
+		if (dev->bh.depth == 0) {
+			topology_print_dev(c, dev, bb);
+			break;
+		}
 	}
-	blobmsg_close_array(bb, a);
-	blobmsg_close_table(bb, t);
 
 	return 0;
 }