13d91be41SRobert Watson /*- 23d91be41SRobert Watson * Copyright (c) 2007 Robert N. M. Watson 33d91be41SRobert Watson * All rights reserved. 43d91be41SRobert Watson * 53d91be41SRobert Watson * Redistribution and use in source and binary forms, with or without 63d91be41SRobert Watson * modification, are permitted provided that the following conditions 73d91be41SRobert Watson * are met: 83d91be41SRobert Watson * 1. Redistributions of source code must retain the above copyright 93d91be41SRobert Watson * notice, this list of conditions and the following disclaimer. 103d91be41SRobert Watson * 2. Redistributions in binary form must reproduce the above copyright 113d91be41SRobert Watson * notice, this list of conditions and the following disclaimer in the 123d91be41SRobert Watson * documentation and/or other materials provided with the distribution. 133d91be41SRobert Watson * 143d91be41SRobert Watson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 153d91be41SRobert Watson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 163d91be41SRobert Watson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 173d91be41SRobert Watson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 183d91be41SRobert Watson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 193d91be41SRobert Watson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 203d91be41SRobert Watson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 213d91be41SRobert Watson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 223d91be41SRobert Watson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 233d91be41SRobert Watson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 243d91be41SRobert Watson * SUCH DAMAGE. 253d91be41SRobert Watson * 263d91be41SRobert Watson * $FreeBSD$ 273d91be41SRobert Watson */ 283d91be41SRobert Watson 29e1f323f3SRobert Watson #include <sys/param.h> 303d91be41SRobert Watson #include <sys/socket.h> 313d91be41SRobert Watson #include <sys/sysctl.h> 323d91be41SRobert Watson #include <sys/un.h> 333d91be41SRobert Watson #include <sys/user.h> 343d91be41SRobert Watson 353d91be41SRobert Watson #include <netinet/in.h> 363d91be41SRobert Watson 373d91be41SRobert Watson #include <arpa/inet.h> 383d91be41SRobert Watson 39821df508SXin LI #include <err.h> 403d91be41SRobert Watson #include <inttypes.h> 413d91be41SRobert Watson #include <stdio.h> 423d91be41SRobert Watson #include <stdlib.h> 433d91be41SRobert Watson #include <string.h> 4443151ee6SPeter Wemm #include <libutil.h> 453d91be41SRobert Watson 463d91be41SRobert Watson #include "procstat.h" 473d91be41SRobert Watson 483d91be41SRobert Watson static const char * 493d91be41SRobert Watson protocol_to_string(int domain, int type, int protocol) 503d91be41SRobert Watson { 513d91be41SRobert Watson 523d91be41SRobert Watson switch (domain) { 533d91be41SRobert Watson case AF_INET: 543d91be41SRobert Watson case AF_INET6: 553d91be41SRobert Watson switch (protocol) { 563d91be41SRobert Watson case IPPROTO_TCP: 573d91be41SRobert Watson return ("TCP"); 583d91be41SRobert Watson case IPPROTO_UDP: 593d91be41SRobert Watson return ("UDP"); 603d91be41SRobert Watson case IPPROTO_ICMP: 615a246d29SRobert Watson return ("ICM"); 623d91be41SRobert Watson case IPPROTO_RAW: 633d91be41SRobert Watson return ("RAW"); 643d91be41SRobert Watson case IPPROTO_SCTP: 655a246d29SRobert Watson return ("SCT"); 665a246d29SRobert Watson case IPPROTO_DIVERT: 675a246d29SRobert Watson return ("IPD"); 683d91be41SRobert Watson default: 695a246d29SRobert Watson return ("IP?"); 703d91be41SRobert Watson } 713d91be41SRobert Watson 723d91be41SRobert Watson case AF_LOCAL: 733d91be41SRobert Watson switch (type) { 743d91be41SRobert Watson case SOCK_STREAM: 755a246d29SRobert Watson return ("UDS"); 763d91be41SRobert Watson case SOCK_DGRAM: 775a246d29SRobert Watson return ("UDD"); 783d91be41SRobert Watson default: 795a246d29SRobert Watson return ("UD?"); 803d91be41SRobert Watson } 813d91be41SRobert Watson default: 825a246d29SRobert Watson return ("?"); 833d91be41SRobert Watson } 843d91be41SRobert Watson } 853d91be41SRobert Watson 863d91be41SRobert Watson static void 873d91be41SRobert Watson addr_to_string(struct sockaddr_storage *ss, char *buffer, int buflen) 883d91be41SRobert Watson { 893d91be41SRobert Watson char buffer2[INET6_ADDRSTRLEN]; 903d91be41SRobert Watson struct sockaddr_in6 *sin6; 913d91be41SRobert Watson struct sockaddr_in *sin; 923d91be41SRobert Watson struct sockaddr_un *sun; 933d91be41SRobert Watson 943d91be41SRobert Watson switch (ss->ss_family) { 953d91be41SRobert Watson case AF_LOCAL: 963d91be41SRobert Watson sun = (struct sockaddr_un *)ss; 973d91be41SRobert Watson if (strlen(sun->sun_path) == 0) 983d91be41SRobert Watson strlcpy(buffer, "-", buflen); 993d91be41SRobert Watson else 1003d91be41SRobert Watson strlcpy(buffer, sun->sun_path, buflen); 1013d91be41SRobert Watson break; 1023d91be41SRobert Watson 1033d91be41SRobert Watson case AF_INET: 1043d91be41SRobert Watson sin = (struct sockaddr_in *)ss; 1053d91be41SRobert Watson snprintf(buffer, buflen, "%s:%d", inet_ntoa(sin->sin_addr), 1063d91be41SRobert Watson ntohs(sin->sin_port)); 1073d91be41SRobert Watson break; 1083d91be41SRobert Watson 1093d91be41SRobert Watson case AF_INET6: 1103d91be41SRobert Watson sin6 = (struct sockaddr_in6 *)ss; 1113d91be41SRobert Watson if (inet_ntop(AF_INET6, &sin6->sin6_addr, buffer2, 1123d91be41SRobert Watson sizeof(buffer2)) != NULL) 1133d91be41SRobert Watson snprintf(buffer, buflen, "%s.%d", buffer2, 1143d91be41SRobert Watson ntohs(sin6->sin6_port)); 1153d91be41SRobert Watson else 1163d91be41SRobert Watson strlcpy(buffer, "-", sizeof(buffer)); 1173d91be41SRobert Watson break; 1183d91be41SRobert Watson 1193d91be41SRobert Watson default: 1203d91be41SRobert Watson strlcpy(buffer, "", buflen); 1213d91be41SRobert Watson break; 1223d91be41SRobert Watson } 1233d91be41SRobert Watson } 1243d91be41SRobert Watson 1253d91be41SRobert Watson static void 1263d91be41SRobert Watson print_address(struct sockaddr_storage *ss) 1273d91be41SRobert Watson { 1283d91be41SRobert Watson char addr[PATH_MAX]; 1293d91be41SRobert Watson 1303d91be41SRobert Watson addr_to_string(ss, addr, sizeof(addr)); 1315a246d29SRobert Watson printf("%s", addr); 1323d91be41SRobert Watson } 1333d91be41SRobert Watson 1343d91be41SRobert Watson void 1353d91be41SRobert Watson procstat_files(pid_t pid, struct kinfo_proc *kipp) 1363d91be41SRobert Watson { 1373d91be41SRobert Watson struct kinfo_file *freep, *kif; 13843151ee6SPeter Wemm int i, cnt; 1393d91be41SRobert Watson const char *str; 1403d91be41SRobert Watson 1413d91be41SRobert Watson if (!hflag) 142f2805949SJoe Marcus Clarke printf("%5s %-16s %4s %1s %1s %-8s %3s %7s %-3s %-12s\n", 1435a246d29SRobert Watson "PID", "COMM", "FD", "T", "V", "FLAGS", "REF", "OFFSET", 1445a246d29SRobert Watson "PRO", "NAME"); 1453d91be41SRobert Watson 14643151ee6SPeter Wemm freep = kinfo_getfile(pid, &cnt); 14708afefa8SJoe Marcus Clarke if (freep == NULL) 14808afefa8SJoe Marcus Clarke return; 14943151ee6SPeter Wemm for (i = 0; i < cnt; i++) { 15043151ee6SPeter Wemm kif = &freep[i]; 1513d91be41SRobert Watson 1523d91be41SRobert Watson printf("%5d ", pid); 1535a246d29SRobert Watson printf("%-16s ", kipp->ki_comm); 154f2805949SJoe Marcus Clarke switch (kif->kf_fd) { 155f2805949SJoe Marcus Clarke case KF_FD_TYPE_CWD: 156f2805949SJoe Marcus Clarke printf(" cwd "); 157f2805949SJoe Marcus Clarke break; 158f2805949SJoe Marcus Clarke 159f2805949SJoe Marcus Clarke case KF_FD_TYPE_ROOT: 160f2805949SJoe Marcus Clarke printf("root "); 161f2805949SJoe Marcus Clarke break; 162f2805949SJoe Marcus Clarke 163f2805949SJoe Marcus Clarke case KF_FD_TYPE_JAIL: 164f2805949SJoe Marcus Clarke printf("jail "); 165f2805949SJoe Marcus Clarke break; 166f2805949SJoe Marcus Clarke 167f2805949SJoe Marcus Clarke default: 168f2805949SJoe Marcus Clarke printf("%4d ", kif->kf_fd); 169f2805949SJoe Marcus Clarke break; 170f2805949SJoe Marcus Clarke } 1713d91be41SRobert Watson switch (kif->kf_type) { 1723d91be41SRobert Watson case KF_TYPE_VNODE: 1733d91be41SRobert Watson str = "v"; 1743d91be41SRobert Watson break; 1753d91be41SRobert Watson 1763d91be41SRobert Watson case KF_TYPE_SOCKET: 1773d91be41SRobert Watson str = "s"; 1783d91be41SRobert Watson break; 1793d91be41SRobert Watson 1803d91be41SRobert Watson case KF_TYPE_PIPE: 1813d91be41SRobert Watson str = "p"; 1823d91be41SRobert Watson break; 1833d91be41SRobert Watson 1843d91be41SRobert Watson case KF_TYPE_FIFO: 1853d91be41SRobert Watson str = "f"; 1863d91be41SRobert Watson break; 1873d91be41SRobert Watson 1883d91be41SRobert Watson case KF_TYPE_KQUEUE: 1893d91be41SRobert Watson str = "k"; 1903d91be41SRobert Watson break; 1913d91be41SRobert Watson 1923d91be41SRobert Watson case KF_TYPE_CRYPTO: 1933d91be41SRobert Watson str = "c"; 1943d91be41SRobert Watson break; 1953d91be41SRobert Watson 1963d91be41SRobert Watson case KF_TYPE_MQUEUE: 1973d91be41SRobert Watson str = "m"; 1983d91be41SRobert Watson break; 1993d91be41SRobert Watson 20087cb56f6SRobert Watson case KF_TYPE_SHM: 20187cb56f6SRobert Watson str = "h"; 20287cb56f6SRobert Watson break; 20387cb56f6SRobert Watson 204bc093719SEd Schouten case KF_TYPE_PTS: 205bc093719SEd Schouten str = "t"; 206bc093719SEd Schouten break; 207bc093719SEd Schouten 2086bc1e9cdSJohn Baldwin case KF_TYPE_SEM: 2096bc1e9cdSJohn Baldwin str = "e"; 2106bc1e9cdSJohn Baldwin break; 2116bc1e9cdSJohn Baldwin 2123d91be41SRobert Watson case KF_TYPE_NONE: 2133d91be41SRobert Watson case KF_TYPE_UNKNOWN: 2143d91be41SRobert Watson default: 2153d91be41SRobert Watson str = "?"; 2163d91be41SRobert Watson break; 2173d91be41SRobert Watson } 2183d91be41SRobert Watson printf("%1s ", str); 2193d91be41SRobert Watson str = "-"; 2203d91be41SRobert Watson if (kif->kf_type == KF_TYPE_VNODE) { 2213d91be41SRobert Watson switch (kif->kf_vnode_type) { 2223d91be41SRobert Watson case KF_VTYPE_VREG: 2233d91be41SRobert Watson str = "r"; 2243d91be41SRobert Watson break; 2253d91be41SRobert Watson 2263d91be41SRobert Watson case KF_VTYPE_VDIR: 2273d91be41SRobert Watson str = "d"; 2283d91be41SRobert Watson break; 2293d91be41SRobert Watson 2303d91be41SRobert Watson case KF_VTYPE_VBLK: 2313d91be41SRobert Watson str = "b"; 2323d91be41SRobert Watson break; 2333d91be41SRobert Watson 2343d91be41SRobert Watson case KF_VTYPE_VCHR: 2353d91be41SRobert Watson str = "c"; 2363d91be41SRobert Watson break; 2373d91be41SRobert Watson 2383d91be41SRobert Watson case KF_VTYPE_VLNK: 2393d91be41SRobert Watson str = "l"; 2403d91be41SRobert Watson break; 2413d91be41SRobert Watson 2423d91be41SRobert Watson case KF_VTYPE_VSOCK: 2433d91be41SRobert Watson str = "s"; 2443d91be41SRobert Watson break; 2453d91be41SRobert Watson 2463d91be41SRobert Watson case KF_VTYPE_VFIFO: 2473d91be41SRobert Watson str = "f"; 2483d91be41SRobert Watson break; 2493d91be41SRobert Watson 2503d91be41SRobert Watson case KF_VTYPE_VBAD: 2513d91be41SRobert Watson str = "x"; 2523d91be41SRobert Watson break; 2533d91be41SRobert Watson 2543d91be41SRobert Watson case KF_VTYPE_VNON: 2553d91be41SRobert Watson case KF_VTYPE_UNKNOWN: 2563d91be41SRobert Watson default: 2573d91be41SRobert Watson str = "?"; 2583d91be41SRobert Watson break; 2593d91be41SRobert Watson } 2603d91be41SRobert Watson } 2613d91be41SRobert Watson printf("%1s ", str); 2623d91be41SRobert Watson printf("%s", kif->kf_flags & KF_FLAG_READ ? "r" : "-"); 2633d91be41SRobert Watson printf("%s", kif->kf_flags & KF_FLAG_WRITE ? "w" : "-"); 2643d91be41SRobert Watson printf("%s", kif->kf_flags & KF_FLAG_APPEND ? "a" : "-"); 2653d91be41SRobert Watson printf("%s", kif->kf_flags & KF_FLAG_ASYNC ? "s" : "-"); 2663d91be41SRobert Watson printf("%s", kif->kf_flags & KF_FLAG_FSYNC ? "f" : "-"); 2673d91be41SRobert Watson printf("%s", kif->kf_flags & KF_FLAG_NONBLOCK ? "n" : "-"); 2683d91be41SRobert Watson printf("%s", kif->kf_flags & KF_FLAG_DIRECT ? "d" : "-"); 2693d91be41SRobert Watson printf("%s ", kif->kf_flags & KF_FLAG_HASLOCK ? "l" : "-"); 270f2805949SJoe Marcus Clarke if (kif->kf_ref_count > -1) 2713d91be41SRobert Watson printf("%3d ", kif->kf_ref_count); 272f2805949SJoe Marcus Clarke else 273f2805949SJoe Marcus Clarke printf("%3c ", '-'); 274f2805949SJoe Marcus Clarke if (kif->kf_offset > -1) 2753d91be41SRobert Watson printf("%7jd ", (intmax_t)kif->kf_offset); 276f2805949SJoe Marcus Clarke else 277f2805949SJoe Marcus Clarke printf("%7c ", '-'); 2783d91be41SRobert Watson 2793d91be41SRobert Watson switch (kif->kf_type) { 2803d91be41SRobert Watson case KF_TYPE_VNODE: 2813d91be41SRobert Watson case KF_TYPE_FIFO: 282bc093719SEd Schouten case KF_TYPE_PTS: 2835a246d29SRobert Watson printf("%-3s ", "-"); 2845a246d29SRobert Watson printf("%-18s", kif->kf_path); 2853d91be41SRobert Watson break; 2863d91be41SRobert Watson 2873d91be41SRobert Watson case KF_TYPE_SOCKET: 2885a246d29SRobert Watson printf("%-3s ", 2893d91be41SRobert Watson protocol_to_string(kif->kf_sock_domain, 2903d91be41SRobert Watson kif->kf_sock_type, kif->kf_sock_protocol)); 2913d91be41SRobert Watson /* 2923d91be41SRobert Watson * While generally we like to print two addresses, 2933d91be41SRobert Watson * local and peer, for sockets, it turns out to be 2943d91be41SRobert Watson * more useful to print the first non-nul address for 2953d91be41SRobert Watson * local sockets, as typically they aren't bound and 2963d91be41SRobert Watson * connected, and the path strings can get long. 2973d91be41SRobert Watson */ 2983d91be41SRobert Watson if (kif->kf_sock_domain == AF_LOCAL) { 2993d91be41SRobert Watson struct sockaddr_un *sun = 3003d91be41SRobert Watson (struct sockaddr_un *)&kif->kf_sa_local; 3013d91be41SRobert Watson 3023d91be41SRobert Watson if (sun->sun_path[0] != 0) 3033d91be41SRobert Watson print_address(&kif->kf_sa_local); 3043d91be41SRobert Watson else 3053d91be41SRobert Watson print_address(&kif->kf_sa_peer); 3063d91be41SRobert Watson } else { 3073d91be41SRobert Watson print_address(&kif->kf_sa_local); 3083d91be41SRobert Watson printf(" "); 3093d91be41SRobert Watson print_address(&kif->kf_sa_peer); 3103d91be41SRobert Watson } 3113d91be41SRobert Watson break; 3123d91be41SRobert Watson 3133d91be41SRobert Watson default: 3145a246d29SRobert Watson printf("%-3s ", "-"); 3155a246d29SRobert Watson printf("%-18s", "-"); 3163d91be41SRobert Watson } 3173d91be41SRobert Watson 3183d91be41SRobert Watson printf("\n"); 3193d91be41SRobert Watson } 3203d91be41SRobert Watson free(freep); 3213d91be41SRobert Watson } 322