xref: /illumos-gate/usr/src/cmd/ptools/pfiles/pfiles.c (revision 8950e535f42dd006f8cfb2122c94f6b7557757e0)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
52caf0dcdSrshoaib  * Common Development and Distribution License (the "License").
62caf0dcdSrshoaib  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
212caf0dcdSrshoaib 
227c478bd9Sstevel@tonic-gate /*
233e95bd4aSAnders Persson  * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
2434bdffbfSGarrett D'Amore  * Copyright 2012 DEY Storage Systems, Inc.  All rights reserved.
257c478bd9Sstevel@tonic-gate  */
26dfc0fed8SRobert Mustacchi /*
27f8cbe0e7SDan McDonald  * Copyright (c) 2017 Joyent, Inc.  All Rights reserved.
28a02120c4SAndy Fiddaman  * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
29dfc0fed8SRobert Mustacchi  */
307c478bd9Sstevel@tonic-gate 
317c478bd9Sstevel@tonic-gate #include <stdio.h>
327c478bd9Sstevel@tonic-gate #include <stdlib.h>
337c478bd9Sstevel@tonic-gate #include <unistd.h>
347c478bd9Sstevel@tonic-gate #include <fcntl.h>
357c478bd9Sstevel@tonic-gate #include <ctype.h>
367c478bd9Sstevel@tonic-gate #include <string.h>
377c478bd9Sstevel@tonic-gate #include <signal.h>
387c478bd9Sstevel@tonic-gate #include <dirent.h>
397c478bd9Sstevel@tonic-gate #include <limits.h>
407c478bd9Sstevel@tonic-gate #include <door.h>
417c478bd9Sstevel@tonic-gate #include <sys/types.h>
4243d18f1cSpriyanka #include <sys/socket.h>
437c478bd9Sstevel@tonic-gate #include <sys/stat.h>
447c478bd9Sstevel@tonic-gate #include <sys/mkdev.h>
45ca9327a6Smeem #include <sys/stropts.h>
46ca9327a6Smeem #include <sys/timod.h>
477c478bd9Sstevel@tonic-gate #include <sys/un.h>
487c478bd9Sstevel@tonic-gate #include <libproc.h>
4943d18f1cSpriyanka #include <netinet/in.h>
50437220cdSdanmcd #include <netinet/udp.h>
517c478bd9Sstevel@tonic-gate #include <arpa/inet.h>
52a154f012SAlexander Stetsenko #include <ucred.h>
53a154f012SAlexander Stetsenko #include <zone.h>
547c478bd9Sstevel@tonic-gate 
557c478bd9Sstevel@tonic-gate static char *command;
567c478bd9Sstevel@tonic-gate static volatile int interrupt;
577c478bd9Sstevel@tonic-gate static int Fflag;
587c478bd9Sstevel@tonic-gate static boolean_t nflag = B_FALSE;
597c478bd9Sstevel@tonic-gate 
607c478bd9Sstevel@tonic-gate static	void	intr(int);
61a02120c4SAndy Fiddaman static	void	dofcntl(struct ps_prochandle *, const prfdinfo_t *, int, int);
62a02120c4SAndy Fiddaman static	void	dosocket(struct ps_prochandle *, const prfdinfo_t *);
63a02120c4SAndy Fiddaman static	void	dosocknames(struct ps_prochandle *, const prfdinfo_t *);
64a02120c4SAndy Fiddaman static	void	dofifo(struct ps_prochandle *, const prfdinfo_t *);
657c478bd9Sstevel@tonic-gate static	void	show_files(struct ps_prochandle *);
667c478bd9Sstevel@tonic-gate static	void	show_fileflags(int);
67a02120c4SAndy Fiddaman static	void	show_door(struct ps_prochandle *, const prfdinfo_t *);
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate int
main(int argc,char ** argv)707c478bd9Sstevel@tonic-gate main(int argc, char **argv)
717c478bd9Sstevel@tonic-gate {
727c478bd9Sstevel@tonic-gate 	int retc = 0;
737c478bd9Sstevel@tonic-gate 	int opt;
747c478bd9Sstevel@tonic-gate 	int errflg = 0;
757c478bd9Sstevel@tonic-gate 	struct ps_prochandle *Pr;
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate 	if ((command = strrchr(argv[0], '/')) != NULL)
787c478bd9Sstevel@tonic-gate 		command++;
797c478bd9Sstevel@tonic-gate 	else
807c478bd9Sstevel@tonic-gate 		command = argv[0];
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate 	/* options */
837c478bd9Sstevel@tonic-gate 	while ((opt = getopt(argc, argv, "Fn")) != EOF) {
847c478bd9Sstevel@tonic-gate 		switch (opt) {
857c478bd9Sstevel@tonic-gate 		case 'F':		/* force grabbing (no O_EXCL) */
867c478bd9Sstevel@tonic-gate 			Fflag = PGRAB_FORCE;
877c478bd9Sstevel@tonic-gate 			break;
887c478bd9Sstevel@tonic-gate 		case 'n':
897c478bd9Sstevel@tonic-gate 			nflag = B_TRUE;
907c478bd9Sstevel@tonic-gate 			break;
917c478bd9Sstevel@tonic-gate 		default:
927c478bd9Sstevel@tonic-gate 			errflg = 1;
937c478bd9Sstevel@tonic-gate 			break;
947c478bd9Sstevel@tonic-gate 		}
957c478bd9Sstevel@tonic-gate 	}
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate 	argc -= optind;
987c478bd9Sstevel@tonic-gate 	argv += optind;
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate 	if (errflg || argc <= 0) {
10134bdffbfSGarrett D'Amore 		(void) fprintf(stderr, "usage:\t%s [-F] { pid | core } ...\n",
1027c478bd9Sstevel@tonic-gate 		    command);
1037c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
1047c478bd9Sstevel@tonic-gate 		    "  (report open files of each process)\n");
1057c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
1067c478bd9Sstevel@tonic-gate 		    "  -F: force grabbing of the target process\n");
1077c478bd9Sstevel@tonic-gate 		exit(2);
1087c478bd9Sstevel@tonic-gate 	}
1097c478bd9Sstevel@tonic-gate 
1107c478bd9Sstevel@tonic-gate 	/* catch signals from terminal */
1117c478bd9Sstevel@tonic-gate 	if (sigset(SIGHUP, SIG_IGN) == SIG_DFL)
1127c478bd9Sstevel@tonic-gate 		(void) sigset(SIGHUP, intr);
1137c478bd9Sstevel@tonic-gate 	if (sigset(SIGINT, SIG_IGN) == SIG_DFL)
1147c478bd9Sstevel@tonic-gate 		(void) sigset(SIGINT, intr);
1157c478bd9Sstevel@tonic-gate 	if (sigset(SIGQUIT, SIG_IGN) == SIG_DFL)
1167c478bd9Sstevel@tonic-gate 		(void) sigset(SIGQUIT, intr);
1177c478bd9Sstevel@tonic-gate 	(void) sigset(SIGPIPE, intr);
1187c478bd9Sstevel@tonic-gate 	(void) sigset(SIGTERM, intr);
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate 	(void) proc_initstdio();
1217c478bd9Sstevel@tonic-gate 
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate 	while (--argc >= 0 && !interrupt) {
1247c478bd9Sstevel@tonic-gate 		char *arg;
1257c478bd9Sstevel@tonic-gate 		psinfo_t psinfo;
1267c478bd9Sstevel@tonic-gate 		pid_t pid;
1277c478bd9Sstevel@tonic-gate 		int gret;
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate 		(void) proc_flushstdio();
1307c478bd9Sstevel@tonic-gate 
13134bdffbfSGarrett D'Amore 		arg = *argv++;
13234bdffbfSGarrett D'Amore 
1337c478bd9Sstevel@tonic-gate 		/* get the specified pid and the psinfo struct */
13434bdffbfSGarrett D'Amore 		if ((pid = proc_arg_psinfo(arg, PR_ARG_PIDS,
1357c478bd9Sstevel@tonic-gate 		    &psinfo, &gret)) == -1) {
13634bdffbfSGarrett D'Amore 
13734bdffbfSGarrett D'Amore 			if ((Pr = proc_arg_xgrab(arg, NULL, PR_ARG_CORES,
13834bdffbfSGarrett D'Amore 			    Fflag, &gret, NULL)) == NULL) {
13934bdffbfSGarrett D'Amore 				(void) fprintf(stderr,
14034bdffbfSGarrett D'Amore 				    "%s: cannot examine %s: %s\n",
1417c478bd9Sstevel@tonic-gate 				    command, arg, Pgrab_error(gret));
1427c478bd9Sstevel@tonic-gate 				retc++;
14334bdffbfSGarrett D'Amore 				continue;
14434bdffbfSGarrett D'Amore 			}
14534bdffbfSGarrett D'Amore 			if (proc_arg_psinfo(arg, PR_ARG_ANY, &psinfo,
14634bdffbfSGarrett D'Amore 			    &gret) < 0) {
14734bdffbfSGarrett D'Amore 				(void) fprintf(stderr,
14834bdffbfSGarrett D'Amore 				    "%s: cannot examine %s: %s\n",
14934bdffbfSGarrett D'Amore 				    command, arg, Pgrab_error(gret));
15034bdffbfSGarrett D'Amore 				retc++;
15134bdffbfSGarrett D'Amore 				Prelease(Pr, 0);
15234bdffbfSGarrett D'Amore 				continue;
15334bdffbfSGarrett D'Amore 			}
15434bdffbfSGarrett D'Amore 			(void) printf("core '%s' of %d:\t%.70s\n",
15534bdffbfSGarrett D'Amore 			    arg, (int)psinfo.pr_pid, psinfo.pr_psargs);
15634bdffbfSGarrett D'Amore 
15734bdffbfSGarrett D'Amore 			show_files(Pr);
15834bdffbfSGarrett D'Amore 			Prelease(Pr, 0);
15934bdffbfSGarrett D'Amore 
1607c478bd9Sstevel@tonic-gate 		} else if ((Pr = Pgrab(pid, Fflag, &gret)) != NULL) {
1617c478bd9Sstevel@tonic-gate 			if (Pcreate_agent(Pr) == 0) {
1627c478bd9Sstevel@tonic-gate 				proc_unctrl_psinfo(&psinfo);
1637c478bd9Sstevel@tonic-gate 				(void) printf("%d:\t%.70s\n",
1647c478bd9Sstevel@tonic-gate 				    (int)pid, psinfo.pr_psargs);
1657c478bd9Sstevel@tonic-gate 				show_files(Pr);
1667c478bd9Sstevel@tonic-gate 				Pdestroy_agent(Pr);
1677c478bd9Sstevel@tonic-gate 			} else {
1687c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr,
1697c478bd9Sstevel@tonic-gate 				    "%s: cannot control process %d\n",
1707c478bd9Sstevel@tonic-gate 				    command, (int)pid);
1717c478bd9Sstevel@tonic-gate 				retc++;
1727c478bd9Sstevel@tonic-gate 			}
1737c478bd9Sstevel@tonic-gate 			Prelease(Pr, 0);
1747c478bd9Sstevel@tonic-gate 			Pr = NULL;
1757c478bd9Sstevel@tonic-gate 		} else {
1767c478bd9Sstevel@tonic-gate 			switch (gret) {
1777c478bd9Sstevel@tonic-gate 			case G_SYS:
1787c478bd9Sstevel@tonic-gate 				proc_unctrl_psinfo(&psinfo);
1797c478bd9Sstevel@tonic-gate 				(void) printf("%d:\t%.70s\n", (int)pid,
1807c478bd9Sstevel@tonic-gate 				    psinfo.pr_psargs);
1817c478bd9Sstevel@tonic-gate 				(void) printf("  [system process]\n");
1827c478bd9Sstevel@tonic-gate 				break;
1837c478bd9Sstevel@tonic-gate 			default:
1847c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr, "%s: %s: %d\n",
1857c478bd9Sstevel@tonic-gate 				    command, Pgrab_error(gret), (int)pid);
1867c478bd9Sstevel@tonic-gate 				retc++;
1877c478bd9Sstevel@tonic-gate 				break;
1887c478bd9Sstevel@tonic-gate 			}
1897c478bd9Sstevel@tonic-gate 		}
1907c478bd9Sstevel@tonic-gate 	}
1917c478bd9Sstevel@tonic-gate 
1927c478bd9Sstevel@tonic-gate 	(void) proc_finistdio();
1937c478bd9Sstevel@tonic-gate 
1947c478bd9Sstevel@tonic-gate 	if (interrupt && retc == 0)
1957c478bd9Sstevel@tonic-gate 		retc++;
1967c478bd9Sstevel@tonic-gate 	return (retc);
1977c478bd9Sstevel@tonic-gate }
1987c478bd9Sstevel@tonic-gate 
1997c478bd9Sstevel@tonic-gate /* ARGSUSED */
2007c478bd9Sstevel@tonic-gate static void
intr(int sig)2017c478bd9Sstevel@tonic-gate intr(int sig)
2027c478bd9Sstevel@tonic-gate {
2037c478bd9Sstevel@tonic-gate 	interrupt = 1;
2047c478bd9Sstevel@tonic-gate }
2057c478bd9Sstevel@tonic-gate 
2067c478bd9Sstevel@tonic-gate /* ------ begin specific code ------ */
2077c478bd9Sstevel@tonic-gate 
208*8950e535SAndy Fiddaman static int
show_paths(uint_t type,const void * data,size_t len,void * arg __unused)209*8950e535SAndy Fiddaman show_paths(uint_t type, const void *data, size_t len, void *arg __unused)
210*8950e535SAndy Fiddaman {
211*8950e535SAndy Fiddaman 	if (type == PR_PATHNAME)
212*8950e535SAndy Fiddaman 		(void) printf("      %.*s\n", len, data);
213*8950e535SAndy Fiddaman 	return (0);
214*8950e535SAndy Fiddaman }
215a02120c4SAndy Fiddaman 
21634bdffbfSGarrett D'Amore static int
show_file(void * data,const prfdinfo_t * info)217a02120c4SAndy Fiddaman show_file(void *data, const prfdinfo_t *info)
21834bdffbfSGarrett D'Amore {
21934bdffbfSGarrett D'Amore 	struct ps_prochandle *Pr = data;
22034bdffbfSGarrett D'Amore 	char unknown[12];
22134bdffbfSGarrett D'Amore 	char *s;
22234bdffbfSGarrett D'Amore 	mode_t mode;
22334bdffbfSGarrett D'Amore 
22434bdffbfSGarrett D'Amore 	if (interrupt)
22534bdffbfSGarrett D'Amore 		return (1);
22634bdffbfSGarrett D'Amore 
22734bdffbfSGarrett D'Amore 	mode = info->pr_mode;
22834bdffbfSGarrett D'Amore 
22934bdffbfSGarrett D'Amore 	switch (mode & S_IFMT) {
23034bdffbfSGarrett D'Amore 	case S_IFCHR: s = "S_IFCHR"; break;
23134bdffbfSGarrett D'Amore 	case S_IFBLK: s = "S_IFBLK"; break;
23234bdffbfSGarrett D'Amore 	case S_IFIFO: s = "S_IFIFO"; break;
23334bdffbfSGarrett D'Amore 	case S_IFDIR: s = "S_IFDIR"; break;
23434bdffbfSGarrett D'Amore 	case S_IFREG: s = "S_IFREG"; break;
23534bdffbfSGarrett D'Amore 	case S_IFLNK: s = "S_IFLNK"; break;
23634bdffbfSGarrett D'Amore 	case S_IFSOCK: s = "S_IFSOCK"; break;
23734bdffbfSGarrett D'Amore 	case S_IFDOOR: s = "S_IFDOOR"; break;
23834bdffbfSGarrett D'Amore 	case S_IFPORT: s = "S_IFPORT"; break;
23934bdffbfSGarrett D'Amore 	default:
24034bdffbfSGarrett D'Amore 		s = unknown;
24134bdffbfSGarrett D'Amore 		(void) sprintf(s, "0x%.4x ", (int)mode & S_IFMT);
24234bdffbfSGarrett D'Amore 		break;
24334bdffbfSGarrett D'Amore 	}
24434bdffbfSGarrett D'Amore 
24534bdffbfSGarrett D'Amore 	(void) printf("%4d: %s mode:0%.3o", info->pr_fd, s,
24634bdffbfSGarrett D'Amore 	    (int)mode & ~S_IFMT);
24734bdffbfSGarrett D'Amore 
24834bdffbfSGarrett D'Amore 	(void) printf(" dev:%u,%u",
24934bdffbfSGarrett D'Amore 	    (unsigned)info->pr_major, (unsigned)info->pr_minor);
25034bdffbfSGarrett D'Amore 
25134bdffbfSGarrett D'Amore 	if ((mode & S_IFMT) == S_IFPORT) {
25234bdffbfSGarrett D'Amore 		(void) printf(" uid:%d gid:%d",
25334bdffbfSGarrett D'Amore 		    (int)info->pr_uid, (int)info->pr_gid);
25434bdffbfSGarrett D'Amore 		(void) printf(" size:%lld\n", (longlong_t)info->pr_size);
25534bdffbfSGarrett D'Amore 		return (0);
25634bdffbfSGarrett D'Amore 	}
25734bdffbfSGarrett D'Amore 
25834bdffbfSGarrett D'Amore 	(void) printf(" ino:%llu uid:%d gid:%d",
25934bdffbfSGarrett D'Amore 	    (u_longlong_t)info->pr_ino, (int)info->pr_uid, (int)info->pr_gid);
26034bdffbfSGarrett D'Amore 
26134bdffbfSGarrett D'Amore 	if ((info->pr_rmajor == (major_t)NODEV) &&
26234bdffbfSGarrett D'Amore 	    (info->pr_rminor == (minor_t)NODEV))
26334bdffbfSGarrett D'Amore 		(void) printf(" size:%lld\n", (longlong_t)info->pr_size);
26434bdffbfSGarrett D'Amore 	else
26534bdffbfSGarrett D'Amore 		(void) printf(" rdev:%u,%u\n",
26634bdffbfSGarrett D'Amore 		    (unsigned)info->pr_rmajor, (unsigned)info->pr_rminor);
26734bdffbfSGarrett D'Amore 
26834bdffbfSGarrett D'Amore 	if (!nflag) {
26934bdffbfSGarrett D'Amore 		dofcntl(Pr, info,
27034bdffbfSGarrett D'Amore 		    (mode & (S_IFMT|S_ENFMT|S_IXGRP)) == (S_IFREG|S_ENFMT),
27134bdffbfSGarrett D'Amore 		    (mode & S_IFMT) == S_IFDOOR);
27234bdffbfSGarrett D'Amore 
27334bdffbfSGarrett D'Amore 		if (Pstate(Pr) != PS_DEAD) {
274a02120c4SAndy Fiddaman 			switch (mode & S_IFMT) {
275a02120c4SAndy Fiddaman 			case S_IFSOCK:
276a02120c4SAndy Fiddaman 				dosocket(Pr, info);
277a02120c4SAndy Fiddaman 				break;
278a02120c4SAndy Fiddaman 			case S_IFIFO:
279a02120c4SAndy Fiddaman 				dofifo(Pr, info);
280a02120c4SAndy Fiddaman 				break;
281a02120c4SAndy Fiddaman 			case S_IFCHR:
28234bdffbfSGarrett D'Amore 				/*
283a02120c4SAndy Fiddaman 				 * This may be a TLI endpoint. If so, it will
284a02120c4SAndy Fiddaman 				 * have socket names in the fdinfo and this
285a02120c4SAndy Fiddaman 				 * will print them.
28634bdffbfSGarrett D'Amore 				 */
287a02120c4SAndy Fiddaman 				dosocknames(Pr, info);
28834bdffbfSGarrett D'Amore 				break;
28934bdffbfSGarrett D'Amore 			}
29034bdffbfSGarrett D'Amore 		}
29134bdffbfSGarrett D'Amore 
292*8950e535SAndy Fiddaman 		(void) proc_fdinfowalk(info, show_paths, NULL);
29334bdffbfSGarrett D'Amore 
29434bdffbfSGarrett D'Amore 		if (info->pr_offset != -1) {
29534bdffbfSGarrett D'Amore 			(void) printf("      offset:%lld\n",
29634bdffbfSGarrett D'Amore 			    (long long)info->pr_offset);
29734bdffbfSGarrett D'Amore 		}
29834bdffbfSGarrett D'Amore 	}
299a02120c4SAndy Fiddaman 
30034bdffbfSGarrett D'Amore 	return (0);
30134bdffbfSGarrett D'Amore }
30234bdffbfSGarrett D'Amore 
3037c478bd9Sstevel@tonic-gate static void
show_files(struct ps_prochandle * Pr)3047c478bd9Sstevel@tonic-gate show_files(struct ps_prochandle *Pr)
3057c478bd9Sstevel@tonic-gate {
3067c478bd9Sstevel@tonic-gate 	struct rlimit rlim;
3077c478bd9Sstevel@tonic-gate 
3087c478bd9Sstevel@tonic-gate 	if (pr_getrlimit(Pr, RLIMIT_NOFILE, &rlim) == 0) {
3097c478bd9Sstevel@tonic-gate 		ulong_t nfd = rlim.rlim_cur;
3107c478bd9Sstevel@tonic-gate 		if (nfd == RLIM_INFINITY)
3117c478bd9Sstevel@tonic-gate 			(void) printf(
3127c478bd9Sstevel@tonic-gate 			    "  Current rlimit: unlimited file descriptors\n");
3137c478bd9Sstevel@tonic-gate 		else
3147c478bd9Sstevel@tonic-gate 			(void) printf(
3157c478bd9Sstevel@tonic-gate 			    "  Current rlimit: %lu file descriptors\n", nfd);
3167c478bd9Sstevel@tonic-gate 	}
3177c478bd9Sstevel@tonic-gate 
31834bdffbfSGarrett D'Amore 	(void) Pfdinfo_iter(Pr, show_file, Pr);
3197c478bd9Sstevel@tonic-gate }
3207c478bd9Sstevel@tonic-gate 
3217c478bd9Sstevel@tonic-gate /* examine open file with fcntl() */
3227c478bd9Sstevel@tonic-gate static void
dofcntl(struct ps_prochandle * Pr,const prfdinfo_t * info,int mandatory,int isdoor)323a02120c4SAndy Fiddaman dofcntl(struct ps_prochandle *Pr, const prfdinfo_t *info, int mandatory,
324a02120c4SAndy Fiddaman     int isdoor)
3257c478bd9Sstevel@tonic-gate {
3267c478bd9Sstevel@tonic-gate 	int fileflags;
3277c478bd9Sstevel@tonic-gate 	int fdflags;
32834bdffbfSGarrett D'Amore 
32934bdffbfSGarrett D'Amore 	fileflags = info->pr_fileflags;
33034bdffbfSGarrett D'Amore 	fdflags = info->pr_fdflags;
3317c478bd9Sstevel@tonic-gate 
3327c478bd9Sstevel@tonic-gate 	if (fileflags != -1 || fdflags != -1) {
3337c478bd9Sstevel@tonic-gate 		(void) printf("      ");
3347c478bd9Sstevel@tonic-gate 		if (fileflags != -1)
3357c478bd9Sstevel@tonic-gate 			show_fileflags(fileflags);
3367c478bd9Sstevel@tonic-gate 		if (fdflags != -1 && (fdflags & FD_CLOEXEC))
3377c478bd9Sstevel@tonic-gate 			(void) printf(" FD_CLOEXEC");
33834bdffbfSGarrett D'Amore 		if (isdoor && (Pstate(Pr) != PS_DEAD))
339a02120c4SAndy Fiddaman 			show_door(Pr, info);
3407c478bd9Sstevel@tonic-gate 		(void) fputc('\n', stdout);
34134bdffbfSGarrett D'Amore 	} else if (isdoor && (Pstate(Pr) != PS_DEAD)) {
3427c478bd9Sstevel@tonic-gate 		(void) printf("    ");
343a02120c4SAndy Fiddaman 		show_door(Pr, info);
3447c478bd9Sstevel@tonic-gate 		(void) fputc('\n', stdout);
3457c478bd9Sstevel@tonic-gate 	}
3467c478bd9Sstevel@tonic-gate 
347a02120c4SAndy Fiddaman 	if (Pstate(Pr) != PS_DEAD) {
348a02120c4SAndy Fiddaman 		if (info->pr_locktype != F_UNLCK &&
349a02120c4SAndy Fiddaman 		    (info->pr_locksysid != -1 || info->pr_lockpid != -1)) {
350a02120c4SAndy Fiddaman 			unsigned long sysid = info->pr_locksysid;
3517c478bd9Sstevel@tonic-gate 
352a02120c4SAndy Fiddaman 			(void) printf("      %s %s lock set",
353437220cdSdanmcd 			    mandatory ? "mandatory" : "advisory",
354a02120c4SAndy Fiddaman 			    info->pr_locktype == F_RDLCK? "read" : "write");
3557c478bd9Sstevel@tonic-gate 			if (sysid)
356a02120c4SAndy Fiddaman 				(void) printf(" by system 0x%lX", sysid);
357a02120c4SAndy Fiddaman 			if (info->pr_lockpid != -1)
358a02120c4SAndy Fiddaman 				(void) printf(" by process %d",
359a02120c4SAndy Fiddaman 				    (int)info->pr_lockpid);
3607c478bd9Sstevel@tonic-gate 			(void) fputc('\n', stdout);
3617c478bd9Sstevel@tonic-gate 		}
3627c478bd9Sstevel@tonic-gate 	}
3637c478bd9Sstevel@tonic-gate }
3647c478bd9Sstevel@tonic-gate 
3657c478bd9Sstevel@tonic-gate #define	ALL_O_FLAGS	O_ACCMODE | O_NDELAY | O_NONBLOCK | O_APPEND | \
3667c478bd9Sstevel@tonic-gate 			O_SYNC | O_DSYNC | O_RSYNC | O_XATTR | \
3677c478bd9Sstevel@tonic-gate 			O_CREAT | O_TRUNC | O_EXCL | O_NOCTTY | O_LARGEFILE
3687c478bd9Sstevel@tonic-gate 
3697c478bd9Sstevel@tonic-gate static void
show_fileflags(int flags)3707c478bd9Sstevel@tonic-gate show_fileflags(int flags)
3717c478bd9Sstevel@tonic-gate {
3727c478bd9Sstevel@tonic-gate 	char buffer[136];
3737c478bd9Sstevel@tonic-gate 	char *str = buffer;
3747c478bd9Sstevel@tonic-gate 
3757c478bd9Sstevel@tonic-gate 	switch (flags & O_ACCMODE) {
3767c478bd9Sstevel@tonic-gate 	case O_RDONLY:
3777c478bd9Sstevel@tonic-gate 		(void) strcpy(str, "O_RDONLY");
3787c478bd9Sstevel@tonic-gate 		break;
3797c478bd9Sstevel@tonic-gate 	case O_WRONLY:
3807c478bd9Sstevel@tonic-gate 		(void) strcpy(str, "O_WRONLY");
3817c478bd9Sstevel@tonic-gate 		break;
3827c478bd9Sstevel@tonic-gate 	case O_RDWR:
3837c478bd9Sstevel@tonic-gate 		(void) strcpy(str, "O_RDWR");
3847c478bd9Sstevel@tonic-gate 		break;
385794f0adbSRoger A. Faulkner 	case O_SEARCH:
386794f0adbSRoger A. Faulkner 		(void) strcpy(str, "O_SEARCH");
387794f0adbSRoger A. Faulkner 		break;
388794f0adbSRoger A. Faulkner 	case O_EXEC:
389794f0adbSRoger A. Faulkner 		(void) strcpy(str, "O_EXEC");
390794f0adbSRoger A. Faulkner 		break;
3917c478bd9Sstevel@tonic-gate 	default:
3927c478bd9Sstevel@tonic-gate 		(void) sprintf(str, "0x%x", flags & O_ACCMODE);
3937c478bd9Sstevel@tonic-gate 		break;
3947c478bd9Sstevel@tonic-gate 	}
3957c478bd9Sstevel@tonic-gate 
3967c478bd9Sstevel@tonic-gate 	if (flags & O_NDELAY)
3977c478bd9Sstevel@tonic-gate 		(void) strcat(str, "|O_NDELAY");
3987c478bd9Sstevel@tonic-gate 	if (flags & O_NONBLOCK)
3997c478bd9Sstevel@tonic-gate 		(void) strcat(str, "|O_NONBLOCK");
4007c478bd9Sstevel@tonic-gate 	if (flags & O_APPEND)
4017c478bd9Sstevel@tonic-gate 		(void) strcat(str, "|O_APPEND");
4027c478bd9Sstevel@tonic-gate 	if (flags & O_SYNC)
4037c478bd9Sstevel@tonic-gate 		(void) strcat(str, "|O_SYNC");
4047c478bd9Sstevel@tonic-gate 	if (flags & O_DSYNC)
4057c478bd9Sstevel@tonic-gate 		(void) strcat(str, "|O_DSYNC");
4067c478bd9Sstevel@tonic-gate 	if (flags & O_RSYNC)
4077c478bd9Sstevel@tonic-gate 		(void) strcat(str, "|O_RSYNC");
4087c478bd9Sstevel@tonic-gate 	if (flags & O_CREAT)
4097c478bd9Sstevel@tonic-gate 		(void) strcat(str, "|O_CREAT");
4107c478bd9Sstevel@tonic-gate 	if (flags & O_TRUNC)
4117c478bd9Sstevel@tonic-gate 		(void) strcat(str, "|O_TRUNC");
4127c478bd9Sstevel@tonic-gate 	if (flags & O_EXCL)
4137c478bd9Sstevel@tonic-gate 		(void) strcat(str, "|O_EXCL");
4147c478bd9Sstevel@tonic-gate 	if (flags & O_NOCTTY)
4157c478bd9Sstevel@tonic-gate 		(void) strcat(str, "|O_NOCTTY");
4167c478bd9Sstevel@tonic-gate 	if (flags & O_LARGEFILE)
4177c478bd9Sstevel@tonic-gate 		(void) strcat(str, "|O_LARGEFILE");
4187c478bd9Sstevel@tonic-gate 	if (flags & O_XATTR)
4197c478bd9Sstevel@tonic-gate 		(void) strcat(str, "|O_XATTR");
4207c478bd9Sstevel@tonic-gate 	if (flags & ~(ALL_O_FLAGS))
4217c478bd9Sstevel@tonic-gate 		(void) sprintf(str + strlen(str), "|0x%x",
4227c478bd9Sstevel@tonic-gate 		    flags & ~(ALL_O_FLAGS));
4237c478bd9Sstevel@tonic-gate 
4247c478bd9Sstevel@tonic-gate 	(void) printf("%s", str);
4257c478bd9Sstevel@tonic-gate }
4267c478bd9Sstevel@tonic-gate 
427a154f012SAlexander Stetsenko /* show process on the other end of a door, socket or fifo */
428a154f012SAlexander Stetsenko static void
show_peer_process(pid_t ppid)429a154f012SAlexander Stetsenko show_peer_process(pid_t ppid)
430a154f012SAlexander Stetsenko {
431a154f012SAlexander Stetsenko 	psinfo_t psinfo;
432a154f012SAlexander Stetsenko 
433a154f012SAlexander Stetsenko 	if (proc_get_psinfo(ppid, &psinfo) == 0)
434a154f012SAlexander Stetsenko 		(void) printf(" %s[%d]", psinfo.pr_fname, (int)ppid);
435a154f012SAlexander Stetsenko 	else
436a154f012SAlexander Stetsenko 		(void) printf(" pid %d", (int)ppid);
437a154f012SAlexander Stetsenko }
438a154f012SAlexander Stetsenko 
4397c478bd9Sstevel@tonic-gate /* show door info */
4407c478bd9Sstevel@tonic-gate static void
show_door(struct ps_prochandle * Pr,const prfdinfo_t * info)441a02120c4SAndy Fiddaman show_door(struct ps_prochandle *Pr, const prfdinfo_t *info)
4427c478bd9Sstevel@tonic-gate {
4437c478bd9Sstevel@tonic-gate 	door_info_t door_info;
4447c478bd9Sstevel@tonic-gate 
445a02120c4SAndy Fiddaman 	if (pr_door_info(Pr, info->pr_fd, &door_info) != 0)
4467c478bd9Sstevel@tonic-gate 		return;
4477c478bd9Sstevel@tonic-gate 
4487c478bd9Sstevel@tonic-gate 	(void) printf("  door to");
449a154f012SAlexander Stetsenko 	show_peer_process(door_info.di_target);
4507c478bd9Sstevel@tonic-gate }
4517c478bd9Sstevel@tonic-gate 
452ca9327a6Smeem /*
453ca9327a6Smeem  * Print out the socket address pointed to by `sa'.  `len' is only
454ca9327a6Smeem  * needed for AF_UNIX sockets.
455ca9327a6Smeem  */
4567c478bd9Sstevel@tonic-gate static void
show_sockaddr(const char * str,const struct sockaddr * sa,socklen_t len)457a02120c4SAndy Fiddaman show_sockaddr(const char *str, const struct sockaddr *sa, socklen_t len)
4587c478bd9Sstevel@tonic-gate {
459ca9327a6Smeem 	struct sockaddr_in *so_in = (struct sockaddr_in *)(void *)sa;
460ca9327a6Smeem 	struct sockaddr_in6 *so_in6 = (struct sockaddr_in6 *)(void *)sa;
4617c478bd9Sstevel@tonic-gate 	struct sockaddr_un *so_un = (struct sockaddr_un *)sa;
4627c478bd9Sstevel@tonic-gate 	char  abuf[INET6_ADDRSTRLEN];
4637c478bd9Sstevel@tonic-gate 	const char *p;
4647c478bd9Sstevel@tonic-gate 
465dfc0fed8SRobert Mustacchi 	if (len == 0)
466dfc0fed8SRobert Mustacchi 		return;
467dfc0fed8SRobert Mustacchi 
4687c478bd9Sstevel@tonic-gate 	switch (sa->sa_family) {
4697c478bd9Sstevel@tonic-gate 	default:
4707c478bd9Sstevel@tonic-gate 		return;
4717c478bd9Sstevel@tonic-gate 	case AF_INET:
472ca9327a6Smeem 		(void) printf("\t%s: AF_INET %s  port: %u\n", str,
4737c478bd9Sstevel@tonic-gate 		    inet_ntop(AF_INET, &so_in->sin_addr, abuf, sizeof (abuf)),
4747c478bd9Sstevel@tonic-gate 		    ntohs(so_in->sin_port));
4757c478bd9Sstevel@tonic-gate 		return;
4767c478bd9Sstevel@tonic-gate 	case AF_INET6:
477ca9327a6Smeem 		(void) printf("\t%s: AF_INET6 %s  port: %u\n", str,
4787c478bd9Sstevel@tonic-gate 		    inet_ntop(AF_INET6, &so_in6->sin6_addr,
4797c478bd9Sstevel@tonic-gate 		    abuf, sizeof (abuf)),
4807c478bd9Sstevel@tonic-gate 		    ntohs(so_in->sin_port));
4817c478bd9Sstevel@tonic-gate 		return;
4827c478bd9Sstevel@tonic-gate 	case AF_UNIX:
4837c478bd9Sstevel@tonic-gate 		if (len >= sizeof (so_un->sun_family)) {
484a02120c4SAndy Fiddaman 			(void) printf("\t%s: AF_UNIX %.*s\n",
485a02120c4SAndy Fiddaman 			    str, len - sizeof (so_un->sun_family),
486a02120c4SAndy Fiddaman 			    so_un->sun_path);
4877c478bd9Sstevel@tonic-gate 		}
4887c478bd9Sstevel@tonic-gate 		return;
4897c478bd9Sstevel@tonic-gate 	case AF_IMPLINK:	p = "AF_IMPLINK";	break;
4907c478bd9Sstevel@tonic-gate 	case AF_PUP:		p = "AF_PUP";		break;
4917c478bd9Sstevel@tonic-gate 	case AF_CHAOS:		p = "AF_CHAOS";		break;
4927c478bd9Sstevel@tonic-gate 	case AF_NS:		p = "AF_NS";		break;
4937c478bd9Sstevel@tonic-gate 	case AF_NBS:		p = "AF_NBS";		break;
4947c478bd9Sstevel@tonic-gate 	case AF_ECMA:		p = "AF_ECMA";		break;
4957c478bd9Sstevel@tonic-gate 	case AF_DATAKIT:	p = "AF_DATAKIT";	break;
4967c478bd9Sstevel@tonic-gate 	case AF_CCITT:		p = "AF_CCITT";		break;
4977c478bd9Sstevel@tonic-gate 	case AF_SNA:		p = "AF_SNA";		break;
4987c478bd9Sstevel@tonic-gate 	case AF_DECnet:		p = "AF_DECnet";	break;
4997c478bd9Sstevel@tonic-gate 	case AF_DLI:		p = "AF_DLI";		break;
5007c478bd9Sstevel@tonic-gate 	case AF_LAT:		p = "AF_LAT";		break;
5017c478bd9Sstevel@tonic-gate 	case AF_HYLINK:		p = "AF_HYLINK";	break;
5027c478bd9Sstevel@tonic-gate 	case AF_APPLETALK:	p = "AF_APPLETALK";	break;
5037c478bd9Sstevel@tonic-gate 	case AF_NIT:		p = "AF_NIT";		break;
5047c478bd9Sstevel@tonic-gate 	case AF_802:		p = "AF_802";		break;
5057c478bd9Sstevel@tonic-gate 	case AF_OSI:		p = "AF_OSI";		break;
5067c478bd9Sstevel@tonic-gate 	case AF_X25:		p = "AF_X25";		break;
5077c478bd9Sstevel@tonic-gate 	case AF_OSINET:		p = "AF_OSINET";	break;
5087c478bd9Sstevel@tonic-gate 	case AF_GOSIP:		p = "AF_GOSIP";		break;
5097c478bd9Sstevel@tonic-gate 	case AF_IPX:		p = "AF_IPX";		break;
5107c478bd9Sstevel@tonic-gate 	case AF_ROUTE:		p = "AF_ROUTE";		break;
511f8cbe0e7SDan McDonald 	case AF_KEY:		p = "AF_KEY";		break;
512f8cbe0e7SDan McDonald 	case AF_POLICY:		p = "AF_POLICY";	break;
5137c478bd9Sstevel@tonic-gate 	case AF_LINK:		p = "AF_LINK";		break;
5147c478bd9Sstevel@tonic-gate 	}
5157c478bd9Sstevel@tonic-gate 
5167c478bd9Sstevel@tonic-gate 	(void) printf("\t%s: %s\n", str, p);
5177c478bd9Sstevel@tonic-gate }
5187c478bd9Sstevel@tonic-gate 
519a154f012SAlexander Stetsenko /*
520a154f012SAlexander Stetsenko  * Print out the process information for the other end of local sockets
521a154f012SAlexander Stetsenko  * and fifos
522a154f012SAlexander Stetsenko  */
523a154f012SAlexander Stetsenko static void
show_ucred(const char * str,ucred_t * cred)524a154f012SAlexander Stetsenko show_ucred(const char *str, ucred_t *cred)
525a154f012SAlexander Stetsenko {
526a154f012SAlexander Stetsenko 	pid_t upid = ucred_getpid(cred);
527a154f012SAlexander Stetsenko 	zoneid_t uzid = ucred_getzoneid(cred);
528a154f012SAlexander Stetsenko 	char zonename[ZONENAME_MAX];
529a154f012SAlexander Stetsenko 
530a154f012SAlexander Stetsenko 	if ((upid != -1) || (uzid != -1)) {
531a154f012SAlexander Stetsenko 		(void) printf("\t%s:", str);
532a154f012SAlexander Stetsenko 		if (upid != -1) {
533a154f012SAlexander Stetsenko 			show_peer_process(upid);
534a154f012SAlexander Stetsenko 		}
535a154f012SAlexander Stetsenko 		if (uzid != -1) {
536a154f012SAlexander Stetsenko 			if (getzonenamebyid(uzid, zonename, sizeof (zonename))
537a154f012SAlexander Stetsenko 			    != -1) {
538a154f012SAlexander Stetsenko 				(void) printf(" zone: %s[%d]", zonename,
539a154f012SAlexander Stetsenko 				    (int)uzid);
540a154f012SAlexander Stetsenko 			} else {
541a154f012SAlexander Stetsenko 				(void) printf(" zoneid: %d", (int)uzid);
542a154f012SAlexander Stetsenko 			}
543a154f012SAlexander Stetsenko 		}
544a154f012SAlexander Stetsenko 		(void) printf("\n");
545a154f012SAlexander Stetsenko 	}
546a154f012SAlexander Stetsenko }
547a154f012SAlexander Stetsenko 
5487c478bd9Sstevel@tonic-gate static void
show_socktype(uint_t type)5497c478bd9Sstevel@tonic-gate show_socktype(uint_t type)
5507c478bd9Sstevel@tonic-gate {
5517c478bd9Sstevel@tonic-gate 	static const char *types[] = {
5527c478bd9Sstevel@tonic-gate 		NULL, "DGRAM", "STREAM", NULL, "RAW", "RDM", "SEQPACKET"
5537c478bd9Sstevel@tonic-gate 	};
5547c478bd9Sstevel@tonic-gate 
5557c478bd9Sstevel@tonic-gate 	if (type < sizeof (types) / sizeof (*types) && types[type] != NULL)
5567c478bd9Sstevel@tonic-gate 		(void) printf("\tSOCK_%s\n", types[type]);
5577c478bd9Sstevel@tonic-gate 	else
5587c478bd9Sstevel@tonic-gate 		(void) printf("\tunknown socket type %u\n", type);
5597c478bd9Sstevel@tonic-gate }
5607c478bd9Sstevel@tonic-gate 
56143d18f1cSpriyanka #define	BUFSIZE	200
5627c478bd9Sstevel@tonic-gate static void
show_sockopts(struct ps_prochandle * Pr,const prfdinfo_t * info)563a02120c4SAndy Fiddaman show_sockopts(struct ps_prochandle *Pr, const prfdinfo_t *info)
5647c478bd9Sstevel@tonic-gate {
565a02120c4SAndy Fiddaman 	const int *val;
566a02120c4SAndy Fiddaman 	size_t vlen;
56743d18f1cSpriyanka 	char buf[BUFSIZE];
5687c478bd9Sstevel@tonic-gate 	char buf1[32];
56943d18f1cSpriyanka 	char ipaddr[INET_ADDRSTRLEN];
5707c478bd9Sstevel@tonic-gate 	int i;
571a02120c4SAndy Fiddaman 	const in_addr_t *nexthop_val;
572a02120c4SAndy Fiddaman 	const prsockopts_bool_opts_t *opts;
5737c478bd9Sstevel@tonic-gate 	struct boolopt {
5747c478bd9Sstevel@tonic-gate 		int		opt;
5757c478bd9Sstevel@tonic-gate 		const char	*name;
5767c478bd9Sstevel@tonic-gate 	};
5777c478bd9Sstevel@tonic-gate 	static struct boolopt boolopts[] = {
578a02120c4SAndy Fiddaman 	    { PR_SO_DEBUG,		"SO_DEBUG,"	},
579a02120c4SAndy Fiddaman 	    { PR_SO_REUSEADDR,		"SO_REUSEADDR,"	},
580a02120c4SAndy Fiddaman 	    { PR_SO_KEEPALIVE,		"SO_KEEPALIVE,"	},
581a02120c4SAndy Fiddaman 	    { PR_SO_DONTROUTE,		"SO_DONTROUTE,"	},
582a02120c4SAndy Fiddaman 	    { PR_SO_BROADCAST,		"SO_BROADCAST,"	},
583a02120c4SAndy Fiddaman 	    { PR_SO_OOBINLINE,		"SO_OOBINLINE,"	},
584a02120c4SAndy Fiddaman 	    { PR_SO_DGRAM_ERRIND,	"SO_DGRAM_ERRIND,"},
585a02120c4SAndy Fiddaman 	    { PR_SO_ALLZONES,		"SO_ALLZONES,"	},
586a02120c4SAndy Fiddaman 	    { PR_SO_MAC_EXEMPT,		"SO_MAC_EXEMPT," },
587a02120c4SAndy Fiddaman 	    { PR_SO_MAC_IMPLICIT,	"SO_MAC_IMPLICIT," },
588a02120c4SAndy Fiddaman 	    { PR_SO_EXCLBIND,		"SO_EXCLBIND," },
589a02120c4SAndy Fiddaman 	    { PR_SO_VRRP,		"SO_VRRP," },
590a02120c4SAndy Fiddaman 	    { PR_UDP_NAT_T_ENDPOINT,	"UDP_NAT_T_ENDPOINT," },
5917c478bd9Sstevel@tonic-gate 	};
592a02120c4SAndy Fiddaman 	const struct linger *l;
593a02120c4SAndy Fiddaman 
594a02120c4SAndy Fiddaman 	opts = proc_fdinfo_misc(info, PR_SOCKOPTS_BOOL_OPTS, NULL);
5957c478bd9Sstevel@tonic-gate 
5965d0bc3edSsommerfe 	buf[0] = '!';		/* sentinel value, never printed */
5977c478bd9Sstevel@tonic-gate 	buf[1] = '\0';
5987c478bd9Sstevel@tonic-gate 
5997c478bd9Sstevel@tonic-gate 	for (i = 0; i < sizeof (boolopts) / sizeof (boolopts[0]); i++) {
600a02120c4SAndy Fiddaman 		if (opts != NULL && opts->prsock_bool_opts & boolopts[i].opt)
6017c478bd9Sstevel@tonic-gate 			(void) strlcat(buf, boolopts[i].name, sizeof (buf));
6027c478bd9Sstevel@tonic-gate 	}
6037c478bd9Sstevel@tonic-gate 
604a02120c4SAndy Fiddaman 	l = proc_fdinfo_misc(info, PR_SOCKOPT_LINGER, NULL);
605a02120c4SAndy Fiddaman 	if (l != NULL && l->l_onoff != 0) {
6067c478bd9Sstevel@tonic-gate 		(void) snprintf(buf1, sizeof (buf1), "SO_LINGER(%d),",
607a02120c4SAndy Fiddaman 		    l->l_linger);
6087c478bd9Sstevel@tonic-gate 		(void) strlcat(buf, buf1, sizeof (buf));
6097c478bd9Sstevel@tonic-gate 	}
6107c478bd9Sstevel@tonic-gate 
611a02120c4SAndy Fiddaman 	val = proc_fdinfo_misc(info, PR_SOCKOPT_SNDBUF, NULL);
612a02120c4SAndy Fiddaman 	if (val != NULL) {
613a02120c4SAndy Fiddaman 		(void) snprintf(buf1, sizeof (buf1), "SO_SNDBUF(%d),", *val);
6147c478bd9Sstevel@tonic-gate 		(void) strlcat(buf, buf1, sizeof (buf));
6157c478bd9Sstevel@tonic-gate 	}
616a02120c4SAndy Fiddaman 
617a02120c4SAndy Fiddaman 	val = proc_fdinfo_misc(info, PR_SOCKOPT_RCVBUF, NULL);
618a02120c4SAndy Fiddaman 	if (val != NULL) {
619a02120c4SAndy Fiddaman 		(void) snprintf(buf1, sizeof (buf1), "SO_RCVBUF(%d),", *val);
6207c478bd9Sstevel@tonic-gate 		(void) strlcat(buf, buf1, sizeof (buf));
6217c478bd9Sstevel@tonic-gate 	}
622a02120c4SAndy Fiddaman 
623a02120c4SAndy Fiddaman 
624a02120c4SAndy Fiddaman 	nexthop_val = proc_fdinfo_misc(info, PR_SOCKOPT_IP_NEXTHOP, &vlen);
625a02120c4SAndy Fiddaman 	if (nexthop_val != NULL && vlen > 0) {
626a02120c4SAndy Fiddaman 		(void) inet_ntop(AF_INET, (void *) nexthop_val,
62729e362daSpriyanka 		    ipaddr, sizeof (ipaddr));
62843d18f1cSpriyanka 		(void) snprintf(buf1, sizeof (buf1), "IP_NEXTHOP(%s),",
62943d18f1cSpriyanka 		    ipaddr);
63043d18f1cSpriyanka 		(void) strlcat(buf, buf1, sizeof (buf));
63143d18f1cSpriyanka 	}
6327c478bd9Sstevel@tonic-gate 
6335d0bc3edSsommerfe 	buf[strlen(buf) - 1] = '\0'; /* overwrites sentinel if no options */
6347c478bd9Sstevel@tonic-gate 	if (buf[1] != '\0')
6357c478bd9Sstevel@tonic-gate 		(void) printf("\t%s\n", buf+1);
6367c478bd9Sstevel@tonic-gate }
6377c478bd9Sstevel@tonic-gate 
6383e95bd4aSAnders Persson #define	MAXNALLOC	32
6393e95bd4aSAnders Persson static void
show_sockfilters(struct ps_prochandle * Pr,const prfdinfo_t * info)640a02120c4SAndy Fiddaman show_sockfilters(struct ps_prochandle *Pr, const prfdinfo_t *info)
6413e95bd4aSAnders Persson {
6423e95bd4aSAnders Persson 	struct fil_info *fi;
6433e95bd4aSAnders Persson 	int i = 0, nalloc = 2, len = nalloc * sizeof (*fi);
6443e95bd4aSAnders Persson 	boolean_t printhdr = B_TRUE;
645a02120c4SAndy Fiddaman 	int fd = info->pr_fd;
6463e95bd4aSAnders Persson 
6473e95bd4aSAnders Persson 	fi = calloc(nalloc, sizeof (*fi));
6483e95bd4aSAnders Persson 	if (fi == NULL) {
6493e95bd4aSAnders Persson 		perror("calloc");
6503e95bd4aSAnders Persson 		return;
6513e95bd4aSAnders Persson 	}
6523e95bd4aSAnders Persson 	/* CONSTCOND */
6533e95bd4aSAnders Persson 	while (1) {
6543e95bd4aSAnders Persson 		if (pr_getsockopt(Pr, fd, SOL_FILTER, FIL_LIST, fi, &len) != 0)
6553e95bd4aSAnders Persson 			break;
6563e95bd4aSAnders Persson 		/* No filters */
6573e95bd4aSAnders Persson 		if (len == 0)
6583e95bd4aSAnders Persson 			break;
6593e95bd4aSAnders Persson 		/* Make sure buffer was large enough */
6603e95bd4aSAnders Persson 		if (fi->fi_pos >= nalloc) {
6613e95bd4aSAnders Persson 			struct fil_info *new;
6623e95bd4aSAnders Persson 
6633e95bd4aSAnders Persson 			nalloc = fi->fi_pos + 1;
6643e95bd4aSAnders Persson 			if (nalloc > MAXNALLOC)
6653e95bd4aSAnders Persson 				break;
6663e95bd4aSAnders Persson 			len = nalloc * sizeof (*fi);
6673e95bd4aSAnders Persson 			new = realloc(fi, nalloc * sizeof (*fi));
6683e95bd4aSAnders Persson 			if (new == NULL) {
6693e95bd4aSAnders Persson 				perror("realloc");
6703e95bd4aSAnders Persson 				break;
6713e95bd4aSAnders Persson 			}
6723e95bd4aSAnders Persson 			fi = new;
6733e95bd4aSAnders Persson 			continue;
6743e95bd4aSAnders Persson 		}
6753e95bd4aSAnders Persson 
6763e95bd4aSAnders Persson 		for (i = 0; (i + 1) * sizeof (*fi) <= len; i++) {
6773e95bd4aSAnders Persson 			if (fi[i].fi_flags & FILF_BYPASS)
6783e95bd4aSAnders Persson 				continue;
6793e95bd4aSAnders Persson 			if (printhdr) {
6803e95bd4aSAnders Persson 				(void) printf("\tfilters: ");
6813e95bd4aSAnders Persson 				printhdr = B_FALSE;
6823e95bd4aSAnders Persson 			}
6833e95bd4aSAnders Persson 			(void) printf("%s", fi[i].fi_name);
6843e95bd4aSAnders Persson 			if (fi[i].fi_flags != 0) {
6853e95bd4aSAnders Persson 				(void) printf("(");
6863e95bd4aSAnders Persson 				if (fi[i].fi_flags & FILF_AUTO)
6873e95bd4aSAnders Persson 					(void) printf("auto,");
6883e95bd4aSAnders Persson 				if (fi[i].fi_flags & FILF_PROG)
6893e95bd4aSAnders Persson 					(void) printf("prog,");
6903e95bd4aSAnders Persson 				(void) printf("\b)");
6913e95bd4aSAnders Persson 			}
6923e95bd4aSAnders Persson 			if (fi[i].fi_pos == 0) /* last one */
6933e95bd4aSAnders Persson 				break;
6943e95bd4aSAnders Persson 			(void) printf(",");
6953e95bd4aSAnders Persson 		}
6963e95bd4aSAnders Persson 		if (!printhdr)
6973e95bd4aSAnders Persson 			(void) printf("\n");
6983e95bd4aSAnders Persson 		break;
6993e95bd4aSAnders Persson 	}
7003e95bd4aSAnders Persson 	free(fi);
7013e95bd4aSAnders Persson }
7023e95bd4aSAnders Persson 
703a154f012SAlexander Stetsenko /* print peer credentials for sockets and named pipes */
704a154f012SAlexander Stetsenko static void
dopeerucred(struct ps_prochandle * Pr,const prfdinfo_t * info)705a02120c4SAndy Fiddaman dopeerucred(struct ps_prochandle *Pr, const prfdinfo_t *info)
706a154f012SAlexander Stetsenko {
707a154f012SAlexander Stetsenko 	ucred_t *peercred = NULL;	/* allocated by getpeerucred */
708a154f012SAlexander Stetsenko 
709a02120c4SAndy Fiddaman 	if (pr_getpeerucred(Pr, info->pr_fd, &peercred) == 0) {
710a154f012SAlexander Stetsenko 		show_ucred("peer", peercred);
711a154f012SAlexander Stetsenko 		ucred_free(peercred);
712a154f012SAlexander Stetsenko 	}
713a154f012SAlexander Stetsenko }
714a154f012SAlexander Stetsenko 
715a02120c4SAndy Fiddaman static void
dosocknames(struct ps_prochandle * Pr,const prfdinfo_t * info)716a02120c4SAndy Fiddaman dosocknames(struct ps_prochandle *Pr, const prfdinfo_t *info)
717a02120c4SAndy Fiddaman {
718a02120c4SAndy Fiddaman 	const struct sockaddr *sa;
719a02120c4SAndy Fiddaman 	size_t vlen;
720a02120c4SAndy Fiddaman 
721a02120c4SAndy Fiddaman 	sa = proc_fdinfo_misc(info, PR_SOCKETNAME, &vlen);
722a02120c4SAndy Fiddaman 	if (sa != NULL)
723a02120c4SAndy Fiddaman 		show_sockaddr("sockname", sa, vlen);
724a02120c4SAndy Fiddaman 
725a02120c4SAndy Fiddaman 	sa = proc_fdinfo_misc(info, PR_PEERSOCKNAME, &vlen);
726a02120c4SAndy Fiddaman 	if (sa != NULL)
727a02120c4SAndy Fiddaman 		show_sockaddr("peername", sa, vlen);
728a02120c4SAndy Fiddaman }
729a02120c4SAndy Fiddaman 
7307c478bd9Sstevel@tonic-gate /* the file is a socket */
7317c478bd9Sstevel@tonic-gate static void
dosocket(struct ps_prochandle * Pr,const prfdinfo_t * info)732a02120c4SAndy Fiddaman dosocket(struct ps_prochandle *Pr, const prfdinfo_t *info)
7337c478bd9Sstevel@tonic-gate {
734a02120c4SAndy Fiddaman 	const int *type;
7357c478bd9Sstevel@tonic-gate 
736a02120c4SAndy Fiddaman 	type = proc_fdinfo_misc(info, PR_SOCKOPT_TYPE, NULL);
737a02120c4SAndy Fiddaman 	if (type != NULL)
738a02120c4SAndy Fiddaman 		show_socktype((uint_t)*type);
7397c478bd9Sstevel@tonic-gate 
740a02120c4SAndy Fiddaman 	show_sockopts(Pr, info);
741a02120c4SAndy Fiddaman 	show_sockfilters(Pr, info);
742a02120c4SAndy Fiddaman 	dosocknames(Pr, info);
743a02120c4SAndy Fiddaman 	dopeerucred(Pr, info);
744a154f012SAlexander Stetsenko }
745a154f012SAlexander Stetsenko 
746a154f012SAlexander Stetsenko /* the file is a fifo (aka "named pipe") */
747a154f012SAlexander Stetsenko static void
dofifo(struct ps_prochandle * Pr,const prfdinfo_t * info)748a02120c4SAndy Fiddaman dofifo(struct ps_prochandle *Pr, const prfdinfo_t *info)
749a154f012SAlexander Stetsenko {
750a02120c4SAndy Fiddaman 	dopeerucred(Pr, info);
751ca9327a6Smeem }
752