13d91be41SRobert Watson /*- 2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 31de7b4b8SPedro F. Giffuni * 4d57486e2SRobert Watson * Copyright (c) 2007-2011 Robert N. M. Watson 5474b62b8SAllan Jude * Copyright (c) 2015 Allan Jude <allanjude@freebsd.org> 63d91be41SRobert Watson * All rights reserved. 73d91be41SRobert Watson * 83d91be41SRobert Watson * Redistribution and use in source and binary forms, with or without 93d91be41SRobert Watson * modification, are permitted provided that the following conditions 103d91be41SRobert Watson * are met: 113d91be41SRobert Watson * 1. Redistributions of source code must retain the above copyright 123d91be41SRobert Watson * notice, this list of conditions and the following disclaimer. 133d91be41SRobert Watson * 2. Redistributions in binary form must reproduce the above copyright 143d91be41SRobert Watson * notice, this list of conditions and the following disclaimer in the 153d91be41SRobert Watson * documentation and/or other materials provided with the distribution. 163d91be41SRobert Watson * 173d91be41SRobert Watson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 183d91be41SRobert Watson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 193d91be41SRobert Watson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 203d91be41SRobert Watson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 213d91be41SRobert Watson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 223d91be41SRobert Watson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 233d91be41SRobert Watson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 243d91be41SRobert Watson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 253d91be41SRobert Watson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 263d91be41SRobert Watson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 273d91be41SRobert Watson * SUCH DAMAGE. 283d91be41SRobert Watson */ 293d91be41SRobert Watson 30b65eb2f8SKonstantin Belousov #include <sys/cdefs.h> 31b65eb2f8SKonstantin Belousov __FBSDID("$FreeBSD$"); 32b65eb2f8SKonstantin Belousov 33e1f323f3SRobert Watson #include <sys/param.h> 34b881b8beSRobert Watson #include <sys/capsicum.h> 353d91be41SRobert Watson #include <sys/socket.h> 363d91be41SRobert Watson #include <sys/sysctl.h> 373d91be41SRobert Watson #include <sys/un.h> 383d91be41SRobert Watson #include <sys/user.h> 393d91be41SRobert Watson 403d91be41SRobert Watson #include <netinet/in.h> 413d91be41SRobert Watson 423d91be41SRobert Watson #include <arpa/inet.h> 433d91be41SRobert Watson 44821df508SXin LI #include <err.h> 450daf62d9SStanislav Sedov #include <libprocstat.h> 463d91be41SRobert Watson #include <inttypes.h> 473d91be41SRobert Watson #include <stdio.h> 483d91be41SRobert Watson #include <stdlib.h> 493d91be41SRobert Watson #include <string.h> 503d91be41SRobert Watson 513d91be41SRobert Watson #include "procstat.h" 523d91be41SRobert Watson 533d91be41SRobert Watson static const char * 543d91be41SRobert Watson protocol_to_string(int domain, int type, int protocol) 553d91be41SRobert Watson { 563d91be41SRobert Watson 573d91be41SRobert Watson switch (domain) { 583d91be41SRobert Watson case AF_INET: 593d91be41SRobert Watson case AF_INET6: 603d91be41SRobert Watson switch (protocol) { 613d91be41SRobert Watson case IPPROTO_TCP: 623d91be41SRobert Watson return ("TCP"); 633d91be41SRobert Watson case IPPROTO_UDP: 643d91be41SRobert Watson return ("UDP"); 653d91be41SRobert Watson case IPPROTO_ICMP: 665a246d29SRobert Watson return ("ICM"); 673d91be41SRobert Watson case IPPROTO_RAW: 683d91be41SRobert Watson return ("RAW"); 693d91be41SRobert Watson case IPPROTO_SCTP: 705a246d29SRobert Watson return ("SCT"); 713d91be41SRobert Watson default: 725a246d29SRobert Watson return ("IP?"); 733d91be41SRobert Watson } 743d91be41SRobert Watson 753d91be41SRobert Watson case AF_LOCAL: 763d91be41SRobert Watson switch (type) { 773d91be41SRobert Watson case SOCK_STREAM: 785a246d29SRobert Watson return ("UDS"); 793d91be41SRobert Watson case SOCK_DGRAM: 805a246d29SRobert Watson return ("UDD"); 813d91be41SRobert Watson default: 825a246d29SRobert Watson return ("UD?"); 833d91be41SRobert Watson } 841f3d8c09SGleb Smirnoff case AF_DIVERT: 851f3d8c09SGleb Smirnoff return ("IPD"); 861f3d8c09SGleb Smirnoff break; 873d91be41SRobert Watson default: 885a246d29SRobert Watson return ("?"); 893d91be41SRobert Watson } 903d91be41SRobert Watson } 913d91be41SRobert Watson 923d91be41SRobert Watson static void 933d91be41SRobert Watson addr_to_string(struct sockaddr_storage *ss, char *buffer, int buflen) 943d91be41SRobert Watson { 953d91be41SRobert Watson char buffer2[INET6_ADDRSTRLEN]; 963d91be41SRobert Watson struct sockaddr_in6 *sin6; 973d91be41SRobert Watson struct sockaddr_in *sin; 983d91be41SRobert Watson struct sockaddr_un *sun; 993d91be41SRobert Watson 1003d91be41SRobert Watson switch (ss->ss_family) { 1013d91be41SRobert Watson case AF_LOCAL: 1023d91be41SRobert Watson sun = (struct sockaddr_un *)ss; 1033d91be41SRobert Watson if (strlen(sun->sun_path) == 0) 1043d91be41SRobert Watson strlcpy(buffer, "-", buflen); 1053d91be41SRobert Watson else 1063d91be41SRobert Watson strlcpy(buffer, sun->sun_path, buflen); 1073d91be41SRobert Watson break; 1083d91be41SRobert Watson 1093d91be41SRobert Watson case AF_INET: 1103d91be41SRobert Watson sin = (struct sockaddr_in *)ss; 111ce0372d7SJeremie Le Hen if (sin->sin_addr.s_addr == INADDR_ANY) 112b9eabd15SJeremie Le Hen snprintf(buffer, buflen, "%s:%d", "*", 113b9eabd15SJeremie Le Hen ntohs(sin->sin_port)); 114b9eabd15SJeremie Le Hen else if (inet_ntop(AF_INET, &sin->sin_addr, buffer2, 115b9eabd15SJeremie Le Hen sizeof(buffer2)) != NULL) 116b9eabd15SJeremie Le Hen snprintf(buffer, buflen, "%s:%d", buffer2, 1173d91be41SRobert Watson ntohs(sin->sin_port)); 1183d91be41SRobert Watson break; 1193d91be41SRobert Watson 1203d91be41SRobert Watson case AF_INET6: 1213d91be41SRobert Watson sin6 = (struct sockaddr_in6 *)ss; 1223d91be41SRobert Watson if (inet_ntop(AF_INET6, &sin6->sin6_addr, buffer2, 1233d91be41SRobert Watson sizeof(buffer2)) != NULL) 1243d91be41SRobert Watson snprintf(buffer, buflen, "%s.%d", buffer2, 1253d91be41SRobert Watson ntohs(sin6->sin6_port)); 1263d91be41SRobert Watson else 12701967281SXin LI strlcpy(buffer, "-", buflen); 1283d91be41SRobert Watson break; 1293d91be41SRobert Watson 1303d91be41SRobert Watson default: 1313d91be41SRobert Watson strlcpy(buffer, "", buflen); 1323d91be41SRobert Watson break; 1333d91be41SRobert Watson } 1343d91be41SRobert Watson } 1353d91be41SRobert Watson 136d57486e2SRobert Watson static struct cap_desc { 1377008be5bSPawel Jakub Dawidek uint64_t cd_right; 138d57486e2SRobert Watson const char *cd_desc; 139d57486e2SRobert Watson } cap_desc[] = { 140d57486e2SRobert Watson /* General file I/O. */ 141d57486e2SRobert Watson { CAP_READ, "rd" }, 142d57486e2SRobert Watson { CAP_WRITE, "wr" }, 1432609222aSPawel Jakub Dawidek { CAP_SEEK, "se" }, 144d57486e2SRobert Watson { CAP_MMAP, "mm" }, 1452609222aSPawel Jakub Dawidek { CAP_CREATE, "cr" }, 146d57486e2SRobert Watson { CAP_FEXECVE, "fe" }, 147d57486e2SRobert Watson { CAP_FSYNC, "fy" }, 148d57486e2SRobert Watson { CAP_FTRUNCATE, "ft" }, 149d57486e2SRobert Watson 150d57486e2SRobert Watson /* VFS methods. */ 151d57486e2SRobert Watson { CAP_FCHDIR, "cd" }, 1522609222aSPawel Jakub Dawidek { CAP_FCHFLAGS, "cf" }, 153d57486e2SRobert Watson { CAP_FCHMOD, "cm" }, 154d57486e2SRobert Watson { CAP_FCHOWN, "cn" }, 155d57486e2SRobert Watson { CAP_FCNTL, "fc" }, 156d57486e2SRobert Watson { CAP_FLOCK, "fl" }, 1572609222aSPawel Jakub Dawidek { CAP_FPATHCONF, "fp" }, 158d57486e2SRobert Watson { CAP_FSCK, "fk" }, 159d57486e2SRobert Watson { CAP_FSTAT, "fs" }, 160d57486e2SRobert Watson { CAP_FSTATFS, "sf" }, 161d57486e2SRobert Watson { CAP_FUTIMES, "fu" }, 162bc1ace0bSEd Schouten { CAP_LINKAT_SOURCE, "ls" }, 163bc1ace0bSEd Schouten { CAP_LINKAT_TARGET, "lt" }, 1642609222aSPawel Jakub Dawidek { CAP_MKDIRAT, "md" }, 1652609222aSPawel Jakub Dawidek { CAP_MKFIFOAT, "mf" }, 1662609222aSPawel Jakub Dawidek { CAP_MKNODAT, "mn" }, 167bc1ace0bSEd Schouten { CAP_RENAMEAT_SOURCE, "rs" }, 168bc1ace0bSEd Schouten { CAP_RENAMEAT_TARGET, "rt" }, 1692609222aSPawel Jakub Dawidek { CAP_SYMLINKAT, "sl" }, 1702609222aSPawel Jakub Dawidek { CAP_UNLINKAT, "un" }, 171d57486e2SRobert Watson 1722609222aSPawel Jakub Dawidek /* Lookups - used to constrain *at() calls. */ 173d57486e2SRobert Watson { CAP_LOOKUP, "lo" }, 174d57486e2SRobert Watson 175d57486e2SRobert Watson /* Extended attributes. */ 176d57486e2SRobert Watson { CAP_EXTATTR_GET, "eg" }, 177d57486e2SRobert Watson { CAP_EXTATTR_SET, "es" }, 178d57486e2SRobert Watson { CAP_EXTATTR_DELETE, "ed" }, 179d57486e2SRobert Watson { CAP_EXTATTR_LIST, "el" }, 180d57486e2SRobert Watson 181d57486e2SRobert Watson /* Access Control Lists. */ 182d57486e2SRobert Watson { CAP_ACL_GET, "ag" }, 183d57486e2SRobert Watson { CAP_ACL_SET, "as" }, 184d57486e2SRobert Watson { CAP_ACL_DELETE, "ad" }, 185d57486e2SRobert Watson { CAP_ACL_CHECK, "ac" }, 186d57486e2SRobert Watson 187d57486e2SRobert Watson /* Socket operations. */ 188d57486e2SRobert Watson { CAP_ACCEPT, "at" }, 189d57486e2SRobert Watson { CAP_BIND, "bd" }, 190d57486e2SRobert Watson { CAP_CONNECT, "co" }, 191d57486e2SRobert Watson { CAP_GETPEERNAME, "pn" }, 192d57486e2SRobert Watson { CAP_GETSOCKNAME, "sn" }, 193d57486e2SRobert Watson { CAP_GETSOCKOPT, "gs" }, 194d57486e2SRobert Watson { CAP_LISTEN, "ln" }, 195d57486e2SRobert Watson { CAP_PEELOFF, "pf" }, 196d57486e2SRobert Watson { CAP_SETSOCKOPT, "ss" }, 197d57486e2SRobert Watson { CAP_SHUTDOWN, "sh" }, 198d57486e2SRobert Watson 199d57486e2SRobert Watson /* Mandatory Access Control. */ 200d57486e2SRobert Watson { CAP_MAC_GET, "mg" }, 201d57486e2SRobert Watson { CAP_MAC_SET, "ms" }, 202d57486e2SRobert Watson 203d57486e2SRobert Watson /* Methods on semaphores. */ 204d57486e2SRobert Watson { CAP_SEM_GETVALUE, "sg" }, 205d57486e2SRobert Watson { CAP_SEM_POST, "sp" }, 206d57486e2SRobert Watson { CAP_SEM_WAIT, "sw" }, 207d57486e2SRobert Watson 208d57486e2SRobert Watson /* Event monitoring and posting. */ 209ed5848c8SPawel Jakub Dawidek { CAP_EVENT, "ev" }, 210ed5848c8SPawel Jakub Dawidek { CAP_KQUEUE_EVENT, "ke" }, 211ed5848c8SPawel Jakub Dawidek { CAP_KQUEUE_CHANGE, "kc" }, 212d57486e2SRobert Watson 213d57486e2SRobert Watson /* Strange and powerful rights that should not be given lightly. */ 214d57486e2SRobert Watson { CAP_IOCTL, "io" }, 215d57486e2SRobert Watson { CAP_TTYHOOK, "ty" }, 216d57486e2SRobert Watson 2176a9f247cSPawel Jakub Dawidek /* Process management via process descriptors. */ 218d57486e2SRobert Watson { CAP_PDGETPID, "pg" }, 2196a9f247cSPawel Jakub Dawidek { CAP_PDWAIT, "pw" }, 220d57486e2SRobert Watson { CAP_PDKILL, "pk" }, 2212609222aSPawel Jakub Dawidek 2227493f24eSPawel Jakub Dawidek /* 2237493f24eSPawel Jakub Dawidek * Rights that allow to use bindat(2) and connectat(2) syscalls on a 2247493f24eSPawel Jakub Dawidek * directory descriptor. 2257493f24eSPawel Jakub Dawidek */ 2267493f24eSPawel Jakub Dawidek { CAP_BINDAT, "ba" }, 2277493f24eSPawel Jakub Dawidek { CAP_CONNECTAT, "ca" }, 2287493f24eSPawel Jakub Dawidek 2292609222aSPawel Jakub Dawidek /* Aliases and defines that combine multiple rights. */ 2302609222aSPawel Jakub Dawidek { CAP_PREAD, "prd" }, 2312609222aSPawel Jakub Dawidek { CAP_PWRITE, "pwr" }, 2322609222aSPawel Jakub Dawidek 2332609222aSPawel Jakub Dawidek { CAP_MMAP_R, "mmr" }, 2342609222aSPawel Jakub Dawidek { CAP_MMAP_W, "mmw" }, 2352609222aSPawel Jakub Dawidek { CAP_MMAP_X, "mmx" }, 2362609222aSPawel Jakub Dawidek { CAP_MMAP_RW, "mrw" }, 2372609222aSPawel Jakub Dawidek { CAP_MMAP_RX, "mrx" }, 2382609222aSPawel Jakub Dawidek { CAP_MMAP_WX, "mwx" }, 2392609222aSPawel Jakub Dawidek { CAP_MMAP_RWX, "mma" }, 2402609222aSPawel Jakub Dawidek 2412609222aSPawel Jakub Dawidek { CAP_RECV, "re" }, 2422609222aSPawel Jakub Dawidek { CAP_SEND, "sd" }, 2432609222aSPawel Jakub Dawidek 2442609222aSPawel Jakub Dawidek { CAP_SOCK_CLIENT, "scl" }, 2452609222aSPawel Jakub Dawidek { CAP_SOCK_SERVER, "ssr" }, 246d57486e2SRobert Watson }; 247f18e52f4SMarcelo Araujo static const u_int cap_desc_count = nitems(cap_desc); 248d57486e2SRobert Watson 249d57486e2SRobert Watson static u_int 2507008be5bSPawel Jakub Dawidek width_capability(cap_rights_t *rightsp) 251d57486e2SRobert Watson { 252d57486e2SRobert Watson u_int count, i, width; 253d57486e2SRobert Watson 254d57486e2SRobert Watson count = 0; 255d57486e2SRobert Watson width = 0; 256d57486e2SRobert Watson for (i = 0; i < cap_desc_count; i++) { 2577008be5bSPawel Jakub Dawidek if (cap_rights_is_set(rightsp, cap_desc[i].cd_right)) { 258d57486e2SRobert Watson width += strlen(cap_desc[i].cd_desc); 259d57486e2SRobert Watson if (count) 260d57486e2SRobert Watson width++; 261d57486e2SRobert Watson count++; 262d57486e2SRobert Watson } 263d57486e2SRobert Watson } 264d57486e2SRobert Watson return (width); 265d57486e2SRobert Watson } 266d57486e2SRobert Watson 267d57486e2SRobert Watson static void 2687008be5bSPawel Jakub Dawidek print_capability(cap_rights_t *rightsp, u_int capwidth) 269d57486e2SRobert Watson { 270d57486e2SRobert Watson u_int count, i, width; 271d57486e2SRobert Watson 272d57486e2SRobert Watson count = 0; 273d57486e2SRobert Watson width = 0; 2747008be5bSPawel Jakub Dawidek for (i = width_capability(rightsp); i < capwidth; i++) { 2757008be5bSPawel Jakub Dawidek if (i != 0) 276474b62b8SAllan Jude xo_emit(" "); 277d57486e2SRobert Watson else 278474b62b8SAllan Jude xo_emit("-"); 279d57486e2SRobert Watson } 280474b62b8SAllan Jude xo_open_list("capabilities"); 281d57486e2SRobert Watson for (i = 0; i < cap_desc_count; i++) { 2827008be5bSPawel Jakub Dawidek if (cap_rights_is_set(rightsp, cap_desc[i].cd_right)) { 283474b62b8SAllan Jude xo_emit("{D:/%s}{l:capabilities/%s}", count ? "," : "", 284474b62b8SAllan Jude cap_desc[i].cd_desc); 285d57486e2SRobert Watson width += strlen(cap_desc[i].cd_desc); 286d57486e2SRobert Watson if (count) 287d57486e2SRobert Watson width++; 288d57486e2SRobert Watson count++; 289d57486e2SRobert Watson } 290d57486e2SRobert Watson } 291474b62b8SAllan Jude xo_close_list("capabilities"); 292d57486e2SRobert Watson } 293d57486e2SRobert Watson 2943d91be41SRobert Watson void 2950daf62d9SStanislav Sedov procstat_files(struct procstat *procstat, struct kinfo_proc *kipp) 2963d91be41SRobert Watson { 2970daf62d9SStanislav Sedov struct sockstat sock; 2980daf62d9SStanislav Sedov struct filestat_list *head; 2990daf62d9SStanislav Sedov struct filestat *fst; 3003d91be41SRobert Watson const char *str; 3010daf62d9SStanislav Sedov struct vnstat vn; 302d57486e2SRobert Watson u_int capwidth, width; 3030daf62d9SStanislav Sedov int error; 304474b62b8SAllan Jude char src_addr[PATH_MAX]; 305474b62b8SAllan Jude char dst_addr[PATH_MAX]; 3063d91be41SRobert Watson 307d57486e2SRobert Watson /* 308d57486e2SRobert Watson * To print the header in capability mode, we need to know the width 309d57486e2SRobert Watson * of the widest capability string. Even if we get no processes 310d57486e2SRobert Watson * back, we will print the header, so we defer aborting due to a lack 311d57486e2SRobert Watson * of processes until after the header logic. 312d57486e2SRobert Watson */ 313d57486e2SRobert Watson capwidth = 0; 3140daf62d9SStanislav Sedov head = procstat_getfiles(procstat, kipp, 0); 3152a243b95SBrooks Davis if (head != NULL && 3162a243b95SBrooks Davis (procstat_opts & PS_OPT_CAPABILITIES) != 0) { 317d57486e2SRobert Watson STAILQ_FOREACH(fst, head, next) { 3187008be5bSPawel Jakub Dawidek width = width_capability(&fst->fs_cap_rights); 319d57486e2SRobert Watson if (width > capwidth) 320d57486e2SRobert Watson capwidth = width; 321d57486e2SRobert Watson } 322d57486e2SRobert Watson if (capwidth < strlen("CAPABILITIES")) 323d57486e2SRobert Watson capwidth = strlen("CAPABILITIES"); 324d57486e2SRobert Watson } 325d57486e2SRobert Watson 3262a243b95SBrooks Davis if ((procstat_opts & PS_OPT_NOHEADER) == 0) { 3272a243b95SBrooks Davis if ((procstat_opts & PS_OPT_CAPABILITIES) != 0) 328474b62b8SAllan Jude xo_emit("{T:/%5s %-16s %5s %1s %-8s %-*s " 329474b62b8SAllan Jude "%-3s %-12s}\n", "PID", "COMM", "FD", "T", 330d57486e2SRobert Watson "FLAGS", capwidth, "CAPABILITIES", "PRO", 331d57486e2SRobert Watson "NAME"); 332d57486e2SRobert Watson else 333474b62b8SAllan Jude xo_emit("{T:/%5s %-16s %5s %1s %1s %-8s " 334474b62b8SAllan Jude "%3s %7s %-3s %-12s}\n", "PID", "COMM", "FD", "T", 335d57486e2SRobert Watson "V", "FLAGS", "REF", "OFFSET", "PRO", "NAME"); 336d57486e2SRobert Watson } 337d57486e2SRobert Watson 3380daf62d9SStanislav Sedov if (head == NULL) 33908afefa8SJoe Marcus Clarke return; 340474b62b8SAllan Jude xo_emit("{ek:process_id/%5d/%d}", kipp->ki_pid); 341474b62b8SAllan Jude xo_emit("{e:command/%-16s/%s}", kipp->ki_comm); 342474b62b8SAllan Jude xo_open_list("files"); 3430daf62d9SStanislav Sedov STAILQ_FOREACH(fst, head, next) { 344474b62b8SAllan Jude xo_open_instance("files"); 345474b62b8SAllan Jude xo_emit("{dk:process_id/%5d/%d} ", kipp->ki_pid); 346474b62b8SAllan Jude xo_emit("{d:command/%-16s/%s} ", kipp->ki_comm); 3470daf62d9SStanislav Sedov if (fst->fs_uflags & PS_FST_UFLAG_CTTY) 348474b62b8SAllan Jude xo_emit("{P: }{:fd/%s} ", "ctty"); 3490daf62d9SStanislav Sedov else if (fst->fs_uflags & PS_FST_UFLAG_CDIR) 350474b62b8SAllan Jude xo_emit("{P: }{:fd/%s} ", "cwd"); 3510daf62d9SStanislav Sedov else if (fst->fs_uflags & PS_FST_UFLAG_JAIL) 352474b62b8SAllan Jude xo_emit("{P: }{:fd/%s} ", "jail"); 3530daf62d9SStanislav Sedov else if (fst->fs_uflags & PS_FST_UFLAG_RDIR) 354474b62b8SAllan Jude xo_emit("{P: }{:fd/%s} ", "root"); 3550daf62d9SStanislav Sedov else if (fst->fs_uflags & PS_FST_UFLAG_TEXT) 356474b62b8SAllan Jude xo_emit("{P: }{:fd/%s} ", "text"); 3570daf62d9SStanislav Sedov else if (fst->fs_uflags & PS_FST_UFLAG_TRACE) 358474b62b8SAllan Jude xo_emit("{:fd/%s} ", "trace"); 3590daf62d9SStanislav Sedov else 360474b62b8SAllan Jude xo_emit("{:fd/%5d} ", fst->fs_fd); 361f2805949SJoe Marcus Clarke 3620daf62d9SStanislav Sedov switch (fst->fs_type) { 3630daf62d9SStanislav Sedov case PS_FST_TYPE_VNODE: 3643d91be41SRobert Watson str = "v"; 365474b62b8SAllan Jude xo_emit("{eq:fd_type/vnode}"); 3663d91be41SRobert Watson break; 3673d91be41SRobert Watson 3680daf62d9SStanislav Sedov case PS_FST_TYPE_SOCKET: 3693d91be41SRobert Watson str = "s"; 370474b62b8SAllan Jude xo_emit("{eq:fd_type/socket}"); 3713d91be41SRobert Watson break; 3723d91be41SRobert Watson 3730daf62d9SStanislav Sedov case PS_FST_TYPE_PIPE: 3743d91be41SRobert Watson str = "p"; 375474b62b8SAllan Jude xo_emit("{eq:fd_type/pipe}"); 3763d91be41SRobert Watson break; 3773d91be41SRobert Watson 3780daf62d9SStanislav Sedov case PS_FST_TYPE_FIFO: 3793d91be41SRobert Watson str = "f"; 380474b62b8SAllan Jude xo_emit("{eq:fd_type/fifo}"); 3813d91be41SRobert Watson break; 3823d91be41SRobert Watson 3830daf62d9SStanislav Sedov case PS_FST_TYPE_KQUEUE: 3843d91be41SRobert Watson str = "k"; 385474b62b8SAllan Jude xo_emit("{eq:fd_type/kqueue}"); 3863d91be41SRobert Watson break; 3873d91be41SRobert Watson 3880daf62d9SStanislav Sedov case PS_FST_TYPE_MQUEUE: 3893d91be41SRobert Watson str = "m"; 390474b62b8SAllan Jude xo_emit("{eq:fd_type/mqueue}"); 3913d91be41SRobert Watson break; 3923d91be41SRobert Watson 3930daf62d9SStanislav Sedov case PS_FST_TYPE_SHM: 39487cb56f6SRobert Watson str = "h"; 395474b62b8SAllan Jude xo_emit("{eq:fd_type/shm}"); 39687cb56f6SRobert Watson break; 39787cb56f6SRobert Watson 3980daf62d9SStanislav Sedov case PS_FST_TYPE_PTS: 399bc093719SEd Schouten str = "t"; 400474b62b8SAllan Jude xo_emit("{eq:fd_type/pts}"); 401bc093719SEd Schouten break; 402bc093719SEd Schouten 4030daf62d9SStanislav Sedov case PS_FST_TYPE_SEM: 4046bc1e9cdSJohn Baldwin str = "e"; 405474b62b8SAllan Jude xo_emit("{eq:fd_type/sem}"); 4066bc1e9cdSJohn Baldwin break; 4076bc1e9cdSJohn Baldwin 4083cfa7c6eSEdward Tomasz Napierala case PS_FST_TYPE_PROCDESC: 4093cfa7c6eSEdward Tomasz Napierala str = "P"; 4103cfa7c6eSEdward Tomasz Napierala xo_emit("{eq:fd_type/procdesc}"); 4113cfa7c6eSEdward Tomasz Napierala break; 4123cfa7c6eSEdward Tomasz Napierala 413a66732deSKonstantin Belousov case PS_FST_TYPE_DEV: 414a66732deSKonstantin Belousov str = "D"; 415a66732deSKonstantin Belousov xo_emit("{eq:fd_type/dev}"); 416a66732deSKonstantin Belousov break; 417a66732deSKonstantin Belousov 41867af9abaSKonstantin Belousov case PS_FST_TYPE_EVENTFD: 41967af9abaSKonstantin Belousov str = "E"; 42067af9abaSKonstantin Belousov xo_emit("{eq:fd_type/eventfd}"); 42167af9abaSKonstantin Belousov break; 42267af9abaSKonstantin Belousov 4230daf62d9SStanislav Sedov case PS_FST_TYPE_NONE: 424474b62b8SAllan Jude str = "?"; 425474b62b8SAllan Jude xo_emit("{eq:fd_type/none}"); 426474b62b8SAllan Jude break; 427474b62b8SAllan Jude 4280daf62d9SStanislav Sedov case PS_FST_TYPE_UNKNOWN: 4293d91be41SRobert Watson default: 4303d91be41SRobert Watson str = "?"; 431474b62b8SAllan Jude xo_emit("{eq:fd_type/unknown}"); 4323d91be41SRobert Watson break; 4333d91be41SRobert Watson } 434474b62b8SAllan Jude xo_emit("{d:fd_type/%1s/%s} ", str); 4352a243b95SBrooks Davis if ((procstat_opts & PS_OPT_CAPABILITIES) == 0) { 4363d91be41SRobert Watson str = "-"; 4370daf62d9SStanislav Sedov if (fst->fs_type == PS_FST_TYPE_VNODE) { 438d57486e2SRobert Watson error = procstat_get_vnode_info(procstat, fst, 439d57486e2SRobert Watson &vn, NULL); 4400daf62d9SStanislav Sedov switch (vn.vn_type) { 4410daf62d9SStanislav Sedov case PS_FST_VTYPE_VREG: 4423d91be41SRobert Watson str = "r"; 443474b62b8SAllan Jude xo_emit("{eq:vode_type/regular}"); 4443d91be41SRobert Watson break; 4453d91be41SRobert Watson 4460daf62d9SStanislav Sedov case PS_FST_VTYPE_VDIR: 4473d91be41SRobert Watson str = "d"; 448474b62b8SAllan Jude xo_emit("{eq:vode_type/directory}"); 4493d91be41SRobert Watson break; 4503d91be41SRobert Watson 4510daf62d9SStanislav Sedov case PS_FST_VTYPE_VBLK: 4523d91be41SRobert Watson str = "b"; 453474b62b8SAllan Jude xo_emit("{eq:vode_type/block}"); 4543d91be41SRobert Watson break; 4553d91be41SRobert Watson 4560daf62d9SStanislav Sedov case PS_FST_VTYPE_VCHR: 4573d91be41SRobert Watson str = "c"; 458474b62b8SAllan Jude xo_emit("{eq:vode_type/character}"); 4593d91be41SRobert Watson break; 4603d91be41SRobert Watson 4610daf62d9SStanislav Sedov case PS_FST_VTYPE_VLNK: 4623d91be41SRobert Watson str = "l"; 463474b62b8SAllan Jude xo_emit("{eq:vode_type/link}"); 4643d91be41SRobert Watson break; 4653d91be41SRobert Watson 4660daf62d9SStanislav Sedov case PS_FST_VTYPE_VSOCK: 4673d91be41SRobert Watson str = "s"; 468474b62b8SAllan Jude xo_emit("{eq:vode_type/socket}"); 4693d91be41SRobert Watson break; 4703d91be41SRobert Watson 4710daf62d9SStanislav Sedov case PS_FST_VTYPE_VFIFO: 4723d91be41SRobert Watson str = "f"; 473474b62b8SAllan Jude xo_emit("{eq:vode_type/fifo}"); 4743d91be41SRobert Watson break; 4753d91be41SRobert Watson 4760daf62d9SStanislav Sedov case PS_FST_VTYPE_VBAD: 4773d91be41SRobert Watson str = "x"; 478474b62b8SAllan Jude xo_emit("{eq:vode_type/revoked_device}"); 4793d91be41SRobert Watson break; 4803d91be41SRobert Watson 4810daf62d9SStanislav Sedov case PS_FST_VTYPE_VNON: 482474b62b8SAllan Jude str = "?"; 483474b62b8SAllan Jude xo_emit("{eq:vode_type/non}"); 484474b62b8SAllan Jude break; 485474b62b8SAllan Jude 4860daf62d9SStanislav Sedov case PS_FST_VTYPE_UNKNOWN: 4873d91be41SRobert Watson default: 4883d91be41SRobert Watson str = "?"; 489474b62b8SAllan Jude xo_emit("{eq:vode_type/unknown}"); 4903d91be41SRobert Watson break; 4913d91be41SRobert Watson } 4923d91be41SRobert Watson } 493474b62b8SAllan Jude xo_emit("{d:vnode_type/%1s/%s} ", str); 494d57486e2SRobert Watson } 495474b62b8SAllan Jude 496474b62b8SAllan Jude xo_emit("{d:/%s}", fst->fs_fflags & PS_FST_FFLAG_READ ? 497474b62b8SAllan Jude "r" : "-"); 498474b62b8SAllan Jude xo_emit("{d:/%s}", fst->fs_fflags & PS_FST_FFLAG_WRITE ? 499474b62b8SAllan Jude "w" : "-"); 500474b62b8SAllan Jude xo_emit("{d:/%s}", fst->fs_fflags & PS_FST_FFLAG_APPEND ? 501474b62b8SAllan Jude "a" : "-"); 502474b62b8SAllan Jude xo_emit("{d:/%s}", fst->fs_fflags & PS_FST_FFLAG_ASYNC ? 503474b62b8SAllan Jude "s" : "-"); 504474b62b8SAllan Jude xo_emit("{d:/%s}", fst->fs_fflags & PS_FST_FFLAG_SYNC ? 505474b62b8SAllan Jude "f" : "-"); 506474b62b8SAllan Jude xo_emit("{d:/%s}", fst->fs_fflags & PS_FST_FFLAG_NONBLOCK ? 507474b62b8SAllan Jude "n" : "-"); 508474b62b8SAllan Jude xo_emit("{d:/%s}", fst->fs_fflags & PS_FST_FFLAG_DIRECT ? 509474b62b8SAllan Jude "d" : "-"); 510474b62b8SAllan Jude xo_emit("{d:/%s}", fst->fs_fflags & PS_FST_FFLAG_HASLOCK ? 511474b62b8SAllan Jude "l" : "-"); 512474b62b8SAllan Jude xo_emit(" "); 513474b62b8SAllan Jude xo_open_list("fd_flags"); 514474b62b8SAllan Jude if (fst->fs_fflags & PS_FST_FFLAG_READ) 515474b62b8SAllan Jude xo_emit("{elq:fd_flags/read}"); 516474b62b8SAllan Jude if (fst->fs_fflags & PS_FST_FFLAG_WRITE) 517474b62b8SAllan Jude xo_emit("{elq:fd_flags/write}"); 518474b62b8SAllan Jude if (fst->fs_fflags & PS_FST_FFLAG_APPEND) 519474b62b8SAllan Jude xo_emit("{elq:fd_flags/append}"); 520474b62b8SAllan Jude if (fst->fs_fflags & PS_FST_FFLAG_ASYNC) 521474b62b8SAllan Jude xo_emit("{elq:fd_flags/async}"); 522474b62b8SAllan Jude if (fst->fs_fflags & PS_FST_FFLAG_SYNC) 523474b62b8SAllan Jude xo_emit("{elq:fd_flags/fsync}"); 524474b62b8SAllan Jude if (fst->fs_fflags & PS_FST_FFLAG_NONBLOCK) 525474b62b8SAllan Jude xo_emit("{elq:fd_flags/nonblocking}"); 526474b62b8SAllan Jude if (fst->fs_fflags & PS_FST_FFLAG_DIRECT) 527474b62b8SAllan Jude xo_emit("{elq:fd_flags/direct_io}"); 528474b62b8SAllan Jude if (fst->fs_fflags & PS_FST_FFLAG_HASLOCK) 529474b62b8SAllan Jude xo_emit("{elq:fd_flags/lock_held}"); 530474b62b8SAllan Jude xo_close_list("fd_flags"); 531474b62b8SAllan Jude 5322a243b95SBrooks Davis if ((procstat_opts & PS_OPT_CAPABILITIES) == 0) { 5330daf62d9SStanislav Sedov if (fst->fs_ref_count > -1) 534474b62b8SAllan Jude xo_emit("{:ref_count/%3d/%d} ", 535474b62b8SAllan Jude fst->fs_ref_count); 536f2805949SJoe Marcus Clarke else 537474b62b8SAllan Jude xo_emit("{q:ref_count/%3c/%c} ", '-'); 5380daf62d9SStanislav Sedov if (fst->fs_offset > -1) 539474b62b8SAllan Jude xo_emit("{:offset/%7jd/%jd} ", 540474b62b8SAllan Jude (intmax_t)fst->fs_offset); 541f2805949SJoe Marcus Clarke else 542474b62b8SAllan Jude xo_emit("{q:offset/%7c/%c} ", '-'); 543d57486e2SRobert Watson } 5442a243b95SBrooks Davis if ((procstat_opts & PS_OPT_CAPABILITIES) != 0) { 5457008be5bSPawel Jakub Dawidek print_capability(&fst->fs_cap_rights, capwidth); 546474b62b8SAllan Jude xo_emit(" "); 547d57486e2SRobert Watson } 5480daf62d9SStanislav Sedov switch (fst->fs_type) { 5490daf62d9SStanislav Sedov case PS_FST_TYPE_SOCKET: 550474b62b8SAllan Jude error = procstat_get_socket_info(procstat, fst, &sock, 551474b62b8SAllan Jude NULL); 5520daf62d9SStanislav Sedov if (error != 0) 5530daf62d9SStanislav Sedov break; 554474b62b8SAllan Jude xo_emit("{:protocol/%-3s/%s} ", 5550daf62d9SStanislav Sedov protocol_to_string(sock.dom_family, 5560daf62d9SStanislav Sedov sock.type, sock.proto)); 55795b97895SConrad Meyer if (sock.proto == IPPROTO_TCP || 55895b97895SConrad Meyer sock.proto == IPPROTO_SCTP || 55995b97895SConrad Meyer sock.type == SOCK_STREAM) { 56095b97895SConrad Meyer xo_emit("{:sendq/%u} ", sock.sendq); 56195b97895SConrad Meyer xo_emit("{:recvq/%u} ", sock.recvq); 56295b97895SConrad Meyer } 5633d91be41SRobert Watson /* 5643d91be41SRobert Watson * While generally we like to print two addresses, 5653d91be41SRobert Watson * local and peer, for sockets, it turns out to be 5663d91be41SRobert Watson * more useful to print the first non-nul address for 5673d91be41SRobert Watson * local sockets, as typically they aren't bound and 5683d91be41SRobert Watson * connected, and the path strings can get long. 5693d91be41SRobert Watson */ 5700daf62d9SStanislav Sedov if (sock.dom_family == AF_LOCAL) { 5713d91be41SRobert Watson struct sockaddr_un *sun = 5720daf62d9SStanislav Sedov (struct sockaddr_un *)&sock.sa_local; 5733d91be41SRobert Watson 5743d91be41SRobert Watson if (sun->sun_path[0] != 0) 575474b62b8SAllan Jude addr_to_string(&sock.sa_local, 576474b62b8SAllan Jude src_addr, sizeof(src_addr)); 5773d91be41SRobert Watson else 578474b62b8SAllan Jude addr_to_string(&sock.sa_peer, 579474b62b8SAllan Jude src_addr, sizeof(src_addr)); 580474b62b8SAllan Jude xo_emit("{:path/%s}", src_addr); 5813d91be41SRobert Watson } else { 582474b62b8SAllan Jude addr_to_string(&sock.sa_local, src_addr, 583474b62b8SAllan Jude sizeof(src_addr)); 584474b62b8SAllan Jude addr_to_string(&sock.sa_peer, dst_addr, 585474b62b8SAllan Jude sizeof(dst_addr)); 586474b62b8SAllan Jude xo_emit("{:path/%s %s}", src_addr, dst_addr); 5873d91be41SRobert Watson } 5883d91be41SRobert Watson break; 5893d91be41SRobert Watson 5903d91be41SRobert Watson default: 591474b62b8SAllan Jude xo_emit("{:protocol/%-3s/%s} ", "-"); 592474b62b8SAllan Jude xo_emit("{:path/%-18s/%s}", fst->fs_path != NULL ? 593474b62b8SAllan Jude fst->fs_path : "-"); 5943d91be41SRobert Watson } 5953d91be41SRobert Watson 596474b62b8SAllan Jude xo_emit("\n"); 597474b62b8SAllan Jude xo_close_instance("files"); 5983d91be41SRobert Watson } 599474b62b8SAllan Jude xo_close_list("files"); 60039f6ca65SMikolaj Golub procstat_freefiles(procstat, head); 6013d91be41SRobert Watson } 602