#include <linux/tipc.h>
#include <linux/tipc_netlink.h>
#include <linux/tipc_sockets_diag.h>
+#include <linux/tls.h>
/* AF_VSOCK/PF_VSOCK is only provided since glibc 2.18 */
#ifndef PF_VSOCK
}
#endif
-static int resolve_services = 1;
int preferred_family = AF_UNSPEC;
static int show_options;
int show_details;
static int sctp_ino;
static int show_tipcinfo;
static int show_tos;
+int numeric;
+int oneline;
enum col_id {
COL_NETID,
return buf;
}
- if (!resolve_services)
+ if (numeric)
goto do_numeric;
if (dg_proto == RAW_PROTO)
static char *sprint_bw(char *buf, double bw)
{
- if (bw > 1000000.)
+ if (numeric)
+ sprintf(buf, "%.0f", bw);
+ else if (bw > 1000000.)
sprintf(buf, "%.1fM", bw / 1000000.);
else if (bw > 1000.)
sprintf(buf, "%.1fK", bw / 1000.);
if (s->sctpi_s_pd_point)
out(" pdpoint:%d", s->sctpi_s_pd_point);
if (s->sctpi_s_nodelay)
- out(" nodealy:%d", s->sctpi_s_nodelay);
+ out(" nodelay:%d", s->sctpi_s_nodelay);
if (s->sctpi_s_disable_fragments)
out(" nofrag:%d", s->sctpi_s_disable_fragments);
if (s->sctpi_s_v4mapped)
print_escape_buf(sig->tcpm_key, sig->tcpm_keylen, " ,");
}
+static void tcp_tls_version(struct rtattr *attr)
+{
+ u_int16_t val;
+
+ if (!attr)
+ return;
+ val = rta_getattr_u16(attr);
+
+ switch (val) {
+ case TLS_1_2_VERSION:
+ out(" version: 1.2");
+ break;
+ case TLS_1_3_VERSION:
+ out(" version: 1.3");
+ break;
+ default:
+ out(" version: unknown(%hu)", val);
+ break;
+ }
+}
+
+static void tcp_tls_cipher(struct rtattr *attr)
+{
+ u_int16_t val;
+
+ if (!attr)
+ return;
+ val = rta_getattr_u16(attr);
+
+ switch (val) {
+ case TLS_CIPHER_AES_GCM_128:
+ out(" cipher: aes-gcm-128");
+ break;
+ case TLS_CIPHER_AES_GCM_256:
+ out(" cipher: aes-gcm-256");
+ break;
+ }
+}
+
+static void tcp_tls_conf(const char *name, struct rtattr *attr)
+{
+ u_int16_t val;
+
+ if (!attr)
+ return;
+ val = rta_getattr_u16(attr);
+
+ switch (val) {
+ case TLS_CONF_BASE:
+ out(" %s: none", name);
+ break;
+ case TLS_CONF_SW:
+ out(" %s: sw", name);
+ break;
+ case TLS_CONF_HW:
+ out(" %s: hw", name);
+ break;
+ case TLS_CONF_HW_RECORD:
+ out(" %s: hw-record", name);
+ break;
+ default:
+ out(" %s: unknown(%hu)", name, val);
+ break;
+ }
+}
+
#define TCPI_HAS_OPT(info, opt) !!(info->tcpi_options & (opt))
static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r,
print_md5sig(sig++);
}
}
+ if (tb[INET_DIAG_ULP_INFO]) {
+ struct rtattr *ulpinfo[INET_ULP_INFO_MAX + 1] = { 0 };
+
+ parse_rtattr_nested(ulpinfo, INET_ULP_INFO_MAX,
+ tb[INET_DIAG_ULP_INFO]);
+
+ if (ulpinfo[INET_ULP_INFO_NAME])
+ out(" tcp-ulp-%s",
+ rta_getattr_str(ulpinfo[INET_ULP_INFO_NAME]));
+
+ if (ulpinfo[INET_ULP_INFO_TLS]) {
+ struct rtattr *tlsinfo[TLS_INFO_MAX + 1] = { 0 };
+
+ parse_rtattr_nested(tlsinfo, TLS_INFO_MAX,
+ ulpinfo[INET_ULP_INFO_TLS]);
+
+ tcp_tls_version(tlsinfo[TLS_INFO_VERSION]);
+ tcp_tls_cipher(tlsinfo[TLS_INFO_CIPHER]);
+ tcp_tls_conf("rxconf", tlsinfo[TLS_INFO_RXCONF]);
+ tcp_tls_conf("txconf", tlsinfo[TLS_INFO_TXCONF]);
+ }
+ }
}
static const char *format_host_sa(struct sockaddr_storage *sa)
len = RTA_PAYLOAD(tb[INET_DIAG_LOCALS]);
sa = RTA_DATA(tb[INET_DIAG_LOCALS]);
- out("locals:%s", format_host_sa(sa));
+ out(" locals:%s", format_host_sa(sa));
for (sa++, len -= sizeof(*sa); len > 0; sa++, len -= sizeof(*sa))
out(",%s", format_host_sa(sa));
}
if (show_mem || (show_tcpinfo && s->type != IPPROTO_UDP)) {
- out("\n\t");
+ if (!oneline)
+ out("\n\t");
if (s->type == IPPROTO_SCTP)
sctp_show_info(nlh, r, tb);
else
if (show_details) {
if (pinfo) {
- out("\n\tver:%d", pinfo->pdi_version);
+ if (oneline)
+ out(" ver:%d", pinfo->pdi_version);
+ else
+ out("\n\tver:%d", pinfo->pdi_version);
out(" cpy_thresh:%d", pinfo->pdi_copy_thresh);
out(" flags( ");
if (pinfo->pdi_flags & PDI_RUNNING)
out(" )");
}
if (ring_rx) {
- out("\n\tring_rx(");
+ if (oneline)
+ out(" ring_rx(");
+ else
+ out("\n\tring_rx(");
packet_show_ring(ring_rx);
out(")");
}
if (ring_tx) {
- out("\n\tring_tx(");
+ if (oneline)
+ out(" ring_tx(");
+ else
+ out("\n\tring_tx(");
packet_show_ring(ring_tx);
out(")");
}
if (has_fanout) {
uint16_t type = (fanout >> 16) & 0xffff;
- out("\n\tfanout(");
+ if (oneline)
+ out(" fanout(");
+ else
+ out("\n\tfanout(");
out("id:%d,", fanout & 0xffff);
out("type:");
int num = RTA_PAYLOAD(tb[PACKET_DIAG_FILTER]) /
sizeof(struct sock_filter);
- out("\n\tbpf filter (%d): ", num);
+ if (oneline)
+ out(" bpf filter (%d): ", num);
+ else
+ out("\n\tbpf filter (%d): ", num);
while (num) {
out(" 0x%02x %u %u %u,",
fil->code, fil->jt, fil->jf, fil->k);
static void xdp_show_ring(const char *name, struct xdp_diag_ring *ring)
{
- out("\n\t%s(", name);
+ if (oneline)
+ out(" %s(", name);
+ else
+ out("\n\t%s(", name);
out("entries:%u", ring->entries);
out(")");
}
static void xdp_show_umem(struct xdp_diag_umem *umem, struct xdp_diag_ring *fr,
struct xdp_diag_ring *cr)
{
- out("\n\tumem(");
+ if (oneline)
+ out(" tumem(");
+ else
+ out("\n\tumem(");
out("id:%u", umem->id);
out(",size:%llu", umem->size);
out(",num_pages:%u", umem->num_pages);
sock_state_print(&st);
- if (resolve_services)
- prot_name = nl_proto_n2a(prot, prot_buf, sizeof(prot_buf));
- else
- prot_name = int_to_str(prot, prot_buf);
+ prot_name = nl_proto_n2a(prot, prot_buf, sizeof(prot_buf));
if (pid == -1) {
procname[0] = '*';
- } else if (resolve_services) {
+ } else if (!numeric) {
int done = 0;
if (!pid) {
proc_ctx_print(&ss);
if (show_tipcinfo) {
- out("\n type:%s", stype_nameg[ss.type]);
+ if (oneline)
+ out(" type:%s", stype_nameg[ss.type]);
+ else
+ out("\n type:%s", stype_nameg[ss.type]);
out(" cong:%s ",
stat[TIPC_NLA_SOCK_STAT_LINK_CONG] ? "link" :
stat[TIPC_NLA_SOCK_STAT_CONN_CONG] ? "conn" : "none");
"\n"
" -K, --kill forcibly close sockets, display what was closed\n"
" -H, --no-header Suppress header line\n"
+" -O, --oneline socket's data printed on a single line\n"
"\n"
" -A, --query=QUERY, --socket=QUERY\n"
" QUERY := {all|inet|tcp|udp|raw|unix|unix_dgram|unix_stream|unix_seqpacket|packet|netlink|vsock_stream|vsock_dgram|tipc}[,QUERY]\n"
{ "kill", 0, 0, 'K' },
{ "no-header", 0, 0, 'H' },
{ "xdp", 0, 0, OPT_XDPSOCK},
+ { "oneline", 0, 0, 'O' },
{ 0 }
};
int state_filter = 0;
while ((ch = getopt_long(argc, argv,
- "dhaletuwxnro460spbEf:miA:D:F:vVzZN:KHS",
+ "dhaletuwxnro460spbEf:miA:D:F:vVzZN:KHSO",
long_opts, NULL)) != EOF) {
switch (ch) {
case 'n':
- resolve_services = 0;
+ numeric = 1;
break;
case 'r':
resolve_hosts = 1;
case 'H':
show_header = 0;
break;
+ case 'O':
+ oneline = 1;
+ break;
case 'h':
help();
case '?':
filter_states_set(¤t_filter, state_filter);
filter_merge_defaults(¤t_filter);
- if (resolve_services && resolve_hosts &&
+ if (!numeric && resolve_hosts &&
(current_filter.dbs & (UNIX_DBM|INET_L4_DBM)))
init_service_resolver();