1 /* $NetBSD: fstat.c,v 1.110 2015/12/22 23:35:21 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.110 2015/12/22 23:35:21 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, bool); 169 #ifdef INET6 170 static const char *inet6_addrstr(char *, size_t, const struct in6_addr *, 171 uint16_t, bool); 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 static const char *vnode_tag[] = { 536 VNODE_TAGS 537 }; 538 539 static const char * 540 vfilestat(struct vnode *vp, struct filestat *fsp) 541 { 542 const char *badtype = NULL; 543 544 if (vp->v_type == VNON) 545 badtype = "none"; 546 else if (vp->v_type == VBAD) 547 badtype = "bad"; 548 else 549 switch (vp->v_tag) { 550 case VT_NON: 551 badtype = dead; 552 break; 553 case VT_UFS: 554 case VT_LFS: 555 case VT_MFS: 556 if (!ufs_filestat(vp, fsp)) 557 badtype = "error"; 558 break; 559 case VT_MSDOSFS: 560 if (!msdosfs_filestat(vp, fsp)) 561 badtype = "error"; 562 break; 563 case VT_NFS: 564 if (!nfs_filestat(vp, fsp)) 565 badtype = "error"; 566 break; 567 case VT_EXT2FS: 568 if (!ext2fs_filestat(vp, fsp)) 569 badtype = "error"; 570 break; 571 case VT_ISOFS: 572 if (!isofs_filestat(vp, fsp)) 573 badtype = "error"; 574 break; 575 case VT_NTFS: 576 if (!ntfs_filestat(vp, fsp)) 577 badtype = "error"; 578 break; 579 case VT_PTYFS: 580 if (!ptyfs_filestat(vp, fsp)) 581 badtype = "error"; 582 break; 583 case VT_TMPFS: 584 if (!tmpfs_filestat(vp, fsp)) 585 badtype = "error"; 586 break; 587 case VT_NULL: 588 case VT_OVERLAY: 589 case VT_UMAP: 590 badtype = layer_filestat(vp, fsp); 591 break; 592 default: { 593 static char unknown[10]; 594 (void)snprintf(unknown, sizeof unknown, "%s(%#x)", 595 (size_t)vp->v_tag < __arraycount(vnode_tag) ? 596 vnode_tag[vp->v_tag] : "?", vp->v_tag); 597 badtype = unknown; 598 break; 599 } 600 } 601 return badtype; 602 } 603 604 static int 605 checkfs(struct vnode *vp, struct vnode *vn, struct filestat *fst, 606 const char **type, const char **fname) 607 { 608 *fname = NULL; 609 if (!KVM_READ(vp, vn, sizeof(*vn))) { 610 dprintf("can't read vnode at %p for pid %d", vp, Pid); 611 return 0; 612 } 613 *type = vfilestat(vn, fst); 614 if (checkfile) { 615 int fsmatch = 0; 616 DEVS *d; 617 #if 0 618 if (*type && *type != dead) 619 return 0; 620 #endif 621 for (d = devs; d != NULL; d = d->next) { 622 if (d->fsid == fst->fsid) { 623 fsmatch = 1; 624 if (d->ino == fst->fileid) { 625 *fname = d->name; 626 break; 627 } 628 } 629 } 630 if (fsmatch == 0 || (*fname == NULL && fsflg == 0)) 631 return 0; 632 } 633 return 1; 634 } 635 636 static void 637 vtrans(struct vnode *vp, int i, int flag, long addr) 638 { 639 struct vnode vn; 640 char mode[15], rw[3]; 641 const char *badtype, *filename; 642 struct filestat fst; 643 644 if (!checkfs(vp, &vn, &fst, &badtype, &filename)) 645 return; 646 647 if (Aflg) 648 (void)printf("%*lx ", 2*(int)(sizeof(void*)), addr); 649 PREFIX(i); 650 if (badtype == dead) { 651 char buf[1024]; 652 (void)snprintb(buf, sizeof(buf), VNODE_FLAGBITS, 653 vn.v_iflag | vn.v_vflag | vn.v_uflag); 654 (void)printf(" flags %s\n", buf); 655 return; 656 } else if (badtype) { 657 (void)printf(" - - %10s -\n", badtype); 658 return; 659 } 660 if (nflg) 661 (void)printf(" %2llu,%-2llu", 662 (unsigned long long)major(fst.fsid), 663 (unsigned long long)minor(fst.fsid)); 664 else 665 (void)printf(" %-8s", getmnton(vn.v_mount)); 666 if (nflg) 667 (void)snprintf(mode, sizeof mode, "%o", fst.mode); 668 else 669 strmode(fst.mode, mode); 670 (void)printf(" %7"PRIu64" %*s", fst.fileid, nflg ? 5 : 10, mode); 671 switch (vn.v_type) { 672 case VBLK: 673 case VCHR: { 674 char *name; 675 676 if (nflg || ((name = devname(fst.rdev, vn.v_type == VCHR ? 677 S_IFCHR : S_IFBLK)) == NULL)) 678 (void)printf(" %s,%-2llu", 679 kdriver_search(vn.v_type, major(fst.rdev)), 680 (unsigned long long)minor(fst.rdev)); 681 else 682 (void)printf(" %6s", name); 683 break; 684 } 685 default: 686 (void)printf(" %6lld", (long long)fst.size); 687 } 688 rw[0] = '\0'; 689 if (flag & FREAD) 690 (void)strlcat(rw, "r", sizeof(rw)); 691 if (flag & FWRITE) 692 (void)strlcat(rw, "w", sizeof(rw)); 693 (void)printf(" %-2s", rw); 694 if (filename && !fsflg) 695 (void)printf(" %s", filename); 696 (void)putchar('\n'); 697 } 698 699 static int 700 ufs_filestat(struct vnode *vp, struct filestat *fsp) 701 { 702 struct inode inode; 703 struct ufsmount ufsmount; 704 union dinode { 705 struct ufs1_dinode dp1; 706 struct ufs2_dinode dp2; 707 } dip; 708 709 if (!KVM_READ(VTOI(vp), &inode, sizeof (inode))) { 710 dprintf("can't read inode at %p for pid %d", VTOI(vp), Pid); 711 return 0; 712 } 713 714 if (!KVM_READ(inode.i_ump, &ufsmount, sizeof (struct ufsmount))) { 715 dprintf("can't read ufsmount at %p for pid %d", inode.i_ump, Pid); 716 return 0; 717 } 718 719 switch (ufsmount.um_fstype) { 720 case UFS1: 721 if (!KVM_READ(inode.i_din.ffs1_din, &dip, 722 sizeof(struct ufs1_dinode))) { 723 dprintf("can't read dinode at %p for pid %d", 724 inode.i_din.ffs1_din, Pid); 725 return 0; 726 } 727 fsp->rdev = dip.dp1.di_rdev; 728 break; 729 case UFS2: 730 if (!KVM_READ(inode.i_din.ffs2_din, &dip, 731 sizeof(struct ufs2_dinode))) { 732 dprintf("can't read dinode at %p for pid %d", 733 inode.i_din.ffs2_din, Pid); 734 return 0; 735 } 736 fsp->rdev = dip.dp2.di_rdev; 737 break; 738 default: 739 dprintf("unknown ufs type %ld for pid %d", 740 ufsmount.um_fstype, Pid); 741 break; 742 } 743 fsp->fsid = inode.i_dev & 0xffff; 744 fsp->fileid = inode.i_number; 745 fsp->mode = (mode_t)inode.i_mode; 746 fsp->size = inode.i_size; 747 748 return 1; 749 } 750 751 static int 752 ext2fs_filestat(struct vnode *vp, struct filestat *fsp) 753 { 754 struct inode inode; 755 struct ext2fs_dinode dinode; 756 757 if (!KVM_READ(VTOI(vp), &inode, sizeof (inode))) { 758 dprintf("can't read inode at %p for pid %d", VTOI(vp), Pid); 759 return 0; 760 } 761 fsp->fsid = inode.i_dev & 0xffff; 762 fsp->fileid = inode.i_number; 763 764 if (!KVM_READ(inode.i_din.e2fs_din, &dinode, sizeof dinode)) { 765 dprintf("can't read ext2fs_dinode at %p for pid %d", 766 inode.i_din.e2fs_din, Pid); 767 return 0; 768 } 769 fsp->mode = dinode.e2di_mode; 770 fsp->size = dinode.e2di_size; 771 fsp->rdev = dinode.e2di_rdev; 772 773 return 1; 774 } 775 776 static int 777 nfs_filestat(struct vnode *vp, struct filestat *fsp) 778 { 779 struct nfsnode nfsnode; 780 struct vattr va; 781 782 if (!KVM_READ(VTONFS(vp), &nfsnode, sizeof (nfsnode))) { 783 dprintf("can't read nfsnode at %p for pid %d", VTONFS(vp), 784 Pid); 785 return 0; 786 } 787 if (!KVM_READ(nfsnode.n_vattr, &va, sizeof(va))) { 788 dprintf("can't read vnode attributes at %p for pid %d", 789 nfsnode.n_vattr, Pid); 790 return 0; 791 } 792 fsp->fsid = va.va_fsid; 793 fsp->fileid = va.va_fileid; 794 fsp->size = nfsnode.n_size; 795 fsp->rdev = va.va_rdev; 796 fsp->mode = (mode_t)va.va_mode | getftype(vp->v_type); 797 798 return 1; 799 } 800 801 static int 802 msdosfs_filestat(struct vnode *vp, struct filestat *fsp) 803 { 804 struct denode de; 805 struct msdosfsmount mp; 806 807 if (!KVM_READ(VTONFS(vp), &de, sizeof(de))) { 808 dprintf("can't read denode at %p for pid %d", VTONFS(vp), 809 Pid); 810 return 0; 811 } 812 if (!KVM_READ(de.de_pmp, &mp, sizeof(mp))) { 813 dprintf("can't read mount struct at %p for pid %d", de.de_pmp, 814 Pid); 815 return 0; 816 } 817 818 fsp->fsid = de.de_dev & 0xffff; 819 fsp->fileid = 0; /* XXX see msdosfs_vptofh() for more info */ 820 fsp->size = de.de_FileSize; 821 fsp->rdev = 0; /* msdosfs doesn't support device files */ 822 fsp->mode = (0777 & mp.pm_mask) | getftype(vp->v_type); 823 return 1; 824 } 825 826 static const char * 827 layer_filestat(struct vnode *vp, struct filestat *fsp) 828 { 829 struct layer_node layer_node; 830 struct mount mount; 831 struct vnode vn; 832 const char *badtype; 833 834 if (!KVM_READ(VTOLAYER(vp), &layer_node, sizeof(layer_node))) { 835 dprintf("can't read layer_node at %p for pid %d", 836 VTOLAYER(vp), Pid); 837 return "error"; 838 } 839 if (!KVM_READ(vp->v_mount, &mount, sizeof(struct mount))) { 840 dprintf("can't read mount struct at %p for pid %d", 841 vp->v_mount, Pid); 842 return "error"; 843 } 844 vp = layer_node.layer_lowervp; 845 if (!KVM_READ(vp, &vn, sizeof(struct vnode))) { 846 dprintf("can't read vnode at %p for pid %d", vp, Pid); 847 return "error"; 848 } 849 if ((badtype = vfilestat(&vn, fsp)) == NULL) 850 fsp->fsid = mount.mnt_stat.f_fsidx.__fsid_val[0]; 851 return badtype; 852 } 853 854 static char * 855 getmnton(struct mount *m) 856 { 857 static struct mount mount; 858 static struct mtab { 859 struct mtab *next; 860 struct mount *m; 861 char mntonname[MNAMELEN]; 862 } *mhead = NULL; 863 struct mtab *mt; 864 865 for (mt = mhead; mt != NULL; mt = mt->next) 866 if (m == mt->m) 867 return mt->mntonname; 868 if (!KVM_READ(m, &mount, sizeof(struct mount))) { 869 warnx("can't read mount table at %p", m); 870 return NULL; 871 } 872 if ((mt = malloc(sizeof (struct mtab))) == NULL) { 873 err(1, "malloc(%u)", (unsigned int)sizeof(struct mtab)); 874 } 875 mt->m = m; 876 (void)memmove(&mt->mntonname[0], &mount.mnt_stat.f_mntonname[0], 877 MNAMELEN); 878 mt->next = mhead; 879 mhead = mt; 880 return mt->mntonname; 881 } 882 883 static const char * 884 inet_addrstr(char *buf, size_t len, const struct in_addr *a, uint16_t p, bool isdg) 885 { 886 char addr[256], serv[256]; 887 struct sockaddr_in sin; 888 const int niflags = 889 (nflg ? (NI_NUMERICHOST|NI_NUMERICSERV) : 0) | 890 (isdg ? NI_DGRAM : 0); 891 892 893 (void)memset(&sin, 0, sizeof(sin)); 894 sin.sin_family = AF_INET; 895 sin.sin_len = sizeof(sin); 896 sin.sin_addr = *a; 897 sin.sin_port = htons(p); 898 899 serv[0] = '\0'; 900 901 if (getnameinfo((struct sockaddr *)&sin, sin.sin_len, 902 addr, sizeof(addr), serv, sizeof(serv), niflags)) { 903 if (inet_ntop(AF_INET, a, addr, sizeof(addr)) == NULL) 904 strlcpy(addr, "invalid", sizeof(addr)); 905 } 906 907 if (serv[0] == '\0') 908 snprintf(serv, sizeof(serv), "%u", p); 909 910 if (a->s_addr == INADDR_ANY) { 911 if (p == 0) 912 buf[0] = '\0'; 913 else 914 snprintf(buf, len, "*:%s", serv); 915 return buf; 916 } 917 918 snprintf(buf, len, "%s:%s", addr, serv); 919 return buf; 920 } 921 922 #ifdef INET6 923 static const char * 924 inet6_addrstr(char *buf, size_t len, const struct in6_addr *a, uint16_t p, bool isdg) 925 { 926 char addr[256], serv[256]; 927 struct sockaddr_in6 sin6; 928 const int niflags = 929 (nflg ? (NI_NUMERICHOST|NI_NUMERICSERV) : 0) | 930 (isdg ? NI_DGRAM : 0); 931 932 (void)memset(&sin6, 0, sizeof(sin6)); 933 sin6.sin6_family = AF_INET6; 934 sin6.sin6_len = sizeof(sin6); 935 sin6.sin6_addr = *a; 936 sin6.sin6_port = htons(p); 937 938 inet6_getscopeid(&sin6, INET6_IS_ADDR_LINKLOCAL); 939 serv[0] = '\0'; 940 941 if (getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len, 942 addr, sizeof(addr), serv, sizeof(serv), niflags)) { 943 if (inet_ntop(AF_INET6, a, addr, sizeof(addr)) == NULL) 944 strlcpy(addr, "invalid", sizeof(addr)); 945 } 946 947 if (serv[0] == '\0') 948 snprintf(serv, sizeof(serv), "%u", p); 949 950 if (IN6_IS_ADDR_UNSPECIFIED(a)) { 951 if (p == 0) 952 buf[0] = '\0'; 953 else 954 snprintf(buf, len, "*:%s", serv); 955 return buf; 956 } 957 958 if (strchr(addr, ':') == NULL) 959 snprintf(buf, len, "%s:%s", addr, serv); 960 else 961 snprintf(buf, len, "[%s]:%s", addr, serv); 962 963 return buf; 964 } 965 #endif 966 967 static const char * 968 at_addrstr(char *buf, size_t len, const struct sockaddr_at *sat) 969 { 970 const struct netrange *nr = &sat->sat_range.r_netrange; 971 const struct at_addr *at = &sat->sat_addr; 972 char addr[64], phase[64], range[64]; 973 974 if (sat->sat_port || at->s_net || at->s_node) { 975 if (at->s_net || at->s_node) 976 snprintf(addr, sizeof(addr), "%u.%u:%u", 977 ntohs(at->s_net), at->s_node, sat->sat_port); 978 else 979 snprintf(addr, sizeof(addr), "*:%u", sat->sat_port); 980 } else 981 addr[0] = '\0'; 982 983 if (nr->nr_phase) 984 snprintf(phase, sizeof(phase), " phase %u", nr->nr_phase); 985 else 986 phase[0] = '\0'; 987 988 if (nr->nr_firstnet || nr->nr_lastnet) 989 snprintf(range, sizeof(range), " range [%u-%u]", 990 ntohs(nr->nr_firstnet), ntohs(nr->nr_lastnet)); 991 else 992 range[0] = '\0'; 993 994 snprintf(buf, len, "%s%s%s", addr, phase, range); 995 return buf; 996 } 997 998 static void 999 socktrans(struct socket *sock, int i) 1000 { 1001 static const char *stypename[] = { 1002 "unused", /* 0 */ 1003 "stream", /* 1 */ 1004 "dgram", /* 2 */ 1005 "raw", /* 3 */ 1006 "rdm", /* 4 */ 1007 "seqpak" /* 5 */ 1008 }; 1009 #define STYPEMAX 5 1010 struct socket so; 1011 struct protosw proto; 1012 struct domain dom; 1013 struct inpcb inpcb; 1014 #ifdef INET6 1015 struct in6pcb in6pcb; 1016 #endif 1017 struct unpcb unpcb; 1018 struct ddpcb ddpcb; 1019 int len; 1020 char dname[32]; 1021 char lbuf[512], fbuf[512], pbuf[24]; 1022 bool isdgram; 1023 1024 pbuf[0] = '\0'; 1025 /* fill in socket */ 1026 if (!KVM_READ(sock, &so, sizeof(struct socket))) { 1027 dprintf("can't read sock at %p", sock); 1028 goto bad; 1029 } 1030 1031 /* fill in protosw entry */ 1032 if (!KVM_READ(so.so_proto, &proto, sizeof(struct protosw))) { 1033 dprintf("can't read protosw at %p", so.so_proto); 1034 goto bad; 1035 } 1036 1037 /* fill in domain */ 1038 if (!KVM_READ(proto.pr_domain, &dom, sizeof(struct domain))) { 1039 dprintf("can't read domain at %p", proto.pr_domain); 1040 goto bad; 1041 } 1042 1043 if (checkfile && dom.dom_family != AF_LOCAL) 1044 return; 1045 1046 if ((len = kvm_read(kd, (u_long)dom.dom_name, dname, 1047 sizeof(dname) - 1)) != sizeof(dname) -1) { 1048 dprintf("can't read domain name at %p", dom.dom_name); 1049 dname[0] = '\0'; 1050 } 1051 else 1052 dname[len] = '\0'; 1053 1054 /* 1055 * protocol specific formatting 1056 * 1057 * Try to find interesting things to print. For TCP, the interesting 1058 * thing is the address of the tcpcb, for UDP and others, just the 1059 * inpcb (socket pcb). For UNIX domain, its the address of the socket 1060 * pcb and the address of the connected pcb (if connected). Otherwise 1061 * just print the protocol number and address of the socket itself. 1062 * The idea is not to duplicate netstat, but to make available enough 1063 * information for further analysis. 1064 */ 1065 fbuf[0] = '\0'; 1066 lbuf[0] = '\0'; 1067 isdgram = false; 1068 switch(dom.dom_family) { 1069 case AF_INET: 1070 getinetproto(pbuf, sizeof(pbuf), proto.pr_protocol); 1071 switch (proto.pr_protocol) { 1072 case IPPROTO_UDP: 1073 isdgram = true; 1074 case IPPROTO_TCP: 1075 if (so.so_pcb == NULL) 1076 break; 1077 if (kvm_read(kd, (u_long)so.so_pcb, (char *)&inpcb, 1078 sizeof(inpcb)) != sizeof(inpcb)) { 1079 dprintf("can't read inpcb at %p", so.so_pcb); 1080 goto bad; 1081 } 1082 inet_addrstr(lbuf, sizeof(lbuf), &inpcb.inp_laddr, 1083 ntohs(inpcb.inp_lport), isdgram); 1084 inet_addrstr(fbuf, sizeof(fbuf), &inpcb.inp_faddr, 1085 ntohs(inpcb.inp_fport), isdgram); 1086 break; 1087 default: 1088 break; 1089 } 1090 break; 1091 #ifdef INET6 1092 case AF_INET6: 1093 getinetproto(pbuf, sizeof(pbuf), proto.pr_protocol); 1094 switch (proto.pr_protocol) { 1095 case IPPROTO_UDP: 1096 isdgram = true; 1097 case IPPROTO_TCP: 1098 if (so.so_pcb == NULL) 1099 break; 1100 if (kvm_read(kd, (u_long)so.so_pcb, (char *)&in6pcb, 1101 sizeof(in6pcb)) != sizeof(in6pcb)) { 1102 dprintf("can't read in6pcb at %p", so.so_pcb); 1103 goto bad; 1104 } 1105 inet6_addrstr(lbuf, sizeof(lbuf), &in6pcb.in6p_laddr, 1106 ntohs(in6pcb.in6p_lport), isdgram); 1107 inet6_addrstr(fbuf, sizeof(fbuf), &in6pcb.in6p_faddr, 1108 ntohs(in6pcb.in6p_fport), isdgram); 1109 break; 1110 default: 1111 break; 1112 } 1113 break; 1114 #endif 1115 case AF_LOCAL: 1116 /* print address of pcb and connected pcb */ 1117 if (so.so_pcb) { 1118 char shoconn[4], *cp; 1119 void *pcb[2]; 1120 size_t p = 0; 1121 1122 pcb[0] = so.so_pcb; 1123 1124 cp = shoconn; 1125 if (!(so.so_state & SS_CANTRCVMORE)) 1126 *cp++ = '<'; 1127 *cp++ = '-'; 1128 if (!(so.so_state & SS_CANTSENDMORE)) 1129 *cp++ = '>'; 1130 *cp = '\0'; 1131 again: 1132 if (kvm_read(kd, (u_long)pcb[p], (char *)&unpcb, 1133 sizeof(struct unpcb)) != sizeof(struct unpcb)){ 1134 dprintf("can't read unpcb at %p", so.so_pcb); 1135 goto bad; 1136 } 1137 if (checkfile) { 1138 struct vnode vn; 1139 struct filestat fst; 1140 const char *badtype, *filename; 1141 if (unpcb.unp_vnode == NULL) 1142 return; 1143 if (!checkfs(unpcb.unp_vnode, &vn, &fst, 1144 &badtype, &filename)) 1145 return; 1146 } 1147 1148 if (unpcb.unp_addr) { 1149 struct sockaddr_un *sun = 1150 malloc(unpcb.unp_addrlen); 1151 if (sun == NULL) 1152 err(1, "malloc(%zu)", 1153 unpcb.unp_addrlen); 1154 if (kvm_read(kd, (u_long)unpcb.unp_addr, 1155 sun, unpcb.unp_addrlen) != 1156 (ssize_t)unpcb.unp_addrlen) { 1157 dprintf("can't read sun at %p", 1158 unpcb.unp_addr); 1159 free(sun); 1160 } else { 1161 snprintf(fbuf, sizeof(fbuf), " %s %s %s", 1162 shoconn, sun->sun_path, 1163 p == 0 ? "[creat]" : "[using]"); 1164 free(sun); 1165 break; 1166 } 1167 } 1168 if (unpcb.unp_conn) { 1169 if (p == 0) { 1170 pcb[++p] = unpcb.unp_conn; 1171 goto again; 1172 } else 1173 snprintf(fbuf, sizeof(fbuf), 1174 " %p %s %p", pcb[0], shoconn, 1175 pcb[1]); 1176 } 1177 } 1178 break; 1179 case AF_APPLETALK: 1180 getatproto(pbuf, sizeof(pbuf), proto.pr_protocol); 1181 if (so.so_pcb) { 1182 if (kvm_read(kd, (u_long)so.so_pcb, (char *)&ddpcb, 1183 sizeof(ddpcb)) != sizeof(ddpcb)){ 1184 dprintf("can't read ddpcb at %p", so.so_pcb); 1185 goto bad; 1186 } 1187 at_addrstr(fbuf, sizeof(fbuf), &ddpcb.ddp_fsat); 1188 at_addrstr(lbuf, sizeof(lbuf), &ddpcb.ddp_lsat); 1189 } 1190 break; 1191 default: 1192 /* print protocol number and socket address */ 1193 snprintf(fbuf, sizeof(fbuf), " %d %jx", proto.pr_protocol, 1194 (uintmax_t)(uintptr_t)sock); 1195 break; 1196 } 1197 PREFIX(i); 1198 if ((u_short)so.so_type > STYPEMAX) 1199 (void)printf("* %s ?%d", dname, so.so_type); 1200 else 1201 (void)printf("* %s %s", dname, stypename[so.so_type]); 1202 1203 if (pbuf[0]) 1204 printf("%s", pbuf); 1205 if (fbuf[0] || lbuf[0]) 1206 printf(" %s%s%s", fbuf, (fbuf[0] && lbuf[0]) ? " <-> " : "", 1207 lbuf); 1208 else if (so.so_pcb) 1209 printf(" %jx", (uintmax_t)(uintptr_t)so.so_pcb); 1210 (void)printf("\n"); 1211 return; 1212 bad: 1213 (void)printf("* error\n"); 1214 } 1215 1216 static void 1217 ptrans(struct file *fp, struct pipe *cpipe, int i) 1218 { 1219 struct pipe cp; 1220 1221 PREFIX(i); 1222 1223 /* fill in pipe */ 1224 if (!KVM_READ(cpipe, &cp, sizeof(struct pipe))) { 1225 dprintf("can't read pipe at %p", cpipe); 1226 goto bad; 1227 } 1228 1229 /* pipe descriptor is either read or write, never both */ 1230 (void)printf("* pipe %p %s %p %s%s%s", cpipe, 1231 (fp->f_flag & FWRITE) ? "->" : "<-", 1232 cp.pipe_peer, 1233 (fp->f_flag & FWRITE) ? "w" : "r", 1234 (fp->f_flag & FNONBLOCK) ? "n" : "", 1235 (cp.pipe_state & PIPE_ASYNC) ? "a" : ""); 1236 (void)printf("\n"); 1237 return; 1238 bad: 1239 (void)printf("* error\n"); 1240 } 1241 1242 static void 1243 misctrans(struct file *file, int i) 1244 { 1245 1246 PREFIX(i); 1247 pmisc(file, dtypes[file->f_type]); 1248 } 1249 1250 /* 1251 * getinetproto -- 1252 * print name of protocol number 1253 */ 1254 static void 1255 getinetproto(char *buf, size_t len, int number) 1256 { 1257 const char *cp; 1258 1259 switch (number) { 1260 case IPPROTO_IP: 1261 cp = "ip"; break; 1262 case IPPROTO_ICMP: 1263 cp ="icmp"; break; 1264 case IPPROTO_GGP: 1265 cp ="ggp"; break; 1266 case IPPROTO_TCP: 1267 cp ="tcp"; break; 1268 case IPPROTO_EGP: 1269 cp ="egp"; break; 1270 case IPPROTO_PUP: 1271 cp ="pup"; break; 1272 case IPPROTO_UDP: 1273 cp ="udp"; break; 1274 case IPPROTO_IDP: 1275 cp ="idp"; break; 1276 case IPPROTO_RAW: 1277 cp ="raw"; break; 1278 case IPPROTO_ICMPV6: 1279 cp ="icmp6"; break; 1280 default: 1281 (void)snprintf(buf, len, " %d", number); 1282 return; 1283 } 1284 (void)snprintf(buf, len, " %s", cp); 1285 } 1286 1287 /* 1288 * getatproto -- 1289 * print name of protocol number 1290 */ 1291 static void 1292 getatproto(char *buf, size_t len, int number) 1293 { 1294 const char *cp; 1295 1296 switch (number) { 1297 case ATPROTO_DDP: 1298 cp = "ddp"; break; 1299 case ATPROTO_AARP: 1300 cp ="aarp"; break; 1301 default: 1302 (void)snprintf(buf, len, " %d", number); 1303 return; 1304 } 1305 (void)snprintf(buf, len, " %s", cp); 1306 } 1307 1308 static int 1309 getfname(const char *filename) 1310 { 1311 struct stat statbuf; 1312 DEVS *cur; 1313 1314 if (stat(filename, &statbuf)) { 1315 warn("stat(%s)", filename); 1316 return 0; 1317 } 1318 if ((cur = malloc(sizeof(*cur))) == NULL) { 1319 err(1, "malloc(%zu)", sizeof(*cur)); 1320 } 1321 cur->next = devs; 1322 devs = cur; 1323 1324 cur->ino = statbuf.st_ino; 1325 cur->fsid = statbuf.st_dev & 0xffff; 1326 cur->name = filename; 1327 return 1; 1328 } 1329 1330 mode_t 1331 getftype(enum vtype v_type) 1332 { 1333 mode_t ftype; 1334 1335 switch (v_type) { 1336 case VREG: 1337 ftype = S_IFREG; 1338 break; 1339 case VDIR: 1340 ftype = S_IFDIR; 1341 break; 1342 case VBLK: 1343 ftype = S_IFBLK; 1344 break; 1345 case VCHR: 1346 ftype = S_IFCHR; 1347 break; 1348 case VLNK: 1349 ftype = S_IFLNK; 1350 break; 1351 case VSOCK: 1352 ftype = S_IFSOCK; 1353 break; 1354 case VFIFO: 1355 ftype = S_IFIFO; 1356 break; 1357 default: 1358 ftype = 0; 1359 break; 1360 }; 1361 1362 return ftype; 1363 } 1364 1365 static void 1366 usage(void) 1367 { 1368 (void)fprintf(stderr, "Usage: %s [-Afnv] [-M core] [-N system] " 1369 "[-p pid] [-u user] [file ...]\n", getprogname()); 1370 exit(1); 1371 } 1372