From: Masatake YAMATO Date: Fri, 3 Feb 2023 05:03:23 +0000 (+0900) Subject: lsfd: use extra information loaded from /proc/net/tcp6 X-Git-Tag: v2.39-rc1~66^2~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1656da13b0e869e3bdbf1b4a8a3d5b648727af31;p=thirdparty%2Futil-linux.git lsfd: use extra information loaded from /proc/net/tcp6 Example output: # ./lsfd -Q '(TYPE == "TCPv6") and ((COMMAND == "sshd") or (COMMAND == "test_mkfds"))' COMMAND PID USER ASSOC MODE TYPE SOURCE MNTID INODE NAME sshd 1137 root 4 rw- TCPv6 sockfs 9 34689 state=listen laddr=[::]:22 test_mkfds 716926 jet 3 rw- TCPv6 sockfs 9 6042073 state=listen laddr=[::1]:12345 test_mkfds 716926 jet 4 rw- TCPv6 sockfs 9 6042074 state=established laddr=[::1]:23456 raddr=[::1]:12345 test_mkfds 716926 jet 5 rw- TCPv6 sockfs 9 6042075 state=established laddr=[::1]:12345 raddr=[::1]:23456 Signed-off-by: Masatake YAMATO --- diff --git a/misc-utils/lsfd-sock-xinfo.c b/misc-utils/lsfd-sock-xinfo.c index 2316fc90ec..a5160c75d7 100644 --- a/misc-utils/lsfd-sock-xinfo.c +++ b/misc-utils/lsfd-sock-xinfo.c @@ -19,6 +19,7 @@ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include /* inet_ntop */ +#include /* in6_addr */ #include /* open(2) */ #include /* SCNu16 */ #include /* SS_* */ @@ -42,6 +43,7 @@ static void load_xinfo_from_proc_unix(ino_t netns_inode); static void load_xinfo_from_proc_raw(ino_t netns_inode); static void load_xinfo_from_proc_tcp(ino_t netns_inode); static void load_xinfo_from_proc_udp(ino_t netns_inode); +static void load_xinfo_from_proc_tcp6(ino_t netns_inode); static int self_netns_fd = -1; static struct stat self_netns_sb; @@ -81,6 +83,7 @@ static void load_sock_xinfo_no_nsswitch(ino_t netns) load_xinfo_from_proc_tcp(netns); load_xinfo_from_proc_udp(netns); load_xinfo_from_proc_raw(netns); + load_xinfo_from_proc_tcp6(netns); } static void load_sock_xinfo_with_fd(int fd, ino_t netns) @@ -420,6 +423,15 @@ static uint32_t kernel32_to_cpu(enum sysfs_byteorder byteorder, uint32_t v) return be32_to_cpu(v); } +/* + * AF_INET6 + */ +struct inet6_xinfo { + struct sock_xinfo sock; + struct in6_addr local_addr; + struct in6_addr remote_addr; +}; + /* * L4 abstract-layer for protocols stacked on IP and IP6. */ @@ -469,11 +481,15 @@ static const char *l4_decode_state(enum l4_state st) } struct l4_xinfo { - struct inet_xinfo inet; + union { + struct inet_xinfo inet; + struct inet6_xinfo inet6; + }; enum l4_state st; }; enum l4_side { L4_LOCAL, L4_REMOTE }; +enum l3_decorator { L3_DECO_START, L3_DECO_END }; struct l4_xinfo_class { struct sock_xinfo_class sock; @@ -484,6 +500,7 @@ struct l4_xinfo_class { void * (*get_addr)(struct l4_xinfo *, enum l4_side); bool (*is_any_addr)(void *); int family; + const char *l3_decorator[2]; }; #define l3_fill_column_handler(L3, SOCK_XINFO, COLUMN_ID, STR) __extension__ \ @@ -533,19 +550,21 @@ static char *tcp_get_name(struct sock_xinfo *sock_xinfo, void *raddr = class->get_addr(l4, L4_REMOTE); char local_s[BUFSIZ]; char remote_s[BUFSIZ]; + const char *start = class->l3_decorator[L3_DECO_START]; + const char *end = class->l3_decorator[L3_DECO_END]; if (!inet_ntop(class->family, laddr, local_s, sizeof(local_s))) xasprintf(&str, "state=%s", st_str); else if (l4->st == TCP_LISTEN || !inet_ntop(class->family, raddr, remote_s, sizeof(remote_s))) - xasprintf(&str, "state=%s laddr=%s:%"SCNu16, + xasprintf(&str, "state=%s laddr=%s%s%s:%"SCNu16, st_str, - local_s, tcp->local_port); + start, local_s, end, tcp->local_port); else - xasprintf(&str, "state=%s laddr=%s:%"SCNu16" raddr=%s:%"SCNu16, + xasprintf(&str, "state=%s laddr=%s%s%s:%"SCNu16" raddr=%s%s%s:%"SCNu16, st_str, - local_s, tcp->local_port, - remote_s, tcp->remote_port); + start, local_s, end, tcp->local_port, + start, remote_s, end, tcp->remote_port); return str; } @@ -591,7 +610,11 @@ static bool tcp_get_listening(struct sock_xinfo *sock_xinfo, p = tcp->remote_port; \ } \ if (n && inet_ntop(class->family, n, s, sizeof(s))) \ - xasprintf(STR, "%s:%"SCNu16, s, p); \ + xasprintf(STR, "%s%s%s:%"SCNu16, \ + class->l3_decorator[L3_DECO_START], \ + s, \ + class->l3_decorator[L3_DECO_END], \ + p); \ break; \ case COL_##L4##_LPORT: \ p = tcp->local_port; \ @@ -684,6 +707,7 @@ static const struct l4_xinfo_class tcp_xinfo_class = { .get_addr = tcp_xinfo_get_addr, .is_any_addr = tcp_xinfo_is_any_addr, .family = AF_INET, + .l3_decorator = {"", ""}, }; static bool L4_verify_initial_line(const char *line) @@ -798,6 +822,7 @@ static const struct l4_xinfo_class udp_xinfo_class = { .get_addr = tcp_xinfo_get_addr, .is_any_addr = tcp_xinfo_is_any_addr, .family = AF_INET, + .l3_decorator = {"", ""}, }; static void load_xinfo_from_proc_udp(ino_t netns_inode) @@ -917,6 +942,7 @@ static const struct l4_xinfo_class raw_xinfo_class = { .get_addr = tcp_xinfo_get_addr, .is_any_addr = tcp_xinfo_is_any_addr, .family = AF_INET, + .l3_decorator = {"", ""}, }; static void load_xinfo_from_proc_raw(ino_t netns_inode) @@ -925,3 +951,98 @@ static void load_xinfo_from_proc_raw(ino_t netns_inode) "/proc/net/raw", &raw_xinfo_class); } + +/* + * TCP6 + */ +static struct sock_xinfo *tcp6_xinfo_scan_line(const struct sock_xinfo_class *class, + char * line, + ino_t netns_inode, + enum sysfs_byteorder byteorder) +{ + uint32_t local_addr[4]; + unsigned int local_port; + uint32_t remote_addr[4]; + unsigned int remote_port; + unsigned int st; + unsigned long inode; + struct tcp_xinfo *tcp; + struct inet6_xinfo *inet6; + struct sock_xinfo *sock; + + if (sscanf(line, + "%*d: " + "%08x%08x%08x%08x:%04x " + "%08x%08x%08x%08x:%04x " + "%x %*x:%*x %*x:%*x %*x %*u %*d %lu ", + local_addr+0, local_addr+1, local_addr+2, local_addr+3, &local_port, + remote_addr+0, remote_addr+1, remote_addr+2, remote_addr+3, &remote_port, + &st, &inode) != 12) + return NULL; + + if (inode == 0) + return NULL; + + tcp = xmalloc(sizeof(struct tcp_xinfo)); + inet6 = &tcp->l4.inet6; + sock = &inet6->sock; + sock->class = class; + sock->inode = (ino_t)inode; + sock->netns_inode = netns_inode; + tcp->local_port = local_port; + for (int i = 0; i < 4; i++) { + inet6->local_addr.s6_addr32[i] = kernel32_to_cpu(byteorder, local_addr[i]); + inet6->remote_addr.s6_addr32[i] = kernel32_to_cpu(byteorder, remote_addr[i]); + } + tcp->remote_port = remote_port; + tcp->l4.st = st; + + return sock; +} + +static bool tcp6_fill_column(struct proc *proc __attribute__((__unused__)), + struct sock_xinfo *sock_xinfo, + struct sock *sock __attribute__((__unused__)), + struct libscols_line *ln __attribute__((__unused__)), + int column_id, + size_t column_index __attribute__((__unused__)), + char **str) +{ + return l3_fill_column_handler(INET6, sock_xinfo, column_id, str) + || l4_fill_column_handler(TCP, sock_xinfo, column_id, str); +} + +static void *tcp6_xinfo_get_addr(struct l4_xinfo * l4, enum l4_side side) +{ + return (side == L4_LOCAL) + ? &l4->inet6.local_addr + : &l4->inet6.remote_addr; +} + +static bool tcp6_xinfo_is_any_addr(void *addr) +{ + return IN6_ARE_ADDR_EQUAL(addr, &(struct in6_addr)IN6ADDR_ANY_INIT); +} + +static const struct l4_xinfo_class tcp6_xinfo_class = { + .sock = { + .get_name = tcp_get_name, + .get_type = tcp_get_type, + .get_state = tcp_get_state, + .get_listening = tcp_get_listening, + .fill_column = tcp6_fill_column, + .free = NULL, + }, + .scan_line = tcp6_xinfo_scan_line, + .get_addr = tcp6_xinfo_get_addr, + .is_any_addr = tcp6_xinfo_is_any_addr, + .family = AF_INET6, + .l3_decorator = {"[", "]"}, +}; + +static void load_xinfo_from_proc_tcp6(ino_t netns_inode) +{ + load_xinfo_from_proc_inet_L4(netns_inode, + "/proc/net/tcp6", + &tcp6_xinfo_class); +} diff --git a/misc-utils/lsfd.c b/misc-utils/lsfd.c index 31a9311d8e..7f6275ee8b 100644 --- a/misc-utils/lsfd.c +++ b/misc-utils/lsfd.c @@ -151,6 +151,10 @@ static const struct colinfo infos[] = { N_("local IP address") }, [COL_INET_RADDR]={"INET.RADDR",0,SCOLS_FL_RIGHT, SCOLS_JSON_STRING, N_("remote IP address") }, + [COL_INET6_LADDR]={"INET6.LADDR",0,SCOLS_FL_RIGHT, SCOLS_JSON_STRING, + N_("local IPv6 address") }, + [COL_INET6_RADDR]={"INET6.RADDR",0,SCOLS_FL_RIGHT, SCOLS_JSON_STRING, + N_("remote IPv6 address") }, [COL_KNAME] = { "KNAME", 0.4, SCOLS_FL_TRUNC, SCOLS_JSON_STRING, N_("name of the file (raw)") }, [COL_KTHREAD] = { "KTHREAD", 0, SCOLS_FL_RIGHT, SCOLS_JSON_BOOLEAN, diff --git a/misc-utils/lsfd.h b/misc-utils/lsfd.h index 3b12c60c63..3023af13b0 100644 --- a/misc-utils/lsfd.h +++ b/misc-utils/lsfd.h @@ -51,6 +51,8 @@ enum { COL_INODE, COL_INET_LADDR, COL_INET_RADDR, + COL_INET6_LADDR, + COL_INET6_RADDR, COL_KNAME, COL_KTHREAD, COL_MAJMIN,