In this commit, we fetch the monitor attributes
and present it in a user friendly manner.

Signed-off-by: Parthasarathy Bhuvaragan <[email protected]>
---
 include/linux/tipc_netlink.h |   8 +-
 tipc/link.c                  | 217 ++++++++++++++++++++++++++++++++++++++++++-
 tipc/node.c                  |  21 ++++-
 tipc/node.h                  |   2 +
 4 files changed, 236 insertions(+), 12 deletions(-)

diff --git a/include/linux/tipc_netlink.h b/include/linux/tipc_netlink.h
index c22f2796265f..63c80d1033dc 100644
--- a/include/linux/tipc_netlink.h
+++ b/include/linux/tipc_netlink.h
@@ -175,6 +175,8 @@ enum {
 enum {
        TIPC_NLA_MON_UNSPEC,
        TIPC_NLA_MON_REF,                       /* u32 */
+       TIPC_NLA_MON_ACTIVE,                    /* flag */
+       TIPC_NLA_MON_BEARER_NAME,               /* string */
        TIPC_NLA_MON_PEERCNT,                   /* u32 */
        TIPC_NLA_MON_LISTGEN,                   /* u32 */
        TIPC_NLA_MON_ACTIVATION_THRESHOLD,      /* u32 */
@@ -203,13 +205,15 @@ enum {
 enum {
        TIPC_NLA_MON_PEER_UNSPEC,
 
+       TIPC_NLA_MON_PEER_ADDR,                 /* u32 */
        TIPC_NLA_MON_PEER_DOMGEN,               /* u32 */
-       TIPC_NLA_MON_PEER_MEMBERS_APPLIED,      /* u32 */
+       TIPC_NLA_MON_PEER_APPLIED,              /* u32 */
        TIPC_NLA_MON_PEER_UPMAP,                /* u64 */
-       TIPC_NLA_MON_PEER_HEADMAP,              /* u64 */
        TIPC_NLA_MON_PEER_MEMBERS,              /* tlv */
+       TIPC_NLA_MON_PEER_UP,                   /* flag */
        TIPC_NLA_MON_PEER_HEAD,                 /* flag */
        TIPC_NLA_MON_PEER_LOCAL,                /* flag */
+       TIPC_NLA_MON_PEER_PAD,                  /* flag */
 
        __TIPC_NLA_MON_PEER_MAX,
        TIPC_NLA_MON_PEER_MAX = __TIPC_NLA_MON_PEER_MAX - 1
diff --git a/tipc/link.c b/tipc/link.c
index 42c48d4beed1..d4468d089048 100644
--- a/tipc/link.c
+++ b/tipc/link.c
@@ -22,6 +22,7 @@
 #include "cmdl.h"
 #include "msg.h"
 #include "link.h"
+#include "node.h"
 
 static int link_list_cb(const struct nlmsghdr *nlh, void *data)
 {
@@ -516,22 +517,228 @@ static int cmd_link_mon_set_prop(struct nlmsghdr *nlh, 
const struct cmd *cmd,
        return msg_doit(nlh, NULL, NULL);
 }
 
+static int map_get(uint64_t up_map, int i)
+{
+       return (up_map & (1 << i)) >> i;
+}
+
+const char dashes[] = 
"+-----------------------------------------------------------------------------+\n";
+const char head1[] =  "| Neighbor Monitoring Table for Node:             using 
Bearer:               |\n";
+const char head2[] =  "| Table Generation:       Cluster Members:        
Active:                     |\n";
+const char head3[] =  "| State:       S-Status  | D-Directly Monitored | 
Dom-Domain Generation       |\n";
+const char head4[] =  "|            U-Up/D-Down |     Y-Yes/N-No       |       
                      |\n";
+const char head5[] =  "|     Node   |  State  | Applied Node Status | 
[Non-Applied Node:Status]      |\n";
+const char head6[] =  "|            |S D Dom  |   5    10    15    20    25    
30    35    40    45  |\n";
+
+#define NODE_POS 37
+#define BEARER_POS 63
+#define TABLE_GEN 19
+#define PEER_CNT 42
+#define ACTIVE_POS 57
+
+#define MAX_NODE_LEN 13 /* 255.4095.4095 */
+#define STATUS_POS (MAX_NODE_LEN + 1)
+#define DIRECTLY_MON_POS (STATUS_POS + 2)
+#define DOM_GEN_POS (DIRECTLY_MON_POS + 2)
+#define MAX_DOM_GEN_LEN 5 /* 65535 */
+#define APPL_POS  (DOM_GEN_POS + MAX_DOM_GEN_LEN + 1)
+
+const char spaces[] = "                                                        
                       \n";
+
+#define MAX_LINE_LEN 80
+
+#define MAX_APPL_NODE_POS (MAX_LINE_LEN - 3)
+#define MAX_NON_APPL_NODE_POS (MAX_LINE_LEN - (MAX_NODE_LEN + 4))
+
+#define sprintp(__line, __pos, fmt, arg...)\
+({ \
+       int __p = __pos;\
+        do { \
+                char __str[128];\
+               sprintf(__str, fmt, ## arg); \
+               memcpy(&__line[__pos], __str, strlen(__str));\
+               __p += strlen(__str);\
+        } while(0);\
+        __p;\
+})
+
+static void link_mon_print_members(char *line, uint32_t applied,
+                                  unsigned long long up_map,
+                                  struct nlattr *attr_members)
+{
+       int pos, i;
+       char *state;
+       uint16_t member_cnt;
+       uint32_t *members;
+
+       pos = APPL_POS;
+
+       for (i = 0; i < applied; i++) {
+               if (i && !(i % 5)) {
+                       pos = sprintp(line, pos, " ");
+                       if (pos  > MAX_APPL_NODE_POS) {
+                               printf("%s", line);
+                               pos = 0;
+                               strcpy(line, spaces);
+                       }
+               }
+               state =  map_get(up_map, i) ? "U" : "D";
+               pos = sprintp(line, pos, "%s", state);
+       }
+
+       member_cnt = mnl_attr_get_payload_len(attr_members);
+       members = mnl_attr_get_payload(attr_members);
+
+       if (applied == member_cnt) {
+               printf("%s", line);
+               return;
+       }
+
+       pos = sprintp(line, pos, " [");
+       for (i = applied; i < member_cnt / sizeof(uint32_t); i++) {
+               if (pos  > MAX_APPL_NODE_POS) {
+                       sprintp(line, pos, " ]");
+                       printf("%s", line);
+                       pos = 0;
+                       strcpy(line, spaces);
+                       pos = sprintp(line, pos, " [");
+               }
+               pos = sprintp(line, pos, " %u.%u.%u", tipc_zone(members[i]),
+                             tipc_cluster(members[i]), tipc_node(members[i]));
+               state =  map_get(up_map, i) ? ":U" : ":D";
+               pos = sprintp(line, pos, "%s", state);
+       }
+       sprintp(line, pos, " ]");
+       printf("%s", line);
+
+}
+
+static int link_mon_peer_list_cb(const struct nlmsghdr *nlh, void *data)
+{
+       struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
+       struct nlattr *info[TIPC_NLA_MAX + 1] = {};
+       struct nlattr *attrs[TIPC_NLA_MON_PEER_MAX + 1] = {};
+       uint32_t addr;
+       uint32_t applied;
+       char line[128];
+
+       mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
+       if (!info[TIPC_NLA_MON_PEER])
+               return MNL_CB_ERROR;
+
+       strcpy(line, spaces);
+       mnl_attr_parse_nested(info[TIPC_NLA_MON_PEER], parse_attrs, attrs);
+
+       addr =  mnl_attr_get_u32(attrs[TIPC_NLA_MON_PEER_ADDR]);
+       sprintp(line, 0, "%u.%u.%u", tipc_zone(addr), tipc_cluster(addr),
+               tipc_node(addr));
+
+       if (attrs[TIPC_NLA_MON_PEER_HEAD] || attrs[TIPC_NLA_MON_PEER_LOCAL]) {
+               sprintp(line, DIRECTLY_MON_POS, "%s", "Y");
+       } else {
+               sprintp(line, DIRECTLY_MON_POS, "%s", "N");
+       }
+
+       if (attrs[TIPC_NLA_MON_PEER_UP]) {
+               sprintp(line, STATUS_POS, "%s", "U");
+       } else {
+               sprintp(line, STATUS_POS, "%s", "D");
+       }
+
+       if (attrs[TIPC_NLA_MON_PEER_DOMGEN]) {
+               sprintp(line, DOM_GEN_POS, "%u",
+                       mnl_attr_get_u32(attrs[TIPC_NLA_MON_PEER_DOMGEN]));
+       } else {
+               sprintp(line, DOM_GEN_POS, "%u", 0);
+       }
+
+       applied = mnl_attr_get_u32(attrs[TIPC_NLA_MON_PEER_APPLIED]);
+
+       if (!applied) {
+               printf("%s", line);
+               return MNL_CB_OK;
+       }
+
+       link_mon_print_members(line, applied,
+                              mnl_attr_get_u64(attrs[TIPC_NLA_MON_PEER_UPMAP]),
+                              attrs[TIPC_NLA_MON_PEER_MEMBERS]);
+
+       return MNL_CB_OK;
+}
+
+static int link_mon_peer_list(uint32_t mon_ref)
+{
+       struct nlmsghdr *nlh;
+       char buf[MNL_SOCKET_BUFFER_SIZE];
+       struct nlattr *nest;
+
+       if (!(nlh = msg_init(buf, TIPC_NL_MON_PEER_GET))) {
+               fprintf(stderr, "error, message initialisation failed\n");
+               return -1;
+       }
+
+       nest = mnl_attr_nest_start(nlh, TIPC_NLA_MON);
+       mnl_attr_put_u32(nlh, TIPC_NLA_MON_REF, mon_ref);
+       mnl_attr_nest_end(nlh, nest);
+
+       return msg_dumpit(nlh, link_mon_peer_list_cb, NULL);
+}
+
 static int link_mon_list_cb(const struct nlmsghdr *nlh, void *data)
 {
        struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
        struct nlattr *info[TIPC_NLA_MAX + 1] = {};
        struct nlattr *attrs[TIPC_NLA_MON_MAX + 1] = {};
+       uint32_t addr;
+       uint32_t peer_cnt;
+       uint32_t mon_ref;
+       char line[128];
+
+       if (tipc_node_get_addr(&addr))
+               return -1;
 
        mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
        if (!info[TIPC_NLA_MON])
                return MNL_CB_ERROR;
 
        mnl_attr_parse_nested(info[TIPC_NLA_MON], parse_attrs, attrs);
-       if (!attrs[TIPC_NLA_MON_ACTIVATION_THRESHOLD])
-               return MNL_CB_ERROR;
-
-       printf("Monitor Activation Threshold :%u\n",
-              mnl_attr_get_u32(attrs[TIPC_NLA_MON_ACTIVATION_THRESHOLD]));
+       peer_cnt = mnl_attr_get_u32(attrs[TIPC_NLA_MON_PEERCNT]);
+
+       printf(dashes);
+       strcpy(line, head1);
+       sprintp(line, NODE_POS, "<%u.%u.%u>", tipc_zone(addr),
+               tipc_cluster(addr), tipc_node(addr));
+       sprintp(line, BEARER_POS, "%s",
+               mnl_attr_get_str(attrs[TIPC_NLA_MON_BEARER_NAME]));
+       printf("%s", line);
+       printf(dashes);
+
+       strcpy(line, head2);
+       sprintp(line, TABLE_GEN, "%u",
+               mnl_attr_get_u32(attrs[TIPC_NLA_MON_LISTGEN]));
+       sprintp(line, PEER_CNT, "%u", peer_cnt);
+       if (attrs[TIPC_NLA_MON_ACTIVE]) {
+               sprintp(line, ACTIVE_POS, "%s", "Yes");
+       } else {
+               sprintp(line, ACTIVE_POS, "%s", "No");
+       }
+       printf("%s", line);
+
+       printf(dashes);
+       printf(head3);
+       printf(head4);
+       printf(dashes);
+       printf(head5);
+       printf(head6);
+#if 0
+       printf(head4);
+       printf(head5);
+#endif
+       printf(dashes);
+       if (peer_cnt) {
+               mon_ref = mnl_attr_get_u32(attrs[TIPC_NLA_MON_REF]);
+               link_mon_peer_list(mon_ref);
+       }
 
        return MNL_CB_OK;
 }
diff --git a/tipc/node.c b/tipc/node.c
index 163fb7432c36..1478d9fb3803 100644
--- a/tipc/node.c
+++ b/tipc/node.c
@@ -102,8 +102,7 @@ static int cmd_node_set_addr(struct nlmsghdr *nlh, const 
struct cmd *cmd,
        return msg_doit(nlh, NULL, NULL);
 }
 
-static int cmd_node_get_addr(struct nlmsghdr *nlh, const struct cmd *cmd,
-                            struct cmdl *cmdl, void *data)
+int tipc_node_get_addr(uint32_t *address)
 {
        int sk;
        socklen_t sz = sizeof(struct sockaddr_tipc);
@@ -122,10 +121,22 @@ static int cmd_node_get_addr(struct nlmsghdr *nlh, const 
struct cmd *cmd,
        }
        close(sk);
 
+       *address = addr.addr.id.node;
+       return 0;
+}
+
+static int cmd_node_get_addr(struct nlmsghdr *nlh, const struct cmd *cmd,
+                            struct cmdl *cmdl, void *data)
+{
+       uint32_t node;
+
+       if (tipc_node_get_addr(&node))
+               return -1;
+
        printf("<%u.%u.%u>\n",
-               tipc_zone(addr.addr.id.node),
-               tipc_cluster(addr.addr.id.node),
-               tipc_node(addr.addr.id.node));
+              tipc_zone(node),
+              tipc_cluster(node),
+              tipc_node(node));
 
        return 0;
 }
diff --git a/tipc/node.h b/tipc/node.h
index afee1fd06039..9aaa46e18d14 100644
--- a/tipc/node.h
+++ b/tipc/node.h
@@ -18,4 +18,6 @@ int cmd_node(struct nlmsghdr *nlh, const struct cmd *cmd, 
struct cmdl *cmdl,
             void *data);
 void cmd_node_help(struct cmdl *cmdl);
 
+int tipc_node_get_addr(uint32_t *address);
+
 #endif
-- 
2.1.4


------------------------------------------------------------------------------
Mobile security can be enabling, not merely restricting. Employees who
bring their own devices (BYOD) to work are irked by the imposition of MDM
restrictions. Mobile Device Manager Plus allows you to control only the
apps on BYO-devices by containerizing them, leaving personal data untouched!
https://ad.doubleclick.net/ddm/clk/304595813;131938128;j
_______________________________________________
tipc-discussion mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tipc-discussion

Reply via email to