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