Wed Aug 26 23:08:29 2020 UTC ()
Provide a helpful error message if we don't have privs to read kernel
addresses.


(christos)
diff -r1.113 -r1.114 src/usr.bin/fstat/fstat.c

cvs diff -r1.113 -r1.114 src/usr.bin/fstat/fstat.c (switch to unified diff)

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