On 2016-05-23 15:27, Parthasarathy Bhuvaragan wrote:
> In this commit, we fetch the monitor attributes
> and present it in a user friendly manner.
It would be nice with an snippet printout here. So we can see how it
might look.

> 
> 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 */
Can't you use the already existing bearer nest?

>       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";
Why isn't this just below the headX[] above?

> +
> +#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;\
> +})
Even though we might have control over the input this seems dangerous.
What do you think about using snprintf() for the __str print and passing
the max length of buffer we are copying into?

> +
> +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;
I don't think this should be a pointer. Can you keep it a normal char and
do state = condition ? 'U' : 'D'; ?

> +     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));
What's going on here?

>  
>       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
> 


------------------------------------------------------------------------------
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