]> git.proxmox.com Git - mirror_iproute2.git/blobdiff - misc/ss.c
ss: add fastopen support
[mirror_iproute2.git] / misc / ss.c
index b8cd60de20e751666eac71384592f6ebce28ae99..54936308484fe430315b69284322f6e1716a064f 100644 (file)
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -32,7 +32,7 @@
 #include "libnetlink.h"
 #include "SNAPSHOT.h"
 
-#include <netinet/tcp.h>
+#include <linux/tcp.h>
 #include <linux/sock_diag.h>
 #include <linux/inet_diag.h>
 #include <linux/unix_diag.h>
@@ -309,7 +309,7 @@ static void user_ent_hash_build(void)
        closedir(dir);
 }
 
-int find_users(unsigned ino, char *buf, int buflen)
+static int find_users(unsigned ino, char *buf, int buflen)
 {
        struct user_ent *p;
        int cnt = 0;
@@ -365,7 +365,7 @@ static const char *slabstat_ids[] =
        "skbuff_head_cache",
 };
 
-int get_slabstat(struct slabstat *s)
+static int get_slabstat(struct slabstat *s)
 {
        char buf[256];
        FILE *fp;
@@ -399,32 +399,32 @@ int get_slabstat(struct slabstat *s)
 
 static const char *sstate_name[] = {
        "UNKNOWN",
-       [TCP_ESTABLISHED] = "ESTAB",
-       [TCP_SYN_SENT] = "SYN-SENT",
-       [TCP_SYN_RECV] = "SYN-RECV",
-       [TCP_FIN_WAIT1] = "FIN-WAIT-1",
-       [TCP_FIN_WAIT2] = "FIN-WAIT-2",
-       [TCP_TIME_WAIT] = "TIME-WAIT",
-       [TCP_CLOSE] = "UNCONN",
-       [TCP_CLOSE_WAIT] = "CLOSE-WAIT",
-       [TCP_LAST_ACK] = "LAST-ACK",
-       [TCP_LISTEN] =  "LISTEN",
-       [TCP_CLOSING] = "CLOSING",
+       [SS_ESTABLISHED] = "ESTAB",
+       [SS_SYN_SENT] = "SYN-SENT",
+       [SS_SYN_RECV] = "SYN-RECV",
+       [SS_FIN_WAIT1] = "FIN-WAIT-1",
+       [SS_FIN_WAIT2] = "FIN-WAIT-2",
+       [SS_TIME_WAIT] = "TIME-WAIT",
+       [SS_CLOSE] = "UNCONN",
+       [SS_CLOSE_WAIT] = "CLOSE-WAIT",
+       [SS_LAST_ACK] = "LAST-ACK",
+       [SS_LISTEN] =   "LISTEN",
+       [SS_CLOSING] = "CLOSING",
 };
 
 static const char *sstate_namel[] = {
        "UNKNOWN",
-       [TCP_ESTABLISHED] = "established",
-       [TCP_SYN_SENT] = "syn-sent",
-       [TCP_SYN_RECV] = "syn-recv",
-       [TCP_FIN_WAIT1] = "fin-wait-1",
-       [TCP_FIN_WAIT2] = "fin-wait-2",
-       [TCP_TIME_WAIT] = "time-wait",
-       [TCP_CLOSE] = "unconnected",
-       [TCP_CLOSE_WAIT] = "close-wait",
-       [TCP_LAST_ACK] = "last-ack",
-       [TCP_LISTEN] =  "listening",
-       [TCP_CLOSING] = "closing",
+       [SS_ESTABLISHED] = "established",
+       [SS_SYN_SENT] = "syn-sent",
+       [SS_SYN_RECV] = "syn-recv",
+       [SS_FIN_WAIT1] = "fin-wait-1",
+       [SS_FIN_WAIT2] = "fin-wait-2",
+       [SS_TIME_WAIT] = "time-wait",
+       [SS_CLOSE] = "unconnected",
+       [SS_CLOSE_WAIT] = "close-wait",
+       [SS_LAST_ACK] = "last-ack",
+       [SS_LISTEN] =   "listening",
+       [SS_CLOSING] = "closing",
 };
 
 struct tcpstat
@@ -455,7 +455,7 @@ static const char *tmr_name[] = {
        "unknown"
 };
 
-const char *print_ms_timer(int timeout)
+static const char *print_ms_timer(int timeout)
 {
        static char buf[64];
        int secs, msecs, minutes;
@@ -482,7 +482,7 @@ const char *print_ms_timer(int timeout)
        return buf;
 }
 
-const char *print_hz_timer(int timeout)
+static const char *print_hz_timer(int timeout)
 {
        int hz = get_user_hz();
        return print_ms_timer(((timeout*1000) + hz-1)/hz);
@@ -498,7 +498,7 @@ struct scache
 
 struct scache *rlist;
 
-void init_service_resolver(void)
+static void init_service_resolver(void)
 {
        char buf[128];
        FILE *fp = popen("/usr/sbin/rpcinfo -p 2>/dev/null", "r");
@@ -555,7 +555,7 @@ static int is_ephemeral(int port)
 }
 
 
-const char *__resolve_service(int port)
+static const char *__resolve_service(int port)
 {
        struct scache *c;
 
@@ -580,7 +580,7 @@ const char *__resolve_service(int port)
 }
 
 
-const char *resolve_service(int port)
+static const char *resolve_service(int port)
 {
        static char buf[128];
        static struct scache cache[256];
@@ -634,7 +634,7 @@ const char *resolve_service(int port)
        return buf;
 }
 
-void formatted_print(const inet_prefix *a, int port)
+static void formatted_print(const inet_prefix *a, int port)
 {
        char buf[1024];
        const char *ap = buf;
@@ -667,7 +667,8 @@ struct aafilter
        struct aafilter *next;
 };
 
-int inet2_addr_match(const inet_prefix *a, const inet_prefix *p, int plen)
+static int inet2_addr_match(const inet_prefix *a, const inet_prefix *p,
+                           int plen)
 {
        if (!inet_addr_match(a, p, plen))
                return 0;
@@ -686,7 +687,7 @@ int inet2_addr_match(const inet_prefix *a, const inet_prefix *p, int plen)
        return 1;
 }
 
-int unix_match(const inet_prefix *a, const inet_prefix *p)
+static int unix_match(const inet_prefix *a, const inet_prefix *p)
 {
        char *addr, *pattern;
        memcpy(&addr, a->data, sizeof(addr));
@@ -698,7 +699,7 @@ int unix_match(const inet_prefix *a, const inet_prefix *p)
        return !fnmatch(pattern, addr, 0);
 }
 
-int run_ssfilter(struct ssfilter *f, struct tcpstat *s)
+static int run_ssfilter(struct ssfilter *f, struct tcpstat *s)
 {
        switch (f->type) {
                case SSF_S_AUTO:
@@ -1326,6 +1327,29 @@ static char *sprint_bw(char *buf, double bw)
        return buf;
 }
 
+static void print_skmeminfo(struct rtattr *tb[], int attrtype)
+{
+       const __u32 *skmeminfo;
+       if (!tb[attrtype])
+               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(")");
+}
+
 static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r)
 {
        struct rtattr * tb[INET_DIAG_MAX+1];
@@ -1336,22 +1360,7 @@ static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r)
                     nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
 
        if (tb[INET_DIAG_SKMEMINFO]) {
-               const __u32 *skmeminfo = RTA_DATA(tb[INET_DIAG_SKMEMINFO]);
-
-               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[INET_DIAG_SKMEMINFO]) >=
-                       (SK_MEMINFO_BACKLOG + 1) * sizeof(__u32))
-                       printf(",bl%u", skmeminfo[SK_MEMINFO_BACKLOG]);
-
-               printf(")");
+               print_skmeminfo(tb, INET_DIAG_SKMEMINFO);
        } else if (tb[INET_DIAG_MEMINFO]) {
                const struct inet_diag_meminfo *minfo
                        = RTA_DATA(tb[INET_DIAG_MEMINFO]);
@@ -1383,6 +1392,8 @@ static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r)
                                printf(" ecn");
                        if (info->tcpi_options & TCPI_OPT_ECN_SEEN)
                                printf(" ecnseen");
+                       if (info->tcpi_options & TCPI_OPT_SYN_DATA)
+                               printf(" fastopen");
                }
 
                if (tb[INET_DIAG_CONG])
@@ -1882,7 +1893,7 @@ outerr:
 }
 
 
-int dgram_show_line(char *line, const struct filter *f, int family)
+static int dgram_show_line(char *line, const struct filter *f, int family)
 {
        struct tcpstat s;
        char *loc, *rem, *data;
@@ -1974,7 +1985,7 @@ int dgram_show_line(char *line, const struct filter *f, int family)
 }
 
 
-int udp_show(struct filter *f)
+static int udp_show(struct filter *f)
 {
        FILE *fp = NULL;
 
@@ -2010,7 +2021,7 @@ outerr:
        } while (0);
 }
 
-int raw_show(struct filter *f)
+static int raw_show(struct filter *f)
 {
        FILE *fp = NULL;
 
@@ -2063,7 +2074,7 @@ int unix_state_map[] = { SS_CLOSE, SS_SYN_SENT,
 
 #define MAX_UNIX_REMEMBER (1024*1024/sizeof(struct unixstat))
 
-void unix_list_free(struct unixstat *list)
+static void unix_list_free(struct unixstat *list)
 {
        while (list) {
                struct unixstat *s = list;
@@ -2074,7 +2085,7 @@ void unix_list_free(struct unixstat *list)
        }
 }
 
-void unix_list_print(struct unixstat *list, struct filter *f)
+static void unix_list_print(struct unixstat *list, struct filter *f)
 {
        struct unixstat *s;
        char *peer;
@@ -2138,7 +2149,7 @@ static int unix_show_sock(struct nlmsghdr *nlh, struct filter *f)
        struct rtattr *tb[UNIX_DIAG_MAX+1];
        char name[128];
        int peer_ino;
-       int rqlen;
+       __u32 rqlen, wqlen;
 
        parse_rtattr(tb, UNIX_DIAG_MAX, (struct rtattr*)(r+1),
                     nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
@@ -2149,12 +2160,16 @@ static int unix_show_sock(struct nlmsghdr *nlh, struct filter *f)
        if (state_width)
                printf("%-*s ", state_width, sstate_name[r->udiag_state]);
 
-       if (tb[UNIX_DIAG_RQLEN])
-               rqlen = *(int *)RTA_DATA(tb[UNIX_DIAG_RQLEN]);
-       else
+       if (tb[UNIX_DIAG_RQLEN]) {
+               struct unix_diag_rqlen *rql = RTA_DATA(tb[UNIX_DIAG_RQLEN]);
+               rqlen = rql->udiag_rqueue;
+               wqlen = rql->udiag_wqueue;
+       } else {
                rqlen = 0;
+               wqlen = 0;
+       }
 
-       printf("%-6d %-6d ", rqlen, 0);
+       printf("%-6u %-6u ", rqlen, wqlen);
 
        if (tb[UNIX_DIAG_NAME]) {
                int len = RTA_PAYLOAD(tb[UNIX_DIAG_NAME]);
@@ -2167,7 +2182,7 @@ static int unix_show_sock(struct nlmsghdr *nlh, struct filter *f)
                sprintf(name, "*");
 
        if (tb[UNIX_DIAG_PEER])
-               peer_ino = *(int *)RTA_DATA(tb[UNIX_DIAG_PEER]);
+               peer_ino = rta_getattr_u32(tb[UNIX_DIAG_PEER]);
        else
                peer_ino = 0;
 
@@ -2183,6 +2198,11 @@ static int unix_show_sock(struct nlmsghdr *nlh, struct filter *f)
                        printf(" users:(%s)", ubuf);
        }
 
+       if (show_mem) {
+               printf("\n\t");
+               print_skmeminfo(tb, UNIX_DIAG_MEMINFO);
+       }
+
        printf("\n");
 
        return 0;
@@ -2209,6 +2229,8 @@ static int unix_show_netlink(struct filter *f, FILE *dump_fp)
        req.r.sdiag_family = AF_UNIX;
        req.r.udiag_states = f->states;
        req.r.udiag_show = UDIAG_SHOW_NAME | UDIAG_SHOW_PEER | UDIAG_SHOW_RQLEN;
+       if (show_mem)
+               req.r.udiag_show |= UDIAG_SHOW_MEMINFO;
 
        if (send(fd, &req, sizeof(req), 0) < 0) {
                close(fd);
@@ -2283,7 +2305,7 @@ close_it:
        return 0;
 }
 
-int unix_show(struct filter *f)
+static int unix_show(struct filter *f)
 {
        FILE *fp;
        char buf[256];
@@ -2368,7 +2390,7 @@ int unix_show(struct filter *f)
 }
 
 
-int packet_show(struct filter *f)
+static int packet_show(struct filter *f)
 {
        FILE *fp;
        char buf[256];
@@ -2445,7 +2467,7 @@ int packet_show(struct filter *f)
        return 0;
 }
 
-int netlink_show(struct filter *f)
+static int netlink_show(struct filter *f)
 {
        FILE *fp;
        char buf[256];
@@ -2534,7 +2556,7 @@ struct snmpstat
        int tcp_estab;
 };
 
-int get_snmp_int(char *proto, char *key, int *result)
+static int get_snmp_int(char *proto, char *key, int *result)
 {
        char buf[1024];
        FILE *fp;
@@ -2629,7 +2651,7 @@ static void get_sockstat_line(char *line, struct sockstat *s)
                       &s->tcp_orphans, &s->tcp_tws, &s->tcp_total, &s->tcp_mem);
 }
 
-int get_sockstat(struct sockstat *s)
+static int get_sockstat(struct sockstat *s)
 {
        char buf[256];
        FILE *fp;
@@ -2651,7 +2673,7 @@ int get_sockstat(struct sockstat *s)
        return 0;
 }
 
-int print_summary(void)
+static int print_summary(void)
 {
        struct sockstat s;
        struct snmpstat sn;
@@ -2743,7 +2765,7 @@ static void usage(void)
 }
 
 
-int scan_state(const char *state)
+static int scan_state(const char *state)
 {
        int i;
        if (strcasecmp(state, "close") == 0 ||