1/*	$NetBSD$	*/
2
3/*-
4 * Copyright (c) 1988, 1993
5 *	The Regents of the University of California.  All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 *    may be used to endorse or promote products derived from this software
17 *    without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#include <sys/cdefs.h>
33#ifndef lint
34__COPYRIGHT("@(#) Copyright (c) 1988, 1993\
35 The Regents of the University of California.  All rights reserved.");
36#endif /* not lint */
37
38#ifndef lint
39#if 0
40static char sccsid[] = "@(#)fstat.c	8.3 (Berkeley) 5/2/95";
41#else
42__RCSID("$NetBSD$");
43#endif
44#endif /* not lint */
45
46#include <sys/types.h>
47#include <sys/param.h>
48#include <sys/time.h>
49#include <sys/proc.h>
50#include <sys/stat.h>
51#include <sys/vnode.h>
52#include <sys/socket.h>
53#include <sys/socketvar.h>
54#include <sys/domain.h>
55#include <sys/protosw.h>
56#include <sys/unpcb.h>
57#include <sys/sysctl.h>
58#include <sys/filedesc.h>
59#include <sys/pipe.h>
60#define _KERNEL
61#include <sys/mount.h>
62#undef _KERNEL
63#define	_KERNEL
64#include <sys/file.h>
65#include <ufs/ufs/inode.h>
66#include <ufs/ufs/ufsmount.h>
67#undef _KERNEL
68#define NFS
69#include <nfs/nfsproto.h>
70#include <nfs/rpcv2.h>
71#include <nfs/nfs.h>
72#include <nfs/nfsnode.h>
73#undef NFS
74#include <msdosfs/denode.h>
75#include <msdosfs/bpb.h>
76#define	_KERNEL
77#include <msdosfs/msdosfsmount.h>
78#undef _KERNEL
79#define	_KERNEL
80#include <miscfs/genfs/layer.h>
81#undef _KERNEL
82
83#include <net/route.h>
84#include <netinet/in.h>
85#include <netinet/in_systm.h>
86#include <netinet/ip.h>
87#include <netinet/in_pcb.h>
88
89#ifdef INET6
90#include <netinet/ip6.h>
91#include <netinet6/ip6_var.h>
92#include <netinet6/in6_pcb.h>
93#endif
94
95#include <netatalk/at.h>
96#include <netatalk/ddp_var.h>
97
98#include <netdb.h>
99#include <arpa/inet.h>
100
101#include <ctype.h>
102#include <errno.h>
103#include <kvm.h>
104#include <limits.h>
105#include <nlist.h>
106#include <paths.h>
107#include <pwd.h>
108#include <stdio.h>
109#include <stdlib.h>
110#include <string.h>
111#include <unistd.h>
112#include <err.h>
113#include <util.h>
114
115#include "fstat.h"
116
117#define	TEXT	-1
118#define	CDIR	-2
119#define	RDIR	-3
120#define	TRACE	-4
121
122typedef struct devs {
123	struct	devs *next;
124	long	fsid;
125	ino_t	ino;
126	const char *name;
127} DEVS;
128static DEVS *devs;
129
130static int 	fsflg,	/* show files on same filesystem as file(s) argument */
131	pflg,	/* show files open by a particular pid */
132	uflg;	/* show files open by a particular (effective) user */
133static int 	checkfile; /* true if restricting to particular files or filesystems */
134static int	nflg;	/* (numerical) display f.s. and rdev as dev_t */
135int	vflg;	/* display errors in locating kernel data objects etc... */
136
137static fdfile_t **ofiles; /* buffer of pointers to file structures */
138static int fstat_maxfiles;
139#define ALLOC_OFILES(d)	\
140	if ((d) > fstat_maxfiles) { \
141		size_t len = (d) * sizeof(fdfile_t *); \
142		free(ofiles); \
143		ofiles = malloc(len); \
144		if (ofiles == NULL) { \
145			err(1, "malloc(%zu)", len);	\
146		} \
147		fstat_maxfiles = (d); \
148	}
149
150kvm_t *kd;
151
152static const char *const dtypes[] = {
153	DTYPE_NAMES
154};
155
156static void	dofiles(struct kinfo_proc2 *);
157static int	ext2fs_filestat(struct vnode *, struct filestat *);
158static int	getfname(const char *);
159static void	getinetproto(int);
160static void	getatproto(int);
161static char   *getmnton(struct mount *);
162static const char   *layer_filestat(struct vnode *, struct filestat *);
163static int	msdosfs_filestat(struct vnode *, struct filestat *);
164static int	nfs_filestat(struct vnode *, struct filestat *);
165static const char *inet_addrstr(char *, size_t, const struct in_addr *,
166    uint16_t);
167#ifdef INET6
168static const char *inet6_addrstr(char *, size_t, const struct in6_addr *,
169    uint16_t);
170#endif
171static const char *at_addrstr(char *, size_t, const struct sockaddr_at *);
172static void	socktrans(struct socket *, int);
173static void	misctrans(struct file *);
174static int	ufs_filestat(struct vnode *, struct filestat *);
175static void	usage(void) __dead;
176static const char   *vfilestat(struct vnode *, struct filestat *);
177static void	vtrans(struct vnode *, int, int);
178static void	ftrans(fdfile_t *, int);
179static void	ptrans(struct file *, struct pipe *, int);
180
181int
182main(int argc, char **argv)
183{
184	struct passwd *passwd;
185	struct kinfo_proc2 *p, *plast;
186	int arg, ch, what;
187	char *memf, *nlistf;
188	char buf[_POSIX2_LINE_MAX];
189	int cnt;
190	gid_t egid = getegid();
191
192	(void)setegid(getgid());
193	arg = 0;
194	what = KERN_PROC_ALL;
195	nlistf = memf = NULL;
196	while ((ch = getopt(argc, argv, "fnp:u:vN:M:")) != -1)
197		switch((char)ch) {
198		case 'f':
199			fsflg = 1;
200			break;
201		case 'M':
202			memf = optarg;
203			break;
204		case 'N':
205			nlistf = optarg;
206			break;
207		case 'n':
208			nflg = 1;
209			break;
210		case 'p':
211			if (pflg++)
212				usage();
213			if (!isdigit((unsigned char)*optarg)) {
214				warnx("-p requires a process id");
215				usage();
216			}
217			what = KERN_PROC_PID;
218			arg = atoi(optarg);
219			break;
220		case 'u':
221			if (uflg++)
222				usage();
223			if (!(passwd = getpwnam(optarg))) {
224				errx(1, "%s: unknown uid", optarg);
225			}
226			what = KERN_PROC_UID;
227			arg = passwd->pw_uid;
228			break;
229		case 'v':
230			vflg = 1;
231			break;
232		case '?':
233		default:
234			usage();
235		}
236
237	if (*(argv += optind)) {
238		for (; *argv; ++argv) {
239			if (getfname(*argv))
240				checkfile = 1;
241		}
242		if (!checkfile)	/* file(s) specified, but none accessible */
243			exit(1);
244	}
245
246	ALLOC_OFILES(256);	/* reserve space for file pointers */
247
248	if (fsflg && !checkfile) {
249		/* -f with no files means use wd */
250		if (getfname(".") == 0)
251			exit(1);
252		checkfile = 1;
253	}
254
255	/*
256	 * Discard setgid privileges.  If not the running kernel, we toss
257	 * them away totally so that bad guys can't print interesting stuff
258	 * from kernel memory, otherwise switch back to kmem for the
259	 * duration of the kvm_openfiles() call.
260	 */
261	if (nlistf != NULL || memf != NULL)
262		(void)setgid(getgid());
263	else
264		(void)setegid(egid);
265
266	if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, buf)) == NULL)
267		errx(1, "%s", buf);
268
269	/* get rid of it now anyway */
270	if (nlistf == NULL && memf == NULL)
271		(void)setgid(getgid());
272
273	if ((p = kvm_getproc2(kd, what, arg, sizeof *p, &cnt)) == NULL) {
274		errx(1, "%s", kvm_geterr(kd));
275	}
276	if (nflg)
277		(void)printf("%s",
278"USER     CMD          PID   FD  DEV     INUM  MODE  SZ|DV R/W");
279	else
280		(void)printf("%s",
281"USER     CMD          PID   FD MOUNT       INUM MODE         SZ|DV R/W");
282	if (checkfile && fsflg == 0)
283		(void)printf(" NAME\n");
284	else
285		(void)putchar('\n');
286
287	for (plast = &p[cnt]; p < plast; ++p) {
288		if (p->p_stat == SZOMB)
289			continue;
290		dofiles(p);
291	}
292	return 0;
293}
294
295static const	char *Uname, *Comm;
296pid_t	Pid;
297
298#define PREFIX(i) (void)printf("%-8.8s %-10s %5d", Uname, Comm, Pid); \
299	switch(i) { \
300	case TEXT: \
301		(void)printf(" text"); \
302		break; \
303	case CDIR: \
304		(void)printf("   wd"); \
305		break; \
306	case RDIR: \
307		(void)printf(" root"); \
308		break; \
309	case TRACE: \
310		(void)printf("   tr"); \
311		break; \
312	default: \
313		(void)printf(" %4d", i); \
314		break; \
315	}
316
317/*
318 * print open files attributed to this process
319 */
320static void
321dofiles(struct kinfo_proc2 *p)
322{
323	int i;
324	struct filedesc filed;
325	struct cwdinfo cwdi;
326	struct fdtab dt;
327
328	Uname = user_from_uid(p->p_uid, 0);
329	Pid = p->p_pid;
330	Comm = p->p_comm;
331
332	if (p->p_fd == 0 || p->p_cwdi == 0)
333		return;
334	if (!KVM_READ(p->p_fd, &filed, sizeof (filed))) {
335		warnx("can't read filedesc at %p for pid %d",
336		    (void *)(uintptr_t)p->p_fd, Pid);
337		return;
338	}
339	if (filed.fd_lastfile == -1)
340		return;
341	if (!KVM_READ(p->p_cwdi, &cwdi, sizeof(cwdi))) {
342		warnx("can't read cwdinfo at %p for pid %d",
343		    (void *)(uintptr_t)p->p_cwdi, Pid);
344		return;
345	}
346	if (!KVM_READ(filed.fd_dt, &dt, sizeof(dt))) {
347		warnx("can't read dtab at %p for pid %d", filed.fd_dt, Pid);
348		return;
349	}
350	if ((unsigned)filed.fd_lastfile >= dt.dt_nfiles ||
351	    filed.fd_freefile > filed.fd_lastfile + 1) {
352		dprintf("filedesc corrupted at %p for pid %d",
353		    (void *)(uintptr_t)p->p_fd, Pid);
354		return;
355	}
356	/*
357	 * root directory vnode, if one
358	 */
359	if (cwdi.cwdi_rdir)
360		vtrans(cwdi.cwdi_rdir, RDIR, FREAD);
361	/*
362	 * current working directory vnode
363	 */
364	vtrans(cwdi.cwdi_cdir, CDIR, FREAD);
365#if 0
366	/*
367	 * Disable for now, since p->p_tracep appears to point to a ktr_desc *
368	 * ktrace vnode, if one
369	 */
370	if (p->p_tracep)
371		ftrans(p->p_tracep, TRACE);
372#endif
373	/*
374	 * open files
375	 */
376#define FPSIZE	(sizeof (fdfile_t *))
377	ALLOC_OFILES(filed.fd_lastfile+1);
378	if (!KVM_READ(&filed.fd_dt->dt_ff, ofiles,
379	    (filed.fd_lastfile+1) * FPSIZE)) {
380		dprintf("can't read file structures at %p for pid %d",
381		    &filed.fd_dt->dt_ff, Pid);
382		return;
383	}
384	for (i = 0; i <= filed.fd_lastfile; i++) {
385		if (ofiles[i] == NULL)
386			continue;
387		ftrans(ofiles[i], i);
388	}
389}
390
391static void
392ftrans(fdfile_t *fp, int i)
393{
394	struct file file;
395	fdfile_t fdfile;
396
397	if (!KVM_READ(fp, &fdfile, sizeof(fdfile))) {
398		dprintf("can't read file %d at %p for pid %d",
399		    i, fp, Pid);
400		return;
401	}
402	if (fdfile.ff_file == NULL)
403		return;
404	if (!KVM_READ(fdfile.ff_file, &file, sizeof(file))) {
405		dprintf("can't read file %d at %p for pid %d",
406		    i, fdfile.ff_file, Pid);
407		return;
408	}
409	switch (file.f_type) {
410	case DTYPE_VNODE:
411		vtrans(file.f_data, i, file.f_flag);
412		break;
413	case DTYPE_SOCKET:
414		if (checkfile == 0)
415			socktrans(file.f_data, i);
416		break;
417	case DTYPE_PIPE:
418		if (checkfile == 0)
419			ptrans(&file, file.f_data, i);
420		break;
421	case DTYPE_MISC:
422	case DTYPE_KQUEUE:
423	case DTYPE_CRYPTO:
424	case DTYPE_MQUEUE:
425	case DTYPE_SEM:
426		if (checkfile == 0)
427			misctrans(&file);
428		break;
429	default:
430		dprintf("unknown file type %d for file %d of pid %d",
431		    file.f_type, i, Pid);
432		break;
433	}
434}
435
436static const char dead[] = "dead";
437
438static const char *
439vfilestat(struct vnode *vp, struct filestat *fsp)
440{
441	const char *badtype = NULL;
442
443	if (vp->v_type == VNON)
444		badtype = "none";
445	else if (vp->v_type == VBAD)
446		badtype = "bad";
447	else
448		switch (vp->v_tag) {
449		case VT_NON:
450			badtype = dead;
451			break;
452		case VT_UFS:
453		case VT_LFS:
454		case VT_MFS:
455			if (!ufs_filestat(vp, fsp))
456				badtype = "error";
457			break;
458		case VT_MSDOSFS:
459			if (!msdosfs_filestat(vp, fsp))
460				badtype = "error";
461			break;
462		case VT_NFS:
463			if (!nfs_filestat(vp, fsp))
464				badtype = "error";
465			break;
466		case VT_EXT2FS:
467			if (!ext2fs_filestat(vp, fsp))
468				badtype = "error";
469			break;
470		case VT_ISOFS:
471			if (!isofs_filestat(vp, fsp))
472				badtype = "error";
473			break;
474		case VT_NTFS:
475			if (!ntfs_filestat(vp, fsp))
476				badtype = "error";
477			break;
478		case VT_PTYFS:
479			if (!ptyfs_filestat(vp, fsp))
480				badtype = "error";
481			break;
482		case VT_TMPFS:
483			if (!tmpfs_filestat(vp, fsp))
484				badtype = "error";
485			break;
486		case VT_NULL:
487		case VT_OVERLAY:
488		case VT_UMAP:
489			badtype = layer_filestat(vp, fsp);
490			break;
491		default: {
492			static char unknown[10];
493			(void)snprintf(unknown, sizeof unknown,
494			    "?(%x)", vp->v_tag);
495			badtype = unknown;
496			break;
497		}
498	}
499	return badtype;
500}
501
502static void
503vtrans(struct vnode *vp, int i, int flag)
504{
505	struct vnode vn;
506	struct filestat fst;
507	char mode[15], rw[3];
508	const char *badtype, *filename;
509
510	filename = NULL;
511	if (!KVM_READ(vp, &vn, sizeof(struct vnode))) {
512		dprintf("can't read vnode at %p for pid %d", vp, Pid);
513		return;
514	}
515	badtype = vfilestat(&vn, &fst);
516	if (checkfile) {
517		int fsmatch = 0;
518		DEVS *d;
519
520		if (badtype && badtype != dead)
521			return;
522		for (d = devs; d != NULL; d = d->next)
523			if (d->fsid == fst.fsid) {
524				fsmatch = 1;
525				if (d->ino == fst.fileid) {
526					filename = d->name;
527					break;
528				}
529			}
530		if (fsmatch == 0 || (filename == NULL && fsflg == 0))
531			return;
532	}
533	PREFIX(i);
534	if (badtype == dead) {
535		char buf[1024];
536		(void)snprintb(buf, sizeof(buf), VNODE_FLAGBITS,
537		    vn.v_iflag | vn.v_vflag | vn.v_uflag);
538		(void)printf(" flags %s\n", buf);
539		return;
540	} else if (badtype) {
541		(void)printf(" -         -  %10s    -\n", badtype);
542		return;
543	}
544	if (nflg)
545		(void)printf(" %2llu,%-2llu",
546		    (unsigned long long)major(fst.fsid),
547		    (unsigned long long)minor(fst.fsid));
548	else
549		(void)printf(" %-8s", getmnton(vn.v_mount));
550	if (nflg)
551		(void)snprintf(mode, sizeof mode, "%o", fst.mode);
552	else
553		strmode(fst.mode, mode);
554	(void)printf(" %7"PRIu64" %*s", fst.fileid, nflg ? 5 : 10, mode);
555	switch (vn.v_type) {
556	case VBLK:
557	case VCHR: {
558		char *name;
559
560		if (nflg || ((name = devname(fst.rdev, vn.v_type == VCHR ?
561		    S_IFCHR : S_IFBLK)) == NULL))
562			(void)printf("  %2llu,%-2llu",
563			    (unsigned long long)major(fst.rdev),
564			    (unsigned long long)minor(fst.rdev));
565		else
566			(void)printf(" %6s", name);
567		break;
568	}
569	default:
570		(void)printf(" %6lld", (long long)fst.size);
571	}
572	rw[0] = '\0';
573	if (flag & FREAD)
574		(void)strlcat(rw, "r", sizeof(rw));
575	if (flag & FWRITE)
576		(void)strlcat(rw, "w", sizeof(rw));
577	(void)printf(" %-2s", rw);
578	if (filename && !fsflg)
579		(void)printf("  %s", filename);
580	(void)putchar('\n');
581}
582
583static int
584ufs_filestat(struct vnode *vp, struct filestat *fsp)
585{
586	struct inode inode;
587	struct ufsmount ufsmount;
588	union dinode {
589		struct ufs1_dinode dp1;
590		struct ufs2_dinode dp2;
591	} dip;
592
593	if (!KVM_READ(VTOI(vp), &inode, sizeof (inode))) {
594		dprintf("can't read inode at %p for pid %d", VTOI(vp), Pid);
595		return 0;
596	}
597
598	if (!KVM_READ(inode.i_ump, &ufsmount, sizeof (struct ufsmount))) {
599		dprintf("can't read ufsmount at %p for pid %d", inode.i_ump, Pid);
600		return 0;
601	}
602
603	switch (ufsmount.um_fstype) {
604	case UFS1:
605		if (!KVM_READ(inode.i_din.ffs1_din, &dip,
606		    sizeof(struct ufs1_dinode))) {
607			dprintf("can't read dinode at %p for pid %d",
608				inode.i_din.ffs1_din, Pid);
609			return 0;
610		}
611		fsp->rdev = dip.dp1.di_rdev;
612		break;
613	case UFS2:
614		if (!KVM_READ(inode.i_din.ffs2_din, &dip,
615		    sizeof(struct ufs2_dinode))) {
616			dprintf("can't read dinode at %p for pid %d",
617			    inode.i_din.ffs2_din, Pid);
618			return 0;
619		}
620		fsp->rdev = dip.dp2.di_rdev;
621		break;
622	default:
623		dprintf("unknown ufs type %ld for pid %d",
624			ufsmount.um_fstype, Pid);
625		break;
626	}
627	fsp->fsid = inode.i_dev & 0xffff;
628	fsp->fileid = inode.i_number;
629	fsp->mode = (mode_t)inode.i_mode;
630	fsp->size = inode.i_size;
631
632	return 1;
633}
634
635static int
636ext2fs_filestat(struct vnode *vp, struct filestat *fsp)
637{
638	struct inode inode;
639	struct ext2fs_dinode dinode;
640
641	if (!KVM_READ(VTOI(vp), &inode, sizeof (inode))) {
642		dprintf("can't read inode at %p for pid %d", VTOI(vp), Pid);
643		return 0;
644	}
645	fsp->fsid = inode.i_dev & 0xffff;
646	fsp->fileid = inode.i_number;
647
648	if (!KVM_READ(inode.i_din.e2fs_din, &dinode, sizeof dinode)) {
649		dprintf("can't read ext2fs_dinode at %p for pid %d",
650			inode.i_din.e2fs_din, Pid);
651		return 0;
652	}
653	fsp->mode = dinode.e2di_mode;
654	fsp->size = dinode.e2di_size;
655	fsp->rdev = dinode.e2di_rdev;
656
657	return 1;
658}
659
660static int
661nfs_filestat(struct vnode *vp, struct filestat *fsp)
662{
663	struct nfsnode nfsnode;
664	struct vattr va;
665
666	if (!KVM_READ(VTONFS(vp), &nfsnode, sizeof (nfsnode))) {
667		dprintf("can't read nfsnode at %p for pid %d", VTONFS(vp),
668		    Pid);
669		return 0;
670	}
671	if (!KVM_READ(nfsnode.n_vattr, &va, sizeof(va))) {
672		dprintf("can't read vnode attributes at %p for pid %d",
673		    nfsnode.n_vattr, Pid);
674		return 0;
675	}
676	fsp->fsid = va.va_fsid;
677	fsp->fileid = va.va_fileid;
678	fsp->size = nfsnode.n_size;
679	fsp->rdev = va.va_rdev;
680	fsp->mode = (mode_t)va.va_mode | getftype(vp->v_type);
681
682	return 1;
683}
684
685static int
686msdosfs_filestat(struct vnode *vp, struct filestat *fsp)
687{
688	struct denode de;
689	struct msdosfsmount mp;
690
691	if (!KVM_READ(VTONFS(vp), &de, sizeof(de))) {
692		dprintf("can't read denode at %p for pid %d", VTONFS(vp),
693		    Pid);
694		return 0;
695	}
696	if (!KVM_READ(de.de_pmp, &mp, sizeof(mp))) {
697		dprintf("can't read mount struct at %p for pid %d", de.de_pmp,
698		    Pid);
699		return 0;
700	}
701
702	fsp->fsid = de.de_dev & 0xffff;
703	fsp->fileid = 0; /* XXX see msdosfs_vptofh() for more info */
704	fsp->size = de.de_FileSize;
705	fsp->rdev = 0;	/* msdosfs doesn't support device files */
706	fsp->mode = (0777 & mp.pm_mask) | getftype(vp->v_type);
707	return 1;
708}
709
710static const char *
711layer_filestat(struct vnode *vp, struct filestat *fsp)
712{
713	struct layer_node layer_node;
714	struct mount mount;
715	struct vnode vn;
716	const char *badtype;
717
718	if (!KVM_READ(VTOLAYER(vp), &layer_node, sizeof(layer_node))) {
719		dprintf("can't read layer_node at %p for pid %d",
720		    VTOLAYER(vp), Pid);
721		return "error";
722	}
723	if (!KVM_READ(vp->v_mount, &mount, sizeof(struct mount))) {
724		dprintf("can't read mount struct at %p for pid %d",
725		    vp->v_mount, Pid);
726		return "error";
727	}
728	vp = layer_node.layer_lowervp;
729	if (!KVM_READ(vp, &vn, sizeof(struct vnode))) {
730		dprintf("can't read vnode at %p for pid %d", vp, Pid);
731		return "error";
732	}
733	if ((badtype = vfilestat(&vn, fsp)) == NULL)
734		fsp->fsid = mount.mnt_stat.f_fsidx.__fsid_val[0];
735	return badtype;
736}
737
738static char *
739getmnton(struct mount *m)
740{
741	static struct mount mount;
742	static struct mtab {
743		struct mtab *next;
744		struct mount *m;
745		char mntonname[MNAMELEN];
746	} *mhead = NULL;
747	struct mtab *mt;
748
749	for (mt = mhead; mt != NULL; mt = mt->next)
750		if (m == mt->m)
751			return mt->mntonname;
752	if (!KVM_READ(m, &mount, sizeof(struct mount))) {
753		warnx("can't read mount table at %p", m);
754		return NULL;
755	}
756	if ((mt = malloc(sizeof (struct mtab))) == NULL) {
757		err(1, "malloc(%u)", (unsigned int)sizeof(struct mtab));
758	}
759	mt->m = m;
760	(void)memmove(&mt->mntonname[0], &mount.mnt_stat.f_mntonname[0],
761	    MNAMELEN);
762	mt->next = mhead;
763	mhead = mt;
764	return mt->mntonname;
765}
766
767static const char *
768inet_addrstr(char *buf, size_t len, const struct in_addr *a, uint16_t p)
769{
770	char addr[256];
771
772	if (a->s_addr == INADDR_ANY) {
773		if (p == 0)
774			addr[0] = '\0';
775		else
776			strlcpy(addr, "*", sizeof(addr));
777	} else {
778		struct sockaddr_in sin;
779		const int niflags = NI_NUMERICHOST;
780
781		(void)memset(&sin, 0, sizeof(sin));
782		sin.sin_family = AF_INET6;
783		sin.sin_len = sizeof(sin);
784		sin.sin_addr = *a;
785
786		if (getnameinfo((struct sockaddr *)&sin, sin.sin_len,
787		    addr, sizeof(addr), NULL, 0, niflags))
788			if (inet_ntop(AF_INET, a, addr, sizeof(addr)) == NULL)
789				strlcpy(addr, "invalid", sizeof(addr));
790	}
791	if (addr[0])
792		snprintf(buf, len, "%s:%u", addr, p);
793	else
794		strlcpy(buf, addr, len);
795	return buf;
796}
797
798#ifdef INET6
799static const char *
800inet6_addrstr(char *buf, size_t len, const struct in6_addr *a, uint16_t p)
801{
802	char addr[256];
803
804	if (IN6_IS_ADDR_UNSPECIFIED(a)) {
805		if (p == 0)
806			addr[0] = '\0';
807		else
808			strlcpy(addr, "*", sizeof(addr));
809	} else {
810		struct sockaddr_in6 sin6;
811		const int niflags = NI_NUMERICHOST;
812
813		(void)memset(&sin6, 0, sizeof(sin6));
814		sin6.sin6_family = AF_INET6;
815		sin6.sin6_len = sizeof(sin6);
816		sin6.sin6_addr = *a;
817
818		if (IN6_IS_ADDR_LINKLOCAL(a) &&
819		    *(u_int16_t *)&sin6.sin6_addr.s6_addr[2] != 0) {
820			sin6.sin6_scope_id =
821				ntohs(*(uint16_t *)&sin6.sin6_addr.s6_addr[2]);
822			sin6.sin6_addr.s6_addr[2] = 0;
823			sin6.sin6_addr.s6_addr[3] = 0;
824		}
825
826		if (getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len,
827		    addr, sizeof(addr), NULL, 0, niflags))
828			if (inet_ntop(AF_INET6, a, addr, sizeof(addr)) == NULL)
829				strlcpy(addr, "invalid", sizeof(addr));
830	}
831	if (addr[0])
832		snprintf(buf, len, "[%s]:%u", addr, p);
833	else
834		strlcpy(buf, addr, len);
835
836	return buf;
837}
838#endif
839
840static const char *
841at_addrstr(char *buf, size_t len, const struct sockaddr_at *sat)
842{
843	const struct netrange *nr = &sat->sat_range.r_netrange;
844	const struct at_addr *at = &sat->sat_addr;
845	char addr[64], phase[64], range[64];
846
847	if (sat->sat_port || at->s_net || at->s_node) {
848		if (at->s_net || at->s_node)
849			snprintf(addr, sizeof(addr), "%u.%u:%u",
850			    ntohs(at->s_net), at->s_node, sat->sat_port);
851		else
852			snprintf(addr, sizeof(addr), "*:%u", sat->sat_port);
853	} else
854		addr[0] = '\0';
855
856	if (nr->nr_phase)
857		snprintf(phase, sizeof(phase), " phase %u", nr->nr_phase);
858	else
859		phase[0] = '\0';
860
861	if (nr->nr_firstnet || nr->nr_lastnet)
862		snprintf(range, sizeof(range), " range [%u-%u]",
863		    ntohs(nr->nr_firstnet), ntohs(nr->nr_lastnet));
864	else
865		range[0] = '\0';
866
867	snprintf(buf, len, "%s%s%s", addr, phase, range);
868	return buf;
869}
870
871static void
872socktrans(struct socket *sock, int i)
873{
874	static const char *stypename[] = {
875		"unused",	/* 0 */
876		"stream", 	/* 1 */
877		"dgram",	/* 2 */
878		"raw",		/* 3 */
879		"rdm",		/* 4 */
880		"seqpak"	/* 5 */
881	};
882#define	STYPEMAX 5
883	struct socket	so;
884	struct protosw	proto;
885	struct domain	dom;
886	struct inpcb	inpcb;
887#ifdef INET6
888	struct in6pcb	in6pcb;
889#endif
890	struct unpcb	unpcb;
891	struct ddpcb	ddpcb;
892	int len;
893	char dname[32];
894	char lbuf[512], fbuf[512];
895	PREFIX(i);
896
897	/* fill in socket */
898	if (!KVM_READ(sock, &so, sizeof(struct socket))) {
899		dprintf("can't read sock at %p", sock);
900		goto bad;
901	}
902
903	/* fill in protosw entry */
904	if (!KVM_READ(so.so_proto, &proto, sizeof(struct protosw))) {
905		dprintf("can't read protosw at %p", so.so_proto);
906		goto bad;
907	}
908
909	/* fill in domain */
910	if (!KVM_READ(proto.pr_domain, &dom, sizeof(struct domain))) {
911		dprintf("can't read domain at %p", proto.pr_domain);
912		goto bad;
913	}
914
915	if ((len = kvm_read(kd, (u_long)dom.dom_name, dname,
916	    sizeof(dname) - 1)) != sizeof(dname) -1) {
917		dprintf("can't read domain name at %p", dom.dom_name);
918		dname[0] = '\0';
919	}
920	else
921		dname[len] = '\0';
922
923	if ((u_short)so.so_type > STYPEMAX)
924		(void)printf("* %s ?%d", dname, so.so_type);
925	else
926		(void)printf("* %s %s", dname, stypename[so.so_type]);
927
928	/*
929	 * protocol specific formatting
930	 *
931	 * Try to find interesting things to print.  For TCP, the interesting
932	 * thing is the address of the tcpcb, for UDP and others, just the
933	 * inpcb (socket pcb).  For UNIX domain, its the address of the socket
934	 * pcb and the address of the connected pcb (if connected).  Otherwise
935	 * just print the protocol number and address of the socket itself.
936	 * The idea is not to duplicate netstat, but to make available enough
937	 * information for further analysis.
938	 */
939	fbuf[0] = '\0';
940	lbuf[0] = '\0';
941	switch(dom.dom_family) {
942	case AF_INET:
943		getinetproto(proto.pr_protocol);
944		switch (proto.pr_protocol) {
945		case IPPROTO_TCP:
946		case IPPROTO_UDP:
947			if (so.so_pcb == NULL)
948				break;
949			if (kvm_read(kd, (u_long)so.so_pcb, (char *)&inpcb,
950			    sizeof(inpcb)) != sizeof(inpcb)) {
951				dprintf("can't read inpcb at %p", so.so_pcb);
952				goto bad;
953			}
954			inet_addrstr(lbuf, sizeof(lbuf), &inpcb.inp_laddr,
955			    ntohs(inpcb.inp_lport));
956			inet_addrstr(fbuf, sizeof(fbuf), &inpcb.inp_faddr,
957			    ntohs(inpcb.inp_fport));
958			break;
959		default:
960			break;
961		}
962		break;
963#ifdef INET6
964	case AF_INET6:
965		getinetproto(proto.pr_protocol);
966		switch (proto.pr_protocol) {
967		case IPPROTO_TCP:
968		case IPPROTO_UDP:
969			if (so.so_pcb == NULL)
970				break;
971			if (kvm_read(kd, (u_long)so.so_pcb, (char *)&in6pcb,
972			    sizeof(in6pcb)) != sizeof(in6pcb)) {
973				dprintf("can't read in6pcb at %p", so.so_pcb);
974				goto bad;
975			}
976			inet6_addrstr(lbuf, sizeof(lbuf), &in6pcb.in6p_laddr,
977			    ntohs(in6pcb.in6p_lport));
978			inet6_addrstr(fbuf, sizeof(fbuf), &in6pcb.in6p_faddr,
979			    ntohs(in6pcb.in6p_fport));
980			break;
981		default:
982			break;
983		}
984		break;
985#endif
986	case AF_LOCAL:
987		/* print address of pcb and connected pcb */
988		if (so.so_pcb) {
989			char shoconn[4], *cp;
990
991			if (kvm_read(kd, (u_long)so.so_pcb, (char *)&unpcb,
992			    sizeof(struct unpcb)) != sizeof(struct unpcb)){
993				dprintf("can't read unpcb at %p", so.so_pcb);
994				goto bad;
995			}
996
997			cp = shoconn;
998			if (!(so.so_state & SS_CANTRCVMORE))
999				*cp++ = '<';
1000			*cp++ = '-';
1001			if (!(so.so_state & SS_CANTSENDMORE))
1002				*cp++ = '>';
1003			*cp = '\0';
1004			if (unpcb.unp_addr) {
1005				struct sockaddr_un *sun =
1006					malloc(unpcb.unp_addrlen);
1007				if (sun == NULL)
1008				    err(1, "malloc(%zu)",
1009					unpcb.unp_addrlen);
1010				if (kvm_read(kd, (u_long)unpcb.unp_addr,
1011				    sun, unpcb.unp_addrlen) !=
1012				    (ssize_t)unpcb.unp_addrlen) {
1013					dprintf("can't read sun at %p",
1014					    unpcb.unp_addr);
1015					free(sun);
1016				} else {
1017					snprintf(fbuf, sizeof(fbuf), " %s %s",
1018					    shoconn, sun->sun_path);
1019					free(sun);
1020					break;
1021				}
1022			}
1023			if (unpcb.unp_conn)
1024				snprintf(fbuf, sizeof(fbuf), " %s %lx", shoconn,
1025				    (long)unpcb.unp_conn);
1026		}
1027		break;
1028	case AF_APPLETALK:
1029		getatproto(proto.pr_protocol);
1030		if (so.so_pcb) {
1031			if (kvm_read(kd, (u_long)so.so_pcb, (char *)&ddpcb,
1032			    sizeof(ddpcb)) != sizeof(ddpcb)){
1033				dprintf("can't read ddpcb at %p", so.so_pcb);
1034				goto bad;
1035			}
1036			at_addrstr(fbuf, sizeof(fbuf), &ddpcb.ddp_fsat);
1037			at_addrstr(lbuf, sizeof(lbuf), &ddpcb.ddp_lsat);
1038		}
1039		break;
1040	default:
1041		/* print protocol number and socket address */
1042		snprintf(fbuf, sizeof(fbuf), " %d %jx", proto.pr_protocol,
1043		    (uintmax_t)(uintptr_t)sock);
1044		break;
1045	}
1046	if (fbuf[0] || lbuf[0])
1047		printf(" %s%s%s", fbuf, (fbuf[0] && lbuf[0]) ? " <-> " : "",
1048		    lbuf);
1049	else if (so.so_pcb)
1050		printf(" %jx", (uintmax_t)(uintptr_t)so.so_pcb);
1051	(void)printf("\n");
1052	return;
1053bad:
1054	(void)printf("* error\n");
1055}
1056
1057static void
1058ptrans(struct file *fp, struct pipe *cpipe, int i)
1059{
1060	struct pipe cp;
1061
1062	PREFIX(i);
1063
1064	/* fill in pipe */
1065	if (!KVM_READ(cpipe, &cp, sizeof(struct pipe))) {
1066		dprintf("can't read pipe at %p", cpipe);
1067		goto bad;
1068	}
1069
1070	/* pipe descriptor is either read or write, never both */
1071	(void)printf("* pipe %p %s %p %s%s%s", cpipe,
1072		(fp->f_flag & FWRITE) ? "->" : "<-",
1073		cp.pipe_peer,
1074		(fp->f_flag & FWRITE) ? "w" : "r",
1075		(fp->f_flag & FNONBLOCK) ? "n" : "",
1076		(cp.pipe_state & PIPE_ASYNC) ? "a" : "");
1077	(void)printf("\n");
1078	return;
1079bad:
1080	(void)printf("* error\n");
1081}
1082
1083static void
1084misctrans(struct file *file)
1085{
1086
1087	PREFIX((int)file->f_type);
1088	pmisc(file, dtypes[file->f_type]);
1089}
1090
1091/*
1092 * getinetproto --
1093 *	print name of protocol number
1094 */
1095static void
1096getinetproto(int number)
1097{
1098	const char *cp;
1099
1100	switch (number) {
1101	case IPPROTO_IP:
1102		cp = "ip"; break;
1103	case IPPROTO_ICMP:
1104		cp ="icmp"; break;
1105	case IPPROTO_GGP:
1106		cp ="ggp"; break;
1107	case IPPROTO_TCP:
1108		cp ="tcp"; break;
1109	case IPPROTO_EGP:
1110		cp ="egp"; break;
1111	case IPPROTO_PUP:
1112		cp ="pup"; break;
1113	case IPPROTO_UDP:
1114		cp ="udp"; break;
1115	case IPPROTO_IDP:
1116		cp ="idp"; break;
1117	case IPPROTO_RAW:
1118		cp ="raw"; break;
1119	case IPPROTO_ICMPV6:
1120		cp ="icmp6"; break;
1121	default:
1122		(void)printf(" %d", number);
1123		return;
1124	}
1125	(void)printf(" %s", cp);
1126}
1127
1128/*
1129 * getatproto --
1130 *	print name of protocol number
1131 */
1132static void
1133getatproto(int number)
1134{
1135	const char *cp;
1136
1137	switch (number) {
1138	case ATPROTO_DDP:
1139		cp = "ddp"; break;
1140	case ATPROTO_AARP:
1141		cp ="aarp"; break;
1142	default:
1143		(void)printf(" %d", number);
1144		return;
1145	}
1146	(void)printf(" %s", cp);
1147}
1148
1149static int
1150getfname(const char *filename)
1151{
1152	struct stat statbuf;
1153	DEVS *cur;
1154
1155	if (stat(filename, &statbuf)) {
1156		warn("stat(%s)", filename);
1157		return 0;
1158	}
1159	if ((cur = malloc(sizeof(*cur))) == NULL) {
1160		err(1, "malloc(%zu)", sizeof(*cur));
1161	}
1162	cur->next = devs;
1163	devs = cur;
1164
1165	cur->ino = statbuf.st_ino;
1166	cur->fsid = statbuf.st_dev & 0xffff;
1167	cur->name = filename;
1168	return 1;
1169}
1170
1171mode_t
1172getftype(enum vtype v_type)
1173{
1174	mode_t ftype;
1175
1176	switch (v_type) {
1177	case VREG:
1178		ftype = S_IFREG;
1179		break;
1180	case VDIR:
1181		ftype = S_IFDIR;
1182		break;
1183	case VBLK:
1184		ftype = S_IFBLK;
1185		break;
1186	case VCHR:
1187		ftype = S_IFCHR;
1188		break;
1189	case VLNK:
1190		ftype = S_IFLNK;
1191		break;
1192	case VSOCK:
1193		ftype = S_IFSOCK;
1194		break;
1195	case VFIFO:
1196		ftype = S_IFIFO;
1197		break;
1198	default:
1199		ftype = 0;
1200		break;
1201	};
1202
1203	return ftype;
1204}
1205
1206static void
1207usage(void)
1208{
1209	(void)fprintf(stderr, "Usage: %s [-fnv] [-p pid] [-u user] "
1210	    "[-N system] [-M core] [file ...]\n", getprogname());
1211	exit(1);
1212}
1213