Fri Jan 17 03:28:01 2014 UTC ()
make fstat -f search for unix sockets.


(christos)
diff -r1.106 -r1.107 src/usr.bin/fstat/fstat.c

cvs diff -r1.106 -r1.107 src/usr.bin/fstat/fstat.c (expand / switch to unified diff)

--- src/usr.bin/fstat/fstat.c 2013/12/15 18:56:59 1.106
+++ src/usr.bin/fstat/fstat.c 2014/01/17 03:28:01 1.107
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: fstat.c,v 1.106 2013/12/15 18:56:59 mlelstv Exp $ */ 1/* $NetBSD: fstat.c,v 1.107 2014/01/17 03:28:01 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.
@@ -29,27 +29,27 @@ @@ -29,27 +29,27 @@
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.106 2013/12/15 18:56:59 mlelstv Exp $"); 42__RCSID("$NetBSD: fstat.c,v 1.107 2014/01/17 03:28:01 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>
@@ -500,28 +500,27 @@ ftrans(fdfile_t *fp, int i) @@ -500,28 +500,27 @@ ftrans(fdfile_t *fp, int i)
500 if (!KVM_READ(fdfile.ff_file, &file, sizeof(file))) { 500 if (!KVM_READ(fdfile.ff_file, &file, sizeof(file))) {
501 dprintf("can't read file %d at %p for pid %d", 501 dprintf("can't read file %d at %p for pid %d",
502 i, fdfile.ff_file, Pid); 502 i, fdfile.ff_file, Pid);
503 return; 503 return;
504 } 504 }
505 if (Aflg && file.f_type != DTYPE_VNODE && checkfile == 0) 505 if (Aflg && file.f_type != DTYPE_VNODE && checkfile == 0)
506 (void)printf("%*lx ", 506 (void)printf("%*lx ",
507 2*(int)(sizeof(void*)), (long)fdfile.ff_file); 507 2*(int)(sizeof(void*)), (long)fdfile.ff_file);
508 switch (file.f_type) { 508 switch (file.f_type) {
509 case DTYPE_VNODE: 509 case DTYPE_VNODE:
510 vtrans(file.f_data, i, file.f_flag, (long)fdfile.ff_file); 510 vtrans(file.f_data, i, file.f_flag, (long)fdfile.ff_file);
511 break; 511 break;
512 case DTYPE_SOCKET: 512 case DTYPE_SOCKET:
513 if (checkfile == 0) 513 socktrans(file.f_data, i);
514 socktrans(file.f_data, i); 
515 break; 514 break;
516 case DTYPE_PIPE: 515 case DTYPE_PIPE:
517 if (checkfile == 0) 516 if (checkfile == 0)
518 ptrans(&file, file.f_data, i); 517 ptrans(&file, file.f_data, i);
519 break; 518 break;
520 case DTYPE_MISC: 519 case DTYPE_MISC:
521 case DTYPE_KQUEUE: 520 case DTYPE_KQUEUE:
522 case DTYPE_CRYPTO: 521 case DTYPE_CRYPTO:
523 case DTYPE_MQUEUE: 522 case DTYPE_MQUEUE:
524 case DTYPE_SEM: 523 case DTYPE_SEM:
525 if (checkfile == 0) 524 if (checkfile == 0)
526 misctrans(&file, i); 525 misctrans(&file, i);
527 break; 526 break;
@@ -588,57 +587,69 @@ vfilestat(struct vnode *vp, struct files @@ -588,57 +587,69 @@ vfilestat(struct vnode *vp, struct files
588 badtype = layer_filestat(vp, fsp); 587 badtype = layer_filestat(vp, fsp);
589 break; 588 break;
590 default: { 589 default: {
591 static char unknown[10]; 590 static char unknown[10];
592 (void)snprintf(unknown, sizeof unknown, 591 (void)snprintf(unknown, sizeof unknown,
593 "?(%x)", vp->v_tag); 592 "?(%x)", vp->v_tag);
594 badtype = unknown; 593 badtype = unknown;
595 break; 594 break;
596 } 595 }
597 } 596 }
598 return badtype; 597 return badtype;
599} 598}
600 599
601static void 600static int
602vtrans(struct vnode *vp, int i, int flag, long addr) 601checkfs(struct vnode *vp, struct vnode *vn, struct filestat *fst,
 602 const char **type, const char **fname)
603{ 603{
604 struct vnode vn; 604 *fname = NULL;
605 struct filestat fst; 605 if (!KVM_READ(vp, vn, sizeof(*vn))) {
606 char mode[15], rw[3]; 
607 const char *badtype, *filename; 
608 
609 filename = NULL; 
610 if (!KVM_READ(vp, &vn, sizeof(struct vnode))) { 
611 dprintf("can't read vnode at %p for pid %d", vp, Pid); 606 dprintf("can't read vnode at %p for pid %d", vp, Pid);
612 return; 607 return 0;
613 } 608 }
614 badtype = vfilestat(&vn, &fst); 609 *type = vfilestat(vn, fst);
615 if (checkfile) { 610 if (checkfile) {
616 int fsmatch = 0; 611 int fsmatch = 0;
617 DEVS *d; 612 DEVS *d;
618 613#if 0
619 if (badtype && badtype != dead) 614 if (*type && *type != dead)
620 return; 615 return 0;
621 for (d = devs; d != NULL; d = d->next) 616#endif
622 if (d->fsid == fst.fsid) { 617 for (d = devs; d != NULL; d = d->next) {
 618 if (d->fsid == fst->fsid) {
623 fsmatch = 1; 619 fsmatch = 1;
624 if (d->ino == fst.fileid) { 620 if (d->ino == fst->fileid) {
625 filename = d->name; 621 *fname = d->name;
626 break; 622 break;
627 } 623 }
628 } 624 }
629 if (fsmatch == 0 || (filename == NULL && fsflg == 0)) 625 }
630 return; 626 if (fsmatch == 0 || (*fname == NULL && fsflg == 0))
 627 return 0;
631 } 628 }
 629 return 1;
 630}
 631
 632static void
 633vtrans(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
632 if (Aflg) 643 if (Aflg)
633 (void)printf("%*lx ", 2*(int)(sizeof(void*)), addr); 644 (void)printf("%*lx ", 2*(int)(sizeof(void*)), addr);
634 PREFIX(i); 645 PREFIX(i);
635 if (badtype == dead) { 646 if (badtype == dead) {
636 char buf[1024]; 647 char buf[1024];
637 (void)snprintb(buf, sizeof(buf), VNODE_FLAGBITS, 648 (void)snprintb(buf, sizeof(buf), VNODE_FLAGBITS,
638 vn.v_iflag | vn.v_vflag | vn.v_uflag); 649 vn.v_iflag | vn.v_vflag | vn.v_uflag);
639 (void)printf(" flags %s\n", buf); 650 (void)printf(" flags %s\n", buf);
640 return; 651 return;
641 } else if (badtype) { 652 } else if (badtype) {
642 (void)printf(" - - %10s -\n", badtype); 653 (void)printf(" - - %10s -\n", badtype);
643 return; 654 return;
644 } 655 }
@@ -989,59 +1000,56 @@ socktrans(struct socket *sock, int i) @@ -989,59 +1000,56 @@ socktrans(struct socket *sock, int i)
989#define STYPEMAX 5 1000#define STYPEMAX 5
990 struct socket so; 1001 struct socket so;
991 struct protosw proto; 1002 struct protosw proto;
992 struct domain dom; 1003 struct domain dom;
993 struct inpcb inpcb; 1004 struct inpcb inpcb;
994#ifdef INET6 1005#ifdef INET6
995 struct in6pcb in6pcb; 1006 struct in6pcb in6pcb;
996#endif 1007#endif
997 struct unpcb unpcb; 1008 struct unpcb unpcb;
998 struct ddpcb ddpcb; 1009 struct ddpcb ddpcb;
999 int len; 1010 int len;
1000 char dname[32]; 1011 char dname[32];
1001 char lbuf[512], fbuf[512]; 1012 char lbuf[512], fbuf[512];
1002 PREFIX(i); 
1003 1013
1004 /* fill in socket */ 1014 /* fill in socket */
1005 if (!KVM_READ(sock, &so, sizeof(struct socket))) { 1015 if (!KVM_READ(sock, &so, sizeof(struct socket))) {
1006 dprintf("can't read sock at %p", sock); 1016 dprintf("can't read sock at %p", sock);
1007 goto bad; 1017 goto bad;
1008 } 1018 }
1009 1019
1010 /* fill in protosw entry */ 1020 /* fill in protosw entry */
1011 if (!KVM_READ(so.so_proto, &proto, sizeof(struct protosw))) { 1021 if (!KVM_READ(so.so_proto, &proto, sizeof(struct protosw))) {
1012 dprintf("can't read protosw at %p", so.so_proto); 1022 dprintf("can't read protosw at %p", so.so_proto);
1013 goto bad; 1023 goto bad;
1014 } 1024 }
1015 1025
1016 /* fill in domain */ 1026 /* fill in domain */
1017 if (!KVM_READ(proto.pr_domain, &dom, sizeof(struct domain))) { 1027 if (!KVM_READ(proto.pr_domain, &dom, sizeof(struct domain))) {
1018 dprintf("can't read domain at %p", proto.pr_domain); 1028 dprintf("can't read domain at %p", proto.pr_domain);
1019 goto bad; 1029 goto bad;
1020 } 1030 }
1021 1031
 1032 if (checkfile && dom.dom_family != AF_LOCAL)
 1033 return;
 1034
1022 if ((len = kvm_read(kd, (u_long)dom.dom_name, dname, 1035 if ((len = kvm_read(kd, (u_long)dom.dom_name, dname,
1023 sizeof(dname) - 1)) != sizeof(dname) -1) { 1036 sizeof(dname) - 1)) != sizeof(dname) -1) {
1024 dprintf("can't read domain name at %p", dom.dom_name); 1037 dprintf("can't read domain name at %p", dom.dom_name);
1025 dname[0] = '\0'; 1038 dname[0] = '\0';
1026 } 1039 }
1027 else 1040 else
1028 dname[len] = '\0'; 1041 dname[len] = '\0';
1029 1042
1030 if ((u_short)so.so_type > STYPEMAX) 
1031 (void)printf("* %s ?%d", dname, so.so_type); 
1032 else 
1033 (void)printf("* %s %s", dname, stypename[so.so_type]); 
1034 
1035 /*  1043 /*
1036 * protocol specific formatting 1044 * protocol specific formatting
1037 * 1045 *
1038 * Try to find interesting things to print. For TCP, the interesting 1046 * Try to find interesting things to print. For TCP, the interesting
1039 * thing is the address of the tcpcb, for UDP and others, just the 1047 * thing is the address of the tcpcb, for UDP and others, just the
1040 * inpcb (socket pcb). For UNIX domain, its the address of the socket 1048 * inpcb (socket pcb). For UNIX domain, its the address of the socket
1041 * pcb and the address of the connected pcb (if connected). Otherwise 1049 * pcb and the address of the connected pcb (if connected). Otherwise
1042 * just print the protocol number and address of the socket itself. 1050 * just print the protocol number and address of the socket itself.
1043 * The idea is not to duplicate netstat, but to make available enough 1051 * The idea is not to duplicate netstat, but to make available enough
1044 * information for further analysis. 1052 * information for further analysis.
1045 */ 1053 */
1046 fbuf[0] = '\0'; 1054 fbuf[0] = '\0';
1047 lbuf[0] = '\0'; 1055 lbuf[0] = '\0';
@@ -1102,26 +1110,36 @@ socktrans(struct socket *sock, int i) @@ -1102,26 +1110,36 @@ socktrans(struct socket *sock, int i)
1102 cp = shoconn; 1110 cp = shoconn;
1103 if (!(so.so_state & SS_CANTRCVMORE)) 1111 if (!(so.so_state & SS_CANTRCVMORE))
1104 *cp++ = '<'; 1112 *cp++ = '<';
1105 *cp++ = '-'; 1113 *cp++ = '-';
1106 if (!(so.so_state & SS_CANTSENDMORE)) 1114 if (!(so.so_state & SS_CANTSENDMORE))
1107 *cp++ = '>'; 1115 *cp++ = '>';
1108 *cp = '\0'; 1116 *cp = '\0';
1109again: 1117again:
1110 if (kvm_read(kd, (u_long)pcb[p], (char *)&unpcb, 1118 if (kvm_read(kd, (u_long)pcb[p], (char *)&unpcb,
1111 sizeof(struct unpcb)) != sizeof(struct unpcb)){ 1119 sizeof(struct unpcb)) != sizeof(struct unpcb)){
1112 dprintf("can't read unpcb at %p", so.so_pcb); 1120 dprintf("can't read unpcb at %p", so.so_pcb);
1113 goto bad; 1121 goto bad;
1114 } 1122 }
 1123 if (checkfile) {
 1124 struct vnode vn;
 1125 struct filestat fst;
 1126 const char *badtype, *filename;
 1127 if (unpcb.unp_vnode == NULL)
 1128 return;
 1129 if (!checkfs(unpcb.unp_vnode, &vn, &fst,
 1130 &badtype, &filename))
 1131 return;
 1132 }
1115 1133
1116 if (unpcb.unp_addr) { 1134 if (unpcb.unp_addr) {
1117 struct sockaddr_un *sun =  1135 struct sockaddr_un *sun =
1118 malloc(unpcb.unp_addrlen); 1136 malloc(unpcb.unp_addrlen);
1119 if (sun == NULL) 1137 if (sun == NULL)
1120 err(1, "malloc(%zu)", 1138 err(1, "malloc(%zu)",
1121 unpcb.unp_addrlen); 1139 unpcb.unp_addrlen);
1122 if (kvm_read(kd, (u_long)unpcb.unp_addr, 1140 if (kvm_read(kd, (u_long)unpcb.unp_addr,
1123 sun, unpcb.unp_addrlen) != 1141 sun, unpcb.unp_addrlen) !=
1124 (ssize_t)unpcb.unp_addrlen) { 1142 (ssize_t)unpcb.unp_addrlen) {
1125 dprintf("can't read sun at %p", 1143 dprintf("can't read sun at %p",
1126 unpcb.unp_addr); 1144 unpcb.unp_addr);
1127 free(sun); 1145 free(sun);
@@ -1152,26 +1170,32 @@ again: @@ -1152,26 +1170,32 @@ again:
1152 dprintf("can't read ddpcb at %p", so.so_pcb); 1170 dprintf("can't read ddpcb at %p", so.so_pcb);
1153 goto bad; 1171 goto bad;
1154 } 1172 }
1155 at_addrstr(fbuf, sizeof(fbuf), &ddpcb.ddp_fsat); 1173 at_addrstr(fbuf, sizeof(fbuf), &ddpcb.ddp_fsat);
1156 at_addrstr(lbuf, sizeof(lbuf), &ddpcb.ddp_lsat); 1174 at_addrstr(lbuf, sizeof(lbuf), &ddpcb.ddp_lsat);
1157 } 1175 }
1158 break; 1176 break;
1159 default: 1177 default:
1160 /* print protocol number and socket address */ 1178 /* print protocol number and socket address */
1161 snprintf(fbuf, sizeof(fbuf), " %d %jx", proto.pr_protocol, 1179 snprintf(fbuf, sizeof(fbuf), " %d %jx", proto.pr_protocol,
1162 (uintmax_t)(uintptr_t)sock); 1180 (uintmax_t)(uintptr_t)sock);
1163 break; 1181 break;
1164 } 1182 }
 1183 PREFIX(i);
 1184 if ((u_short)so.so_type > STYPEMAX)
 1185 (void)printf("* %s ?%d", dname, so.so_type);
 1186 else
 1187 (void)printf("* %s %s", dname, stypename[so.so_type]);
 1188
1165 if (fbuf[0] || lbuf[0]) 1189 if (fbuf[0] || lbuf[0])
1166 printf(" %s%s%s", fbuf, (fbuf[0] && lbuf[0]) ? " <-> " : "", 1190 printf(" %s%s%s", fbuf, (fbuf[0] && lbuf[0]) ? " <-> " : "",
1167 lbuf); 1191 lbuf);
1168 else if (so.so_pcb) 1192 else if (so.so_pcb)
1169 printf(" %jx", (uintmax_t)(uintptr_t)so.so_pcb); 1193 printf(" %jx", (uintmax_t)(uintptr_t)so.so_pcb);
1170 (void)printf("\n"); 1194 (void)printf("\n");
1171 return; 1195 return;
1172bad: 1196bad:
1173 (void)printf("* error\n"); 1197 (void)printf("* error\n");
1174} 1198}
1175 1199
1176static void 1200static void
1177ptrans(struct file *fp, struct pipe *cpipe, int i) 1201ptrans(struct file *fp, struct pipe *cpipe, int i)