Now, since the fmt (json, hr) handlers are in place, all can be output via these
newly deviced code parts.

Signed-off-by: Matthias Tafelmeier <matthias.tafelme...@gmx.net>
Suggested-by: Hagen Paul Pfeifer <ha...@jauu.net>
---
 misc/ss.c | 332 +++++++++++++++++++++++++++++---------------------------------
 1 file changed, 153 insertions(+), 179 deletions(-)

diff --git a/misc/ss.c b/misc/ss.c
index f563710..a760cf9 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -105,6 +105,7 @@ int show_sock_ctx = 0;
 int user_ent_hash_build_init = 0;
 int follow_events = 0;
 int json_output = 0;
+int json_first_elem = 1;
 
 int netid_width;
 int state_width;
@@ -113,6 +114,8 @@ int addr_width;
 int serv_width;
 int screen_width;
 
+enum out_fmt_type fmt_type = FMT_HR;
+
 static const char *TCP_PROTO = "tcp";
 static const char *UDP_PROTO = "udp";
 static const char *RAW_PROTO = "raw";
@@ -346,6 +349,16 @@ static FILE *ephemeral_ports_open(void)
 #define USER_ENT_HASH_SIZE     256
 struct user_ent *user_ent_hash[USER_ENT_HASH_SIZE];
 
+static void json_print_opening(void)
+{
+       if (json_output && json_first_elem) {
+               json_first_elem = 0;
+               printf("{\n");
+       } else if (json_output) {
+               printf(",\n{\n");
+       }
+}
+
 static int user_ent_hashfn(unsigned int ino)
 {
        int val = (ino >> 24) ^ (ino >> 16) ^ (ino >> 8) ^ ino;
@@ -791,7 +804,8 @@ do_numeric:
        return buf;
 }
 
-static void inet_addr_print(const inet_prefix *a, int port, unsigned int 
ifindex)
+static void inet_addr_print(const inet_prefix * a, int port,
+                           unsigned int ifindex, char *peer_kind)
 {
        char buf[1024];
        const char *ap = buf;
@@ -819,8 +833,8 @@ static void inet_addr_print(const inet_prefix *a, int port, 
unsigned int ifindex
                est_len -= strlen(ifname) + 1;  /* +1 for percent char */
        }
 
-       sock_addr_print_width(est_len, ap, ":", serv_width, 
resolve_service(port),
-                       ifname);
+       sock_addr_fmt(ap, est_len, ":", serv_width, resolve_service(port),
+                       ifname, peer_kind);
 }
 
 static int inet2_addr_match(const inet_prefix *a, const inet_prefix *p,
@@ -1352,21 +1366,28 @@ static void inet_stats_print(struct sockstat *s, int 
protocol)
 {
        char *buf = NULL;
 
-       sock_state_print(s, proto_name(protocol));
+       sock_state_fmt(s, sstate_name, proto_name(protocol),
+                       netid_width, state_width);
 
-       inet_addr_print(&s->local, s->lport, s->iface);
-       inet_addr_print(&s->remote, s->rport, 0);
+       if (json_output) {
+               printf("\t,\"peers\": {\n");
+       }
+       inet_addr_print(&s->local, s->lport, s->iface, "local");
+       inet_addr_print(&s->remote, s->rport, 0, "remote");
+       if (json_output) {
+               printf("}");
+       }
 
        if (show_proc_ctx || show_sock_ctx) {
                if (find_entry(s->ino, &buf,
-                               (show_proc_ctx & show_sock_ctx) ?
-                               PROC_SOCK_CTX : PROC_CTX) > 0) {
-                       printf(" users:(%s)", buf);
+                              (show_proc_ctx & show_sock_ctx) ?
+                              PROC_SOCK_CTX : PROC_CTX) > 0) {
+                       sock_users_fmt(buf);
                        free(buf);
                }
        } else if (show_users) {
                if (find_entry(s->ino, &buf, USERS) > 0) {
-                       printf(" users:(%s)", buf);
+                       sock_users_fmt(buf);
                        free(buf);
                }
        }
@@ -1470,16 +1491,16 @@ static int tcp_show_line(char *line, const struct 
filter *f, int family)
        inet_stats_print(&s.ss, IPPROTO_TCP);
 
        if (show_options)
-               tcp_timer_print(&s);
+               tcp_timer_fmt(&s);
 
        if (show_details) {
-               sock_details_print(&s.ss);
+               sock_details_fmt(&s.ss, GENERIC_DETAIL, 0, 0);
                if (opt[0])
-                       printf(" opt:\"%s\"", opt);
+                       opt_fmt(opt);
        }
 
        if (show_tcpinfo)
-               tcp_stats_print(&s);
+               tcp_stats_fmt(&s);
 
        printf("\n");
        return 0;
@@ -1523,31 +1544,14 @@ static void print_skmeminfo(struct rtattr *tb[], int 
attrtype)
                        const struct inet_diag_meminfo *minfo =
                                RTA_DATA(tb[INET_DIAG_MEMINFO]);
 
-                       printf(" mem:(r%u,w%u,f%u,t%u)",
-                                       minfo->idiag_rmem,
-                                       minfo->idiag_wmem,
-                                       minfo->idiag_fmem,
-                                       minfo->idiag_tmem);
+                       mem_fmt(minfo);
                }
                return;
        }
 
        skmeminfo = RTA_DATA(tb[attrtype]);
 
-       printf(" skmem:(r%u,rb%u,t%u,tb%u,f%u,w%u,o%u",
-              skmeminfo[SK_MEMINFO_RMEM_ALLOC],
-              skmeminfo[SK_MEMINFO_RCVBUF],
-              skmeminfo[SK_MEMINFO_WMEM_ALLOC],
-              skmeminfo[SK_MEMINFO_SNDBUF],
-              skmeminfo[SK_MEMINFO_FWD_ALLOC],
-              skmeminfo[SK_MEMINFO_WMEM_QUEUED],
-              skmeminfo[SK_MEMINFO_OPTMEM]);
-
-       if (RTA_PAYLOAD(tb[attrtype]) >=
-               (SK_MEMINFO_BACKLOG + 1) * sizeof(__u32))
-               printf(",bl%u", skmeminfo[SK_MEMINFO_BACKLOG]);
-
-       printf(")");
+       skmem_fmt(skmeminfo, tb, attrtype);
 }
 
 #define TCPI_HAS_OPT(info, opt) !!(info->tcpi_options & (opt))
@@ -1660,8 +1664,11 @@ static void tcp_show_info(const struct nlmsghdr *nlh, 
struct inet_diag_msg *r,
                s.bytes_received = info->tcpi_bytes_received;
                s.segs_out = info->tcpi_segs_out;
                s.segs_in = info->tcpi_segs_in;
-               tcp_stats_print(&s);
-               free(s.dctcp);
+               tcp_stats_fmt(&s);
+               if (s.dctcp)
+                       free(s.dctcp);
+               if (s.cong_alg)
+                       free(s.cong_alg);
        }
 }
 
@@ -1685,6 +1692,8 @@ static int inet_show_sock(struct nlmsghdr *nlh, struct 
filter *f, int protocol)
        s.iface         = r->id.idiag_if;
        s.sk            = cookie_sk_get(&r->id.idiag_cookie[0]);
 
+       json_print_opening();
+
        if (s.local.family == AF_INET) {
                s.local.bytelen = s.remote.bytelen = 4;
        } else {
@@ -1708,29 +1717,29 @@ static int inet_show_sock(struct nlmsghdr *nlh, struct 
filter *f, int protocol)
                t.timer = r->idiag_timer;
                t.timeout = r->idiag_expires;
                t.retrans = r->idiag_retrans;
-               tcp_timer_print(&t);
+               tcp_timer_fmt(&t);
        }
 
        if (show_details) {
-               sock_details_print(&s);
-               if (s.local.family == AF_INET6 && tb[INET_DIAG_SKV6ONLY]) {
-                       unsigned char v6only;
-                       v6only = *(__u8 *)RTA_DATA(tb[INET_DIAG_SKV6ONLY]);
-                       printf(" v6only:%u", v6only);
-               }
+               sock_details_fmt(&s, GENERIC_DETAIL, 0, 0);
                if (tb[INET_DIAG_SHUTDOWN]) {
                        unsigned char mask;
                        mask = *(__u8 *)RTA_DATA(tb[INET_DIAG_SHUTDOWN]);
-                       printf(" %c-%c", mask & 1 ? '-' : '<', mask & 2 ? '-' : 
'>');
+                       sock_conn_fmt(mask);
                }
        }
 
        if (show_mem || show_tcpinfo) {
-               printf("\n\t");
+               if (!json_output)
+                       printf("\n\t");
                tcp_show_info(nlh, r, tb);
        }
 
-       printf("\n");
+       if (json_output)
+               printf("}\n");
+       else
+               printf("\n");
+
        return 0;
 }
 
@@ -2081,7 +2090,10 @@ static int dgram_show_line(char *line, const struct 
filter *f, int family)
        inet_stats_print(&s, dg_proto == UDP_PROTO ? IPPROTO_UDP : 0);
 
        if (show_details && opt[0])
-               printf(" opt:\"%s\"", opt);
+               opt_fmt(opt);
+
+       if (json_output)
+               printf("}");
 
        printf("\n");
        return 0;
@@ -2258,27 +2270,36 @@ static void unix_stats_print(struct sockstat *list, 
struct filter *f)
                                continue;
                }
 
-               sock_state_print(s, unix_netid_name(s->type));
+               sock_state_fmt(s, sstate_name,
+                               unix_netid_name(s->type), netid_width, 
state_width);
 
-               sock_addr_print(s->name ?: "*", " ",
-                               int_to_str(s->lport, port_name), NULL);
-               sock_addr_print(peer, " ", int_to_str(s->rport, port_name),
-                               NULL);
+               if (json_output) {
+                       printf("\t,\"peers\": {\n");
+               }
+               sock_addr_fmt(s->name ?: "*", addr_width, " ", serv_width,
+                               int_to_str(s->lport, port_name),
+                               NULL, "local");
+               sock_addr_fmt(peer, addr_width, " ", serv_width,
+                               int_to_str(s->rport, port_name),
+                               NULL, "remote");
+               if (json_output)
+                       printf("}\n");
 
                if (show_proc_ctx || show_sock_ctx) {
                        if (find_entry(s->ino, &ctx_buf,
-                                       (show_proc_ctx & show_sock_ctx) ?
-                                       PROC_SOCK_CTX : PROC_CTX) > 0) {
-                               printf(" users:(%s)", ctx_buf);
+                                      (show_proc_ctx & show_sock_ctx) ?
+                                      PROC_SOCK_CTX : PROC_CTX) > 0) {
+                               sock_users_fmt(ctx_buf);
                                free(ctx_buf);
                        }
                } else if (show_users) {
                        if (find_entry(s->ino, &ctx_buf, USERS) > 0) {
-                               printf(" users:(%s)", ctx_buf);
+                               sock_users_fmt(ctx_buf);
                                free(ctx_buf);
                        }
                }
-               printf("\n");
+               if (!json_output)
+                       printf("\n");
        }
 }
 
@@ -2291,7 +2312,9 @@ static int unix_show_sock(const struct sockaddr_nl *addr, 
struct nlmsghdr *nlh,
        char name[128];
        struct sockstat stat = { .name = "*", .peer_name = "*" };
 
-       parse_rtattr(tb, UNIX_DIAG_MAX, (struct rtattr*)(r+1),
+       json_print_opening();
+
+       parse_rtattr(tb, UNIX_DIAG_MAX, (struct rtattr *)(r + 1),
                     nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
 
        stat.type  = r->udiag_type;
@@ -2324,21 +2347,28 @@ static int unix_show_sock(const struct sockaddr_nl 
*addr, struct nlmsghdr *nlh,
                return 0;
 
        unix_stats_print(&stat, f);
-
-       if (show_mem) {
-               printf("\t");
+if (show_mem) {
+               if (!json_output)
+                       printf("\t");
                print_skmeminfo(tb, UNIX_DIAG_MEMINFO);
        }
        if (show_details) {
                if (tb[UNIX_DIAG_SHUTDOWN]) {
                        unsigned char mask;
                        mask = *(__u8 *)RTA_DATA(tb[UNIX_DIAG_SHUTDOWN]);
-                       printf(" %c-%c", mask & 1 ? '-' : '<', mask & 2 ? '-' : 
'>');
+                       sock_conn_fmt(mask);
                }
        }
-       if (show_mem || show_details)
-               printf("\n");
+               if (show_mem || show_details)
+               if (!json_output)
+                       printf("\n");
 
+       if (json_output) {
+               printf("}\n");
+       }
+
+       if (name)
+               free(name);
        return 0;
 }
 
@@ -2480,7 +2510,8 @@ static int packet_stats_print(struct sockstat *s, const 
struct filter *f)
                        return 1;
        }
 
-       sock_state_print(s, s->type == SOCK_RAW ? "p_raw" : "p_dgr");
+       sock_state_fmt(s, sstate_name, s->type == SOCK_RAW ? "p_raw" : "p_dgr",
+                       netid_width, state_width);
 
        if (s->prot == 3)
                addr = "*";
@@ -2492,25 +2523,35 @@ static int packet_stats_print(struct sockstat *s, const 
struct filter *f)
        else
                port = xll_index_to_name(s->iface);
 
-       sock_addr_print(addr, ":", port, NULL);
-       sock_addr_print("", "*", "", NULL);
+       if (json_output)
+               printf("\t,\"peers\": {\n");
+
+       sock_addr_fmt(addr, addr_width, ":",
+                       serv_width, port,
+                       NULL, "local");
+       sock_addr_fmt("", addr_width, "*",
+                       serv_width, "",
+                       NULL, "remote");
+
+       if (json_output)
+               printf("}\n");
 
        if (show_proc_ctx || show_sock_ctx) {
                if (find_entry(s->ino, &buf,
-                                       (show_proc_ctx & show_sock_ctx) ?
-                                       PROC_SOCK_CTX : PROC_CTX) > 0) {
-                       printf(" users:(%s)", buf);
+                              (show_proc_ctx & show_sock_ctx) ?
+                              PROC_SOCK_CTX : PROC_CTX) > 0) {
+                       sock_users_fmt(buf);
                        free(buf);
                }
        } else if (show_users) {
                if (find_entry(s->ino, &buf, USERS) > 0) {
-                       printf(" users:(%s)", buf);
+                       sock_users_fmt(buf);
                        free(buf);
                }
        }
 
        if (show_details)
-               sock_details_print(s);
+               sock_details_fmt(s, GENERIC_DETAIL, 0, 0);
 
        return 0;
 }
@@ -2527,7 +2568,9 @@ static int packet_show_sock(const struct sockaddr_nl 
*addr,
        uint32_t fanout = 0;
        bool has_fanout = false;
 
-       parse_rtattr(tb, PACKET_DIAG_MAX, (struct rtattr*)(r+1),
+       json_print_opening();
+
+       parse_rtattr(tb, PACKET_DIAG_MAX, (struct rtattr *)(r + 1),
                     nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
 
        /* use /proc/net/packet if all info are not available */
@@ -2567,60 +2610,9 @@ static int packet_show_sock(const struct sockaddr_nl 
*addr,
        if (packet_stats_print(&stat, f))
                return 0;
 
-       if (show_details) {
-               if (pinfo) {
-                       printf("\n\tver:%d", pinfo->pdi_version);
-                       printf(" cpy_thresh:%d", pinfo->pdi_copy_thresh);
-                       printf(" flags( ");
-                       if (pinfo->pdi_flags & PDI_RUNNING)
-                               printf("running");
-                       if (pinfo->pdi_flags & PDI_AUXDATA)
-                               printf(" auxdata");
-                       if (pinfo->pdi_flags & PDI_ORIGDEV)
-                               printf(" origdev");
-                       if (pinfo->pdi_flags & PDI_VNETHDR)
-                               printf(" vnethdr");
-                       if (pinfo->pdi_flags & PDI_LOSS)
-                               printf(" loss");
-                       if (!pinfo->pdi_flags)
-                               printf("0");
-                       printf(" )");
-               }
-               if (ring_rx) {
-                       printf("\n\tring_rx(");
-                       packet_show_ring(ring_rx);
-                       printf(")");
-               }
-               if (ring_tx) {
-                       printf("\n\tring_tx(");
-                       packet_show_ring(ring_tx);
-                       printf(")");
-               }
-               if (has_fanout) {
-                       uint16_t type = (fanout >> 16) & 0xffff;
-
-                       printf("\n\tfanout(");
-                       printf("id:%d,", fanout & 0xffff);
-                       printf("type:");
-
-                       if (type == 0)
-                               printf("hash");
-                       else if (type == 1)
-                               printf("lb");
-                       else if (type == 2)
-                               printf("cpu");
-                       else if (type == 3)
-                               printf("roll");
-                       else if (type == 4)
-                               printf("random");
-                       else if (type == 5)
-                               printf("qm");
-                       else
-                               printf("0x%x", type);
-
-                       printf(")");
-               }
-       }
+       if (show_details)
+               packet_details_fmt(pinfo,
+                               ring_rx, ring_tx, fanout, has_fanout);
 
        if (show_bpf && tb[PACKET_DIAG_FILTER]) {
                struct sock_filter *fil =
@@ -2628,15 +2620,15 @@ static int packet_show_sock(const struct sockaddr_nl 
*addr,
                int num = RTA_PAYLOAD(tb[PACKET_DIAG_FILTER]) /
                          sizeof(struct sock_filter);
 
-               printf("\n\tbpf filter (%d): ", num);
-               while (num) {
-                       printf(" 0x%02x %u %u %u,",
-                             fil->code, fil->jt, fil->jf, fil->k);
-                       num--;
-                       fil++;
-               }
+               bpf_filter_fmt(fil, num);
        }
-       printf("\n");
+
+       if (json_output)
+               printf("}\n");
+       else
+               printf("\n");
+
+
        return 0;
 }
 
@@ -2712,6 +2704,7 @@ static int netlink_show_one(struct filter *f,
        SPRINT_BUF(prot_buf) = {};
        const char *prot_name;
        char procname[64] = {};
+       char *rem = "remote";
 
        st.state = SS_CLOSE;
        st.rq    = rq;
@@ -2727,7 +2720,7 @@ static int netlink_show_one(struct filter *f,
                        return 1;
        }
 
-       sock_state_print(&st, "nl");
+       sock_state_fmt(&st, sstate_name,"nl", netid_width, state_width);
 
        if (resolve_services)
                prot_name = nl_proto_n2a(prot, prot_buf, sizeof(prot_buf));
@@ -2759,17 +2752,24 @@ static int netlink_show_one(struct filter *f,
                int_to_str(pid, procname);
        }
 
-       sock_addr_print(prot_name, ":", procname, NULL);
+       if (json_output)
+               printf("\t,\"peers\": {\n");
+
+       sock_addr_fmt(prot_name, addr_width, ":", serv_width,
+                       procname, NULL, "local");
 
        if (state == NETLINK_CONNECTED) {
                char dst_group_buf[30];
                char dst_pid_buf[30];
-               sock_addr_print(int_to_str(dst_group, dst_group_buf), ":",
-                               int_to_str(dst_pid, dst_pid_buf), NULL);
+               sock_addr_fmt(int_to_str(dst_group, dst_group_buf), addr_width, 
":",
+                               serv_width, int_to_str(dst_pid, dst_pid_buf), 
NULL, rem);
        } else {
-               sock_addr_print("", "*", "", NULL);
+               sock_addr_fmt("", addr_width, "*", serv_width, "", NULL, rem);
        }
 
+       if (json_output)
+               printf("}\n");
+
        char *pid_context = NULL;
        if (show_proc_ctx) {
                /* The pid value will either be:
@@ -2783,16 +2783,11 @@ static int netlink_show_one(struct filter *f,
                else if (pid > 0)
                        getpidcon(pid, &pid_context);
 
-               if (pid_context != NULL) {
-                       printf("proc_ctx=%-*s ", serv_width, pid_context);
-                       free(pid_context);
-               } else {
-                       printf("proc_ctx=%-*s ", serv_width, "unavailable");
-               }
+               proc_fmt(serv_width, pid_context);
        }
 
        if (show_details) {
-               printf(" sk=%llx cb=%llx groups=0x%08x", sk, cb, groups);
+               sock_details_fmt(&st, NETLINK_DETAIL, groups, cb);
        }
        printf("\n");
 
@@ -2808,7 +2803,9 @@ static int netlink_show_sock(const struct sockaddr_nl 
*addr,
        int rq = 0, wq = 0;
        unsigned long groups = 0;
 
-       parse_rtattr(tb, NETLINK_DIAG_MAX, (struct rtattr*)(r+1),
+       json_print_opening();
+
+       parse_rtattr(tb, NETLINK_DIAG_MAX, (struct rtattr *)(r + 1),
                     nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
 
        if (tb[NETLINK_DIAG_GROUPS] && RTA_PAYLOAD(tb[NETLINK_DIAG_GROUPS]))
@@ -2834,6 +2831,9 @@ static int netlink_show_sock(const struct sockaddr_nl 
*addr,
                printf("\n");
        }
 
+       if (json_output)
+               printf("}\n");
+
        return 0;
 }
 
@@ -3028,7 +3028,7 @@ static int get_sockstat(struct ssummary *s)
        return 0;
 }
 
-static int print_summary(void)
+static int print_summary(bool has_successor)
 {
        struct ssummary s;
        struct snmpstat sn;
@@ -3040,32 +3040,7 @@ static int print_summary(void)
 
        get_slabstat(&slabstat);
 
-       printf("Total: %d (kernel %d)\n", s.socks, slabstat.socks);
-
-       printf("TCP:   %d (estab %d, closed %d, orphaned %d, synrecv %d, 
timewait %d/%d), ports %d\n",
-              s.tcp_total + slabstat.tcp_syns + s.tcp_tws,
-              sn.tcp_estab,
-              s.tcp_total - (s.tcp4_hashed+s.tcp6_hashed-s.tcp_tws),
-              s.tcp_orphans,
-              slabstat.tcp_syns,
-              s.tcp_tws, slabstat.tcp_tws,
-              slabstat.tcp_ports
-              );
-
-       printf("\n");
-       printf("Transport Total     IP        IPv6\n");
-       printf("*         %-9d %-9s %-9s\n", slabstat.socks, "-", "-");
-       printf("RAW       %-9d %-9d %-9d\n", s.raw4+s.raw6, s.raw4, s.raw6);
-       printf("UDP       %-9d %-9d %-9d\n", s.udp4+s.udp6, s.udp4, s.udp6);
-       printf("TCP       %-9d %-9d %-9d\n", s.tcp4_hashed+s.tcp6_hashed, 
s.tcp4_hashed, s.tcp6_hashed);
-       printf("INET      %-9d %-9d %-9d\n",
-              s.raw4+s.udp4+s.tcp4_hashed+
-              s.raw6+s.udp6+s.tcp6_hashed,
-              s.raw4+s.udp4+s.tcp4_hashed,
-              s.raw6+s.udp6+s.tcp6_hashed);
-       printf("FRAG      %-9d %-9d %-9d\n", s.frag4+s.frag6, s.frag4, s.frag6);
-
-       printf("\n");
+       sock_summary_fmt(&s, &sn, &slabstat, has_successor);
 
        if (json_output && has_successor)
                printf(",\n");
@@ -3406,11 +3381,10 @@ int main(int argc, char *argv[])
        argc -= optind;
        argv += optind;
 
-       if (do_summary) {
-               print_summary();
-               if (do_default && argc == 0)
-                       exit(0);
-       }
+       if (json_output)
+               printf("{\n");
+
+
 
        /* Now parse filter... */
        if (argc == 0 && filter_fp) {
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to