13d91be41SRobert Watson /*-
24d846d26SWarner 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
30e1f323f3SRobert Watson #include <sys/param.h>
31b881b8beSRobert Watson #include <sys/capsicum.h>
323d91be41SRobert Watson #include <sys/socket.h>
333d91be41SRobert Watson #include <sys/sysctl.h>
343d91be41SRobert Watson #include <sys/un.h>
353d91be41SRobert Watson #include <sys/user.h>
363d91be41SRobert Watson
373d91be41SRobert Watson #include <netinet/in.h>
383d91be41SRobert Watson
393d91be41SRobert Watson #include <arpa/inet.h>
403d91be41SRobert Watson
41821df508SXin LI #include <err.h>
420daf62d9SStanislav Sedov #include <libprocstat.h>
433d91be41SRobert Watson #include <inttypes.h>
443d91be41SRobert Watson #include <stdio.h>
453d91be41SRobert Watson #include <stdlib.h>
463d91be41SRobert Watson #include <string.h>
473d91be41SRobert Watson
483d91be41SRobert Watson #include "procstat.h"
493d91be41SRobert Watson
503d91be41SRobert Watson static const char *
protocol_to_string(int domain,int type,int protocol)513d91be41SRobert Watson protocol_to_string(int domain, int type, int protocol)
523d91be41SRobert Watson {
533d91be41SRobert Watson
543d91be41SRobert Watson switch (domain) {
553d91be41SRobert Watson case AF_INET:
563d91be41SRobert Watson case AF_INET6:
573d91be41SRobert Watson switch (protocol) {
583d91be41SRobert Watson case IPPROTO_TCP:
593d91be41SRobert Watson return ("TCP");
603d91be41SRobert Watson case IPPROTO_UDP:
613d91be41SRobert Watson return ("UDP");
623d91be41SRobert Watson case IPPROTO_ICMP:
635a246d29SRobert Watson return ("ICM");
643d91be41SRobert Watson case IPPROTO_RAW:
653d91be41SRobert Watson return ("RAW");
663d91be41SRobert Watson case IPPROTO_SCTP:
675a246d29SRobert Watson return ("SCT");
683d91be41SRobert Watson default:
695a246d29SRobert Watson return ("IP?");
703d91be41SRobert Watson }
713d91be41SRobert Watson
723d91be41SRobert Watson case AF_LOCAL:
733d91be41SRobert Watson switch (type) {
743d91be41SRobert Watson case SOCK_STREAM:
755a246d29SRobert Watson return ("UDS");
763d91be41SRobert Watson case SOCK_DGRAM:
775a246d29SRobert Watson return ("UDD");
78*8011df62SKonstantin Belousov case SOCK_SEQPACKET:
79*8011df62SKonstantin Belousov return ("UDQ");
803d91be41SRobert Watson default:
815a246d29SRobert Watson return ("UD?");
823d91be41SRobert Watson }
831f3d8c09SGleb Smirnoff case AF_DIVERT:
841f3d8c09SGleb Smirnoff return ("IPD");
851f3d8c09SGleb Smirnoff break;
863d91be41SRobert Watson default:
875a246d29SRobert Watson return ("?");
883d91be41SRobert Watson }
893d91be41SRobert Watson }
903d91be41SRobert Watson
913d91be41SRobert Watson static void
addr_to_string(struct sockaddr_storage * ss,char * buffer,int buflen)923d91be41SRobert Watson addr_to_string(struct sockaddr_storage *ss, char *buffer, int buflen)
933d91be41SRobert Watson {
943d91be41SRobert Watson char buffer2[INET6_ADDRSTRLEN];
953d91be41SRobert Watson struct sockaddr_in6 *sin6;
963d91be41SRobert Watson struct sockaddr_in *sin;
973d91be41SRobert Watson struct sockaddr_un *sun;
983d91be41SRobert Watson
993d91be41SRobert Watson switch (ss->ss_family) {
1003d91be41SRobert Watson case AF_LOCAL:
1013d91be41SRobert Watson sun = (struct sockaddr_un *)ss;
1023d91be41SRobert Watson if (strlen(sun->sun_path) == 0)
1033d91be41SRobert Watson strlcpy(buffer, "-", buflen);
1043d91be41SRobert Watson else
1053d91be41SRobert Watson strlcpy(buffer, sun->sun_path, buflen);
1063d91be41SRobert Watson break;
1073d91be41SRobert Watson
1083d91be41SRobert Watson case AF_INET:
1093d91be41SRobert Watson sin = (struct sockaddr_in *)ss;
110ce0372d7SJeremie Le Hen if (sin->sin_addr.s_addr == INADDR_ANY)
111b9eabd15SJeremie Le Hen snprintf(buffer, buflen, "%s:%d", "*",
112b9eabd15SJeremie Le Hen ntohs(sin->sin_port));
113b9eabd15SJeremie Le Hen else if (inet_ntop(AF_INET, &sin->sin_addr, buffer2,
114b9eabd15SJeremie Le Hen sizeof(buffer2)) != NULL)
115b9eabd15SJeremie Le Hen snprintf(buffer, buflen, "%s:%d", buffer2,
1163d91be41SRobert Watson ntohs(sin->sin_port));
1173d91be41SRobert Watson break;
1183d91be41SRobert Watson
1193d91be41SRobert Watson case AF_INET6:
1203d91be41SRobert Watson sin6 = (struct sockaddr_in6 *)ss;
1213d91be41SRobert Watson if (inet_ntop(AF_INET6, &sin6->sin6_addr, buffer2,
1223d91be41SRobert Watson sizeof(buffer2)) != NULL)
1233d91be41SRobert Watson snprintf(buffer, buflen, "%s.%d", buffer2,
1243d91be41SRobert Watson ntohs(sin6->sin6_port));
1253d91be41SRobert Watson else
12601967281SXin LI strlcpy(buffer, "-", buflen);
1273d91be41SRobert Watson break;
1283d91be41SRobert Watson
1293d91be41SRobert Watson default:
1303d91be41SRobert Watson strlcpy(buffer, "", buflen);
1313d91be41SRobert Watson break;
1323d91be41SRobert Watson }
1333d91be41SRobert Watson }
1343d91be41SRobert Watson
135d57486e2SRobert Watson static struct cap_desc {
1367008be5bSPawel Jakub Dawidek uint64_t cd_right;
137d57486e2SRobert Watson const char *cd_desc;
138d57486e2SRobert Watson } cap_desc[] = {
139d57486e2SRobert Watson /* General file I/O. */
140d57486e2SRobert Watson { CAP_READ, "rd" },
141d57486e2SRobert Watson { CAP_WRITE, "wr" },
1422609222aSPawel Jakub Dawidek { CAP_SEEK, "se" },
143d57486e2SRobert Watson { CAP_MMAP, "mm" },
1442609222aSPawel Jakub Dawidek { CAP_CREATE, "cr" },
145d57486e2SRobert Watson { CAP_FEXECVE, "fe" },
146d57486e2SRobert Watson { CAP_FSYNC, "fy" },
147d57486e2SRobert Watson { CAP_FTRUNCATE, "ft" },
148d57486e2SRobert Watson
149d57486e2SRobert Watson /* VFS methods. */
150d57486e2SRobert Watson { CAP_FCHDIR, "cd" },
1512609222aSPawel Jakub Dawidek { CAP_FCHFLAGS, "cf" },
152d57486e2SRobert Watson { CAP_FCHMOD, "cm" },
153d57486e2SRobert Watson { CAP_FCHOWN, "cn" },
154b165e9e3SEdward Tomasz Napierala { CAP_FCHROOT, "ct" },
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
width_capability(cap_rights_t * rightsp)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
print_capability(cap_rights_t * rightsp,u_int capwidth)2687008be5bSPawel Jakub Dawidek print_capability(cap_rights_t *rightsp, u_int capwidth)
269d57486e2SRobert Watson {
270660d6c5cSJohn Baldwin u_int count, i;
271d57486e2SRobert Watson
272d57486e2SRobert Watson count = 0;
2737008be5bSPawel Jakub Dawidek for (i = width_capability(rightsp); i < capwidth; i++) {
2747008be5bSPawel Jakub Dawidek if (i != 0)
275474b62b8SAllan Jude xo_emit(" ");
276d57486e2SRobert Watson else
277474b62b8SAllan Jude xo_emit("-");
278d57486e2SRobert Watson }
279474b62b8SAllan Jude xo_open_list("capabilities");
280d57486e2SRobert Watson for (i = 0; i < cap_desc_count; i++) {
2817008be5bSPawel Jakub Dawidek if (cap_rights_is_set(rightsp, cap_desc[i].cd_right)) {
282474b62b8SAllan Jude xo_emit("{D:/%s}{l:capabilities/%s}", count ? "," : "",
283474b62b8SAllan Jude cap_desc[i].cd_desc);
284d57486e2SRobert Watson count++;
285d57486e2SRobert Watson }
286d57486e2SRobert Watson }
287474b62b8SAllan Jude xo_close_list("capabilities");
288d57486e2SRobert Watson }
289d57486e2SRobert Watson
2903d91be41SRobert Watson void
procstat_files(struct procstat * procstat,struct kinfo_proc * kipp)2910daf62d9SStanislav Sedov procstat_files(struct procstat *procstat, struct kinfo_proc *kipp)
2923d91be41SRobert Watson {
2930daf62d9SStanislav Sedov struct sockstat sock;
2940daf62d9SStanislav Sedov struct filestat_list *head;
2950daf62d9SStanislav Sedov struct filestat *fst;
2963d91be41SRobert Watson const char *str;
2970daf62d9SStanislav Sedov struct vnstat vn;
298d57486e2SRobert Watson u_int capwidth, width;
2990daf62d9SStanislav Sedov int error;
300474b62b8SAllan Jude char src_addr[PATH_MAX];
301474b62b8SAllan Jude char dst_addr[PATH_MAX];
3023d91be41SRobert Watson
303d57486e2SRobert Watson /*
304d57486e2SRobert Watson * To print the header in capability mode, we need to know the width
305d57486e2SRobert Watson * of the widest capability string. Even if we get no processes
306d57486e2SRobert Watson * back, we will print the header, so we defer aborting due to a lack
307d57486e2SRobert Watson * of processes until after the header logic.
308d57486e2SRobert Watson */
309d57486e2SRobert Watson capwidth = 0;
3100daf62d9SStanislav Sedov head = procstat_getfiles(procstat, kipp, 0);
3112a243b95SBrooks Davis if (head != NULL &&
3122a243b95SBrooks Davis (procstat_opts & PS_OPT_CAPABILITIES) != 0) {
313d57486e2SRobert Watson STAILQ_FOREACH(fst, head, next) {
3147008be5bSPawel Jakub Dawidek width = width_capability(&fst->fs_cap_rights);
315d57486e2SRobert Watson if (width > capwidth)
316d57486e2SRobert Watson capwidth = width;
317d57486e2SRobert Watson }
318d57486e2SRobert Watson if (capwidth < strlen("CAPABILITIES"))
319d57486e2SRobert Watson capwidth = strlen("CAPABILITIES");
320d57486e2SRobert Watson }
321d57486e2SRobert Watson
3222a243b95SBrooks Davis if ((procstat_opts & PS_OPT_NOHEADER) == 0) {
3232a243b95SBrooks Davis if ((procstat_opts & PS_OPT_CAPABILITIES) != 0)
324474b62b8SAllan Jude xo_emit("{T:/%5s %-16s %5s %1s %-8s %-*s "
325474b62b8SAllan Jude "%-3s %-12s}\n", "PID", "COMM", "FD", "T",
326d57486e2SRobert Watson "FLAGS", capwidth, "CAPABILITIES", "PRO",
327d57486e2SRobert Watson "NAME");
328d57486e2SRobert Watson else
329474b62b8SAllan Jude xo_emit("{T:/%5s %-16s %5s %1s %1s %-8s "
330474b62b8SAllan Jude "%3s %7s %-3s %-12s}\n", "PID", "COMM", "FD", "T",
331d57486e2SRobert Watson "V", "FLAGS", "REF", "OFFSET", "PRO", "NAME");
332d57486e2SRobert Watson }
333d57486e2SRobert Watson
3340daf62d9SStanislav Sedov if (head == NULL)
33508afefa8SJoe Marcus Clarke return;
336474b62b8SAllan Jude xo_emit("{ek:process_id/%5d/%d}", kipp->ki_pid);
337474b62b8SAllan Jude xo_emit("{e:command/%-16s/%s}", kipp->ki_comm);
338474b62b8SAllan Jude xo_open_list("files");
3390daf62d9SStanislav Sedov STAILQ_FOREACH(fst, head, next) {
340474b62b8SAllan Jude xo_open_instance("files");
341474b62b8SAllan Jude xo_emit("{dk:process_id/%5d/%d} ", kipp->ki_pid);
342474b62b8SAllan Jude xo_emit("{d:command/%-16s/%s} ", kipp->ki_comm);
3430daf62d9SStanislav Sedov if (fst->fs_uflags & PS_FST_UFLAG_CTTY)
344474b62b8SAllan Jude xo_emit("{P: }{:fd/%s} ", "ctty");
3450daf62d9SStanislav Sedov else if (fst->fs_uflags & PS_FST_UFLAG_CDIR)
346474b62b8SAllan Jude xo_emit("{P: }{:fd/%s} ", "cwd");
3470daf62d9SStanislav Sedov else if (fst->fs_uflags & PS_FST_UFLAG_JAIL)
348474b62b8SAllan Jude xo_emit("{P: }{:fd/%s} ", "jail");
3490daf62d9SStanislav Sedov else if (fst->fs_uflags & PS_FST_UFLAG_RDIR)
350474b62b8SAllan Jude xo_emit("{P: }{:fd/%s} ", "root");
3510daf62d9SStanislav Sedov else if (fst->fs_uflags & PS_FST_UFLAG_TEXT)
352474b62b8SAllan Jude xo_emit("{P: }{:fd/%s} ", "text");
3530daf62d9SStanislav Sedov else if (fst->fs_uflags & PS_FST_UFLAG_TRACE)
354474b62b8SAllan Jude xo_emit("{:fd/%s} ", "trace");
3550daf62d9SStanislav Sedov else
356474b62b8SAllan Jude xo_emit("{:fd/%5d} ", fst->fs_fd);
357f2805949SJoe Marcus Clarke
3580daf62d9SStanislav Sedov switch (fst->fs_type) {
3590daf62d9SStanislav Sedov case PS_FST_TYPE_VNODE:
3603d91be41SRobert Watson str = "v";
361474b62b8SAllan Jude xo_emit("{eq:fd_type/vnode}");
3623d91be41SRobert Watson break;
3633d91be41SRobert Watson
3640daf62d9SStanislav Sedov case PS_FST_TYPE_SOCKET:
3653d91be41SRobert Watson str = "s";
366474b62b8SAllan Jude xo_emit("{eq:fd_type/socket}");
3673d91be41SRobert Watson break;
3683d91be41SRobert Watson
3690daf62d9SStanislav Sedov case PS_FST_TYPE_PIPE:
3703d91be41SRobert Watson str = "p";
371474b62b8SAllan Jude xo_emit("{eq:fd_type/pipe}");
3723d91be41SRobert Watson break;
3733d91be41SRobert Watson
3740daf62d9SStanislav Sedov case PS_FST_TYPE_FIFO:
3753d91be41SRobert Watson str = "f";
376474b62b8SAllan Jude xo_emit("{eq:fd_type/fifo}");
3773d91be41SRobert Watson break;
3783d91be41SRobert Watson
3790daf62d9SStanislav Sedov case PS_FST_TYPE_KQUEUE:
3803d91be41SRobert Watson str = "k";
381474b62b8SAllan Jude xo_emit("{eq:fd_type/kqueue}");
3823d91be41SRobert Watson break;
3833d91be41SRobert Watson
3840daf62d9SStanislav Sedov case PS_FST_TYPE_MQUEUE:
3853d91be41SRobert Watson str = "m";
386474b62b8SAllan Jude xo_emit("{eq:fd_type/mqueue}");
3873d91be41SRobert Watson break;
3883d91be41SRobert Watson
3890daf62d9SStanislav Sedov case PS_FST_TYPE_SHM:
39087cb56f6SRobert Watson str = "h";
391474b62b8SAllan Jude xo_emit("{eq:fd_type/shm}");
39287cb56f6SRobert Watson break;
39387cb56f6SRobert Watson
3940daf62d9SStanislav Sedov case PS_FST_TYPE_PTS:
395bc093719SEd Schouten str = "t";
396474b62b8SAllan Jude xo_emit("{eq:fd_type/pts}");
397bc093719SEd Schouten break;
398bc093719SEd Schouten
3990daf62d9SStanislav Sedov case PS_FST_TYPE_SEM:
4006bc1e9cdSJohn Baldwin str = "e";
401474b62b8SAllan Jude xo_emit("{eq:fd_type/sem}");
4026bc1e9cdSJohn Baldwin break;
4036bc1e9cdSJohn Baldwin
4043cfa7c6eSEdward Tomasz Napierala case PS_FST_TYPE_PROCDESC:
4053cfa7c6eSEdward Tomasz Napierala str = "P";
4063cfa7c6eSEdward Tomasz Napierala xo_emit("{eq:fd_type/procdesc}");
4073cfa7c6eSEdward Tomasz Napierala break;
4083cfa7c6eSEdward Tomasz Napierala
409a66732deSKonstantin Belousov case PS_FST_TYPE_DEV:
410a66732deSKonstantin Belousov str = "D";
411a66732deSKonstantin Belousov xo_emit("{eq:fd_type/dev}");
412a66732deSKonstantin Belousov break;
413a66732deSKonstantin Belousov
41467af9abaSKonstantin Belousov case PS_FST_TYPE_EVENTFD:
41567af9abaSKonstantin Belousov str = "E";
41667af9abaSKonstantin Belousov xo_emit("{eq:fd_type/eventfd}");
41767af9abaSKonstantin Belousov break;
41867af9abaSKonstantin Belousov
4190daf62d9SStanislav Sedov case PS_FST_TYPE_NONE:
420474b62b8SAllan Jude str = "?";
421474b62b8SAllan Jude xo_emit("{eq:fd_type/none}");
422474b62b8SAllan Jude break;
423474b62b8SAllan Jude
4240daf62d9SStanislav Sedov case PS_FST_TYPE_UNKNOWN:
4253d91be41SRobert Watson default:
4263d91be41SRobert Watson str = "?";
427474b62b8SAllan Jude xo_emit("{eq:fd_type/unknown}");
4283d91be41SRobert Watson break;
4293d91be41SRobert Watson }
430474b62b8SAllan Jude xo_emit("{d:fd_type/%1s/%s} ", str);
4312a243b95SBrooks Davis if ((procstat_opts & PS_OPT_CAPABILITIES) == 0) {
4323d91be41SRobert Watson str = "-";
4330daf62d9SStanislav Sedov if (fst->fs_type == PS_FST_TYPE_VNODE) {
434d57486e2SRobert Watson error = procstat_get_vnode_info(procstat, fst,
435d57486e2SRobert Watson &vn, NULL);
4360daf62d9SStanislav Sedov switch (vn.vn_type) {
4370daf62d9SStanislav Sedov case PS_FST_VTYPE_VREG:
4383d91be41SRobert Watson str = "r";
439474b62b8SAllan Jude xo_emit("{eq:vode_type/regular}");
4403d91be41SRobert Watson break;
4413d91be41SRobert Watson
4420daf62d9SStanislav Sedov case PS_FST_VTYPE_VDIR:
4433d91be41SRobert Watson str = "d";
444474b62b8SAllan Jude xo_emit("{eq:vode_type/directory}");
4453d91be41SRobert Watson break;
4463d91be41SRobert Watson
4470daf62d9SStanislav Sedov case PS_FST_VTYPE_VBLK:
4483d91be41SRobert Watson str = "b";
449474b62b8SAllan Jude xo_emit("{eq:vode_type/block}");
4503d91be41SRobert Watson break;
4513d91be41SRobert Watson
4520daf62d9SStanislav Sedov case PS_FST_VTYPE_VCHR:
4533d91be41SRobert Watson str = "c";
454474b62b8SAllan Jude xo_emit("{eq:vode_type/character}");
4553d91be41SRobert Watson break;
4563d91be41SRobert Watson
4570daf62d9SStanislav Sedov case PS_FST_VTYPE_VLNK:
4583d91be41SRobert Watson str = "l";
459474b62b8SAllan Jude xo_emit("{eq:vode_type/link}");
4603d91be41SRobert Watson break;
4613d91be41SRobert Watson
4620daf62d9SStanislav Sedov case PS_FST_VTYPE_VSOCK:
4633d91be41SRobert Watson str = "s";
464474b62b8SAllan Jude xo_emit("{eq:vode_type/socket}");
4653d91be41SRobert Watson break;
4663d91be41SRobert Watson
4670daf62d9SStanislav Sedov case PS_FST_VTYPE_VFIFO:
4683d91be41SRobert Watson str = "f";
469474b62b8SAllan Jude xo_emit("{eq:vode_type/fifo}");
4703d91be41SRobert Watson break;
4713d91be41SRobert Watson
4720daf62d9SStanislav Sedov case PS_FST_VTYPE_VBAD:
4733d91be41SRobert Watson str = "x";
474474b62b8SAllan Jude xo_emit("{eq:vode_type/revoked_device}");
4753d91be41SRobert Watson break;
4763d91be41SRobert Watson
4770daf62d9SStanislav Sedov case PS_FST_VTYPE_VNON:
478474b62b8SAllan Jude str = "?";
479474b62b8SAllan Jude xo_emit("{eq:vode_type/non}");
480474b62b8SAllan Jude break;
481474b62b8SAllan Jude
4820daf62d9SStanislav Sedov case PS_FST_VTYPE_UNKNOWN:
4833d91be41SRobert Watson default:
4843d91be41SRobert Watson str = "?";
485474b62b8SAllan Jude xo_emit("{eq:vode_type/unknown}");
4863d91be41SRobert Watson break;
4873d91be41SRobert Watson }
4883d91be41SRobert Watson }
489474b62b8SAllan Jude xo_emit("{d:vnode_type/%1s/%s} ", str);
490d57486e2SRobert Watson }
491474b62b8SAllan Jude
492474b62b8SAllan Jude xo_emit("{d:/%s}", fst->fs_fflags & PS_FST_FFLAG_READ ?
493474b62b8SAllan Jude "r" : "-");
494474b62b8SAllan Jude xo_emit("{d:/%s}", fst->fs_fflags & PS_FST_FFLAG_WRITE ?
495474b62b8SAllan Jude "w" : "-");
496474b62b8SAllan Jude xo_emit("{d:/%s}", fst->fs_fflags & PS_FST_FFLAG_APPEND ?
497474b62b8SAllan Jude "a" : "-");
498474b62b8SAllan Jude xo_emit("{d:/%s}", fst->fs_fflags & PS_FST_FFLAG_ASYNC ?
499474b62b8SAllan Jude "s" : "-");
500474b62b8SAllan Jude xo_emit("{d:/%s}", fst->fs_fflags & PS_FST_FFLAG_SYNC ?
501474b62b8SAllan Jude "f" : "-");
502474b62b8SAllan Jude xo_emit("{d:/%s}", fst->fs_fflags & PS_FST_FFLAG_NONBLOCK ?
503474b62b8SAllan Jude "n" : "-");
504474b62b8SAllan Jude xo_emit("{d:/%s}", fst->fs_fflags & PS_FST_FFLAG_DIRECT ?
505474b62b8SAllan Jude "d" : "-");
506474b62b8SAllan Jude xo_emit("{d:/%s}", fst->fs_fflags & PS_FST_FFLAG_HASLOCK ?
507474b62b8SAllan Jude "l" : "-");
508474b62b8SAllan Jude xo_emit(" ");
509474b62b8SAllan Jude xo_open_list("fd_flags");
510474b62b8SAllan Jude if (fst->fs_fflags & PS_FST_FFLAG_READ)
511474b62b8SAllan Jude xo_emit("{elq:fd_flags/read}");
512474b62b8SAllan Jude if (fst->fs_fflags & PS_FST_FFLAG_WRITE)
513474b62b8SAllan Jude xo_emit("{elq:fd_flags/write}");
514474b62b8SAllan Jude if (fst->fs_fflags & PS_FST_FFLAG_APPEND)
515474b62b8SAllan Jude xo_emit("{elq:fd_flags/append}");
516474b62b8SAllan Jude if (fst->fs_fflags & PS_FST_FFLAG_ASYNC)
517474b62b8SAllan Jude xo_emit("{elq:fd_flags/async}");
518474b62b8SAllan Jude if (fst->fs_fflags & PS_FST_FFLAG_SYNC)
519474b62b8SAllan Jude xo_emit("{elq:fd_flags/fsync}");
520474b62b8SAllan Jude if (fst->fs_fflags & PS_FST_FFLAG_NONBLOCK)
521474b62b8SAllan Jude xo_emit("{elq:fd_flags/nonblocking}");
522474b62b8SAllan Jude if (fst->fs_fflags & PS_FST_FFLAG_DIRECT)
523474b62b8SAllan Jude xo_emit("{elq:fd_flags/direct_io}");
524474b62b8SAllan Jude if (fst->fs_fflags & PS_FST_FFLAG_HASLOCK)
525474b62b8SAllan Jude xo_emit("{elq:fd_flags/lock_held}");
526474b62b8SAllan Jude xo_close_list("fd_flags");
527474b62b8SAllan Jude
5282a243b95SBrooks Davis if ((procstat_opts & PS_OPT_CAPABILITIES) == 0) {
5290daf62d9SStanislav Sedov if (fst->fs_ref_count > -1)
530474b62b8SAllan Jude xo_emit("{:ref_count/%3d/%d} ",
531474b62b8SAllan Jude fst->fs_ref_count);
532f2805949SJoe Marcus Clarke else
533474b62b8SAllan Jude xo_emit("{q:ref_count/%3c/%c} ", '-');
5340daf62d9SStanislav Sedov if (fst->fs_offset > -1)
535474b62b8SAllan Jude xo_emit("{:offset/%7jd/%jd} ",
536474b62b8SAllan Jude (intmax_t)fst->fs_offset);
537f2805949SJoe Marcus Clarke else
538474b62b8SAllan Jude xo_emit("{q:offset/%7c/%c} ", '-');
539d57486e2SRobert Watson }
5402a243b95SBrooks Davis if ((procstat_opts & PS_OPT_CAPABILITIES) != 0) {
5417008be5bSPawel Jakub Dawidek print_capability(&fst->fs_cap_rights, capwidth);
542474b62b8SAllan Jude xo_emit(" ");
543d57486e2SRobert Watson }
5440daf62d9SStanislav Sedov switch (fst->fs_type) {
5450daf62d9SStanislav Sedov case PS_FST_TYPE_SOCKET:
546474b62b8SAllan Jude error = procstat_get_socket_info(procstat, fst, &sock,
547474b62b8SAllan Jude NULL);
5480daf62d9SStanislav Sedov if (error != 0)
5490daf62d9SStanislav Sedov break;
550474b62b8SAllan Jude xo_emit("{:protocol/%-3s/%s} ",
5510daf62d9SStanislav Sedov protocol_to_string(sock.dom_family,
5520daf62d9SStanislav Sedov sock.type, sock.proto));
55395b97895SConrad Meyer if (sock.proto == IPPROTO_TCP ||
55495b97895SConrad Meyer sock.proto == IPPROTO_SCTP ||
55595b97895SConrad Meyer sock.type == SOCK_STREAM) {
55695b97895SConrad Meyer xo_emit("{:sendq/%u} ", sock.sendq);
55795b97895SConrad Meyer xo_emit("{:recvq/%u} ", sock.recvq);
55895b97895SConrad Meyer }
5593d91be41SRobert Watson /*
5603d91be41SRobert Watson * While generally we like to print two addresses,
5613d91be41SRobert Watson * local and peer, for sockets, it turns out to be
5623d91be41SRobert Watson * more useful to print the first non-nul address for
5633d91be41SRobert Watson * local sockets, as typically they aren't bound and
5643d91be41SRobert Watson * connected, and the path strings can get long.
5653d91be41SRobert Watson */
5660daf62d9SStanislav Sedov if (sock.dom_family == AF_LOCAL) {
5673d91be41SRobert Watson struct sockaddr_un *sun =
5680daf62d9SStanislav Sedov (struct sockaddr_un *)&sock.sa_local;
5693d91be41SRobert Watson
5703d91be41SRobert Watson if (sun->sun_path[0] != 0)
571474b62b8SAllan Jude addr_to_string(&sock.sa_local,
572474b62b8SAllan Jude src_addr, sizeof(src_addr));
5733d91be41SRobert Watson else
574474b62b8SAllan Jude addr_to_string(&sock.sa_peer,
575474b62b8SAllan Jude src_addr, sizeof(src_addr));
576474b62b8SAllan Jude xo_emit("{:path/%s}", src_addr);
5773d91be41SRobert Watson } else {
578474b62b8SAllan Jude addr_to_string(&sock.sa_local, src_addr,
579474b62b8SAllan Jude sizeof(src_addr));
580474b62b8SAllan Jude addr_to_string(&sock.sa_peer, dst_addr,
581474b62b8SAllan Jude sizeof(dst_addr));
582474b62b8SAllan Jude xo_emit("{:path/%s %s}", src_addr, dst_addr);
5833d91be41SRobert Watson }
5843d91be41SRobert Watson break;
5853d91be41SRobert Watson
5863d91be41SRobert Watson default:
587474b62b8SAllan Jude xo_emit("{:protocol/%-3s/%s} ", "-");
588474b62b8SAllan Jude xo_emit("{:path/%-18s/%s}", fst->fs_path != NULL ?
589474b62b8SAllan Jude fst->fs_path : "-");
5903d91be41SRobert Watson }
5913d91be41SRobert Watson
592474b62b8SAllan Jude xo_emit("\n");
593474b62b8SAllan Jude xo_close_instance("files");
5943d91be41SRobert Watson }
595474b62b8SAllan Jude xo_close_list("files");
59639f6ca65SMikolaj Golub procstat_freefiles(procstat, head);
5973d91be41SRobert Watson }
598