1*a984a0c3Sguenther /* $OpenBSD: ktrstruct.c,v 1.32 2024/07/26 19:16:31 guenther Exp $ */ 2dbedfdbcSguenther 3dbedfdbcSguenther /*- 4dbedfdbcSguenther * Copyright (c) 1988, 1993 5dbedfdbcSguenther * The Regents of the University of California. All rights reserved. 6dbedfdbcSguenther * 7dbedfdbcSguenther * Redistribution and use in source and binary forms, with or without 8dbedfdbcSguenther * modification, are permitted provided that the following conditions 9dbedfdbcSguenther * are met: 10dbedfdbcSguenther * 1. Redistributions of source code must retain the above copyright 11dbedfdbcSguenther * notice, this list of conditions and the following disclaimer. 12dbedfdbcSguenther * 2. Redistributions in binary form must reproduce the above copyright 13dbedfdbcSguenther * notice, this list of conditions and the following disclaimer in the 14dbedfdbcSguenther * documentation and/or other materials provided with the distribution. 15dbedfdbcSguenther * 3. Neither the name of the University nor the names of its contributors 16dbedfdbcSguenther * may be used to endorse or promote products derived from this software 17dbedfdbcSguenther * without specific prior written permission. 18dbedfdbcSguenther * 19dbedfdbcSguenther * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20dbedfdbcSguenther * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21dbedfdbcSguenther * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22dbedfdbcSguenther * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23dbedfdbcSguenther * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24dbedfdbcSguenther * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25dbedfdbcSguenther * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26dbedfdbcSguenther * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27dbedfdbcSguenther * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28dbedfdbcSguenther * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29dbedfdbcSguenther * SUCH DAMAGE. 30dbedfdbcSguenther */ 31dbedfdbcSguenther 32dbedfdbcSguenther #include <sys/types.h> 33dbedfdbcSguenther #include <sys/resource.h> 34dbedfdbcSguenther #include <sys/socket.h> 3564a15077Sguenther #include <sys/select.h> 36dbedfdbcSguenther #include <sys/stat.h> 37dbedfdbcSguenther #include <sys/time.h> 381a72e1b0Stedu #include <sys/event.h> 39dbedfdbcSguenther #include <sys/un.h> 405c402730Santon #include <sys/fcntl.h> 411338505aSguenther #include <ufs/ufs/quota.h> 42dbedfdbcSguenther #include <netinet/in.h> 43dbedfdbcSguenther #include <arpa/inet.h> 44dbedfdbcSguenther 45dbedfdbcSguenther #include <ctype.h> 46dbedfdbcSguenther #include <err.h> 47dbedfdbcSguenther #include <limits.h> 487003901fSguenther #include <netdb.h> 49dbedfdbcSguenther #include <poll.h> 50dbedfdbcSguenther #include <signal.h> 5154bca4b0Sguenther #include <stddef.h> 52dbedfdbcSguenther #include <stdio.h> 53dbedfdbcSguenther #include <stdlib.h> 54dbedfdbcSguenther #include <stdint.h> 55dbedfdbcSguenther #include <string.h> 56dbedfdbcSguenther #include <grp.h> 57dbedfdbcSguenther #include <pwd.h> 58dbedfdbcSguenther #include <unistd.h> 5980bc2255Sguenther #include <vis.h> 60dbedfdbcSguenther 61dbedfdbcSguenther #include "kdump.h" 62dbedfdbcSguenther #include "kdump_subr.h" 63dbedfdbcSguenther 64dbedfdbcSguenther #define TIME_FORMAT "%b %e %T %Y" 65dbedfdbcSguenther 66dbedfdbcSguenther static void 67dbedfdbcSguenther ktrsockaddr(struct sockaddr *sa) 68dbedfdbcSguenther { 69dbedfdbcSguenther /* 7080bc2255Sguenther * TODO: Support additional address families 7180bc2255Sguenther * #include <netmpls/mpls.h> 7280bc2255Sguenther * struct sockaddr_mpls *mpls; 73dbedfdbcSguenther */ 74dbedfdbcSguenther 75dbedfdbcSguenther /* 76dbedfdbcSguenther * note: ktrstruct() has already verified that sa points to a 77dbedfdbcSguenther * buffer at least sizeof(struct sockaddr) bytes long and exactly 78dbedfdbcSguenther * sa->sa_len bytes long. 79dbedfdbcSguenther */ 80dbedfdbcSguenther printf("struct sockaddr { "); 81dbedfdbcSguenther sockfamilyname(sa->sa_family); 82dbedfdbcSguenther printf(", "); 83dbedfdbcSguenther 84dbedfdbcSguenther #define check_sockaddr_len(n) \ 85dbedfdbcSguenther if (sa_##n->s##n##_len < sizeof(struct sockaddr_##n)) { \ 86dbedfdbcSguenther printf("invalid"); \ 87dbedfdbcSguenther break; \ 88dbedfdbcSguenther } 89dbedfdbcSguenther 90dbedfdbcSguenther switch(sa->sa_family) { 91dbedfdbcSguenther case AF_INET: { 92dbedfdbcSguenther struct sockaddr_in *sa_in; 939ec514d4Sotto char addr[INET_ADDRSTRLEN]; 94dbedfdbcSguenther 95dbedfdbcSguenther sa_in = (struct sockaddr_in *)sa; 96dbedfdbcSguenther check_sockaddr_len(in); 97dbedfdbcSguenther inet_ntop(AF_INET, &sa_in->sin_addr, addr, sizeof addr); 98dbedfdbcSguenther printf("%s:%u", addr, ntohs(sa_in->sin_port)); 99dbedfdbcSguenther break; 100dbedfdbcSguenther } 101dbedfdbcSguenther case AF_INET6: { 102dbedfdbcSguenther struct sockaddr_in6 *sa_in6; 1039ec514d4Sotto char addr[INET6_ADDRSTRLEN], scope[12] = { 0 }; 104dbedfdbcSguenther 105dbedfdbcSguenther sa_in6 = (struct sockaddr_in6 *)sa; 106dbedfdbcSguenther check_sockaddr_len(in6); 107dbedfdbcSguenther inet_ntop(AF_INET6, &sa_in6->sin6_addr, addr, sizeof addr); 1089ec514d4Sotto if (sa_in6->sin6_scope_id) 1099ec514d4Sotto snprintf(scope, sizeof(scope), "%%%u", 1109ec514d4Sotto sa_in6->sin6_scope_id); 1119ec514d4Sotto printf("[%s%s]:%u", addr, scope, htons(sa_in6->sin6_port)); 112dbedfdbcSguenther break; 113dbedfdbcSguenther } 114dbedfdbcSguenther case AF_UNIX: { 115dbedfdbcSguenther struct sockaddr_un *sa_un; 11680bc2255Sguenther char path[4 * sizeof(sa_un->sun_path) + 1]; 11780bc2255Sguenther size_t len; 118dbedfdbcSguenther 119dbedfdbcSguenther sa_un = (struct sockaddr_un *)sa; 12080bc2255Sguenther len = sa_un->sun_len; 12180bc2255Sguenther if (len <= offsetof(struct sockaddr_un, sun_path)) { 122dbedfdbcSguenther printf("invalid"); 123dbedfdbcSguenther break; 124dbedfdbcSguenther } 12580bc2255Sguenther len -= offsetof(struct sockaddr_un, sun_path); 12680bc2255Sguenther if (len > sizeof(sa_un->sun_path)) { 12780bc2255Sguenther printf("too long"); 12880bc2255Sguenther break; 12980bc2255Sguenther } 13080bc2255Sguenther /* format, stopping at first NUL */ 13180bc2255Sguenther len = strnlen(sa_un->sun_path, len); 13280bc2255Sguenther strvisx(path, sa_un->sun_path, len, 13380bc2255Sguenther VIS_CSTYLE | VIS_DQ | VIS_TAB | VIS_NL); 13480bc2255Sguenther printf("\"%s\"", path); 135dbedfdbcSguenther break; 136dbedfdbcSguenther } 137dbedfdbcSguenther default: 138dbedfdbcSguenther printf("unknown address family"); 139dbedfdbcSguenther } 140dbedfdbcSguenther printf(" }\n"); 141dbedfdbcSguenther } 142dbedfdbcSguenther 143dbedfdbcSguenther static void 144154ec7daSguenther print_time(time_t t, int relative, int have_subsec) 145dbedfdbcSguenther { 146dbedfdbcSguenther char timestr[PATH_MAX + 4]; 147dbedfdbcSguenther struct tm *tm; 148dbedfdbcSguenther 149154ec7daSguenther if (t < 0 && have_subsec) { 150154ec7daSguenther /* negative times with non-zero subsecs require care */ 151154ec7daSguenther printf("-%jd", -(intmax_t)(t + 1)); 152154ec7daSguenther } else 153dbedfdbcSguenther printf("%jd", (intmax_t)t); 154154ec7daSguenther 1552f33c23dStedu /* 1970s times are probably relative */ 1562f33c23dStedu if (!relative && t > (10 * 365 * 24 * 3600)) { 157dbedfdbcSguenther tm = localtime(&t); 15840f07bdcSjsg if (tm != NULL) { 15940f07bdcSjsg (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, 16040f07bdcSjsg tm); 161154ec7daSguenther printf("<\"%s\">", timestr); 162dbedfdbcSguenther } 163dbedfdbcSguenther } 16440f07bdcSjsg } 165dbedfdbcSguenther 166dbedfdbcSguenther static void 167dbedfdbcSguenther print_timespec(const struct timespec *tsp, int relative) 168dbedfdbcSguenther { 169911117f3Sguenther if (tsp->tv_nsec == UTIME_NOW) 170911117f3Sguenther printf("UTIME_NOW"); 171911117f3Sguenther else if (tsp->tv_nsec == UTIME_OMIT) 172911117f3Sguenther printf("UTIME_OMIT"); 173154ec7daSguenther else { 174154ec7daSguenther print_time(tsp->tv_sec, relative, tsp->tv_nsec); 175dbedfdbcSguenther if (tsp->tv_nsec != 0) 176154ec7daSguenther printf(".%09ld", tsp->tv_sec >= 0 ? tsp->tv_nsec : 177154ec7daSguenther 1000000000 - tsp->tv_nsec); 178154ec7daSguenther } 179154ec7daSguenther } 180154ec7daSguenther 181154ec7daSguenther void 182154ec7daSguenther uidname(int uid) 183154ec7daSguenther { 184154ec7daSguenther const char *name; 185154ec7daSguenther 186154ec7daSguenther if (uid == -1) 187154ec7daSguenther printf("-1"); 188154ec7daSguenther else { 189154ec7daSguenther printf("%u<", (unsigned)uid); 190154ec7daSguenther if (uid > UID_MAX || (name = user_from_uid(uid, 1)) == NULL) 191154ec7daSguenther printf("unknown>"); 192154ec7daSguenther else 193154ec7daSguenther printf("\"%s\">", name); 194154ec7daSguenther } 195154ec7daSguenther } 196154ec7daSguenther 197154ec7daSguenther void 198154ec7daSguenther gidname(int gid) 199154ec7daSguenther { 200154ec7daSguenther const char *name; 201154ec7daSguenther 202154ec7daSguenther if (gid == -1) 203154ec7daSguenther printf("-1"); 204154ec7daSguenther else { 205154ec7daSguenther printf("%u<", (unsigned)gid); 206154ec7daSguenther if (gid > GID_MAX || (name = group_from_gid(gid, 1)) == NULL) 207154ec7daSguenther printf("unknown>"); 208154ec7daSguenther else 209154ec7daSguenther printf("\"%s\">", name); 210dbedfdbcSguenther } 211911117f3Sguenther } 212dbedfdbcSguenther 213dbedfdbcSguenther static void 214dbedfdbcSguenther ktrstat(const struct stat *statp) 215dbedfdbcSguenther { 216dbedfdbcSguenther char mode[12]; 217dbedfdbcSguenther 218dbedfdbcSguenther /* 219dbedfdbcSguenther * note: ktrstruct() has already verified that statp points to a 220dbedfdbcSguenther * buffer exactly sizeof(struct stat) bytes long. 221dbedfdbcSguenther */ 222dbedfdbcSguenther printf("struct stat { "); 223dbedfdbcSguenther strmode(statp->st_mode, mode); 224154ec7daSguenther printf("dev=%d, ino=%llu, mode=%s, nlink=%u, uid=", 225dbedfdbcSguenther statp->st_dev, (unsigned long long)statp->st_ino, 226dbedfdbcSguenther mode, statp->st_nlink); 227154ec7daSguenther uidname(statp->st_uid); 228154ec7daSguenther printf(", gid="); 229154ec7daSguenther gidname(statp->st_gid); 230154ec7daSguenther printf(", rdev=%d, ", statp->st_rdev); 231dbedfdbcSguenther printf("atime="); 232dbedfdbcSguenther print_timespec(&statp->st_atim, 0); 233dbedfdbcSguenther printf(", mtime="); 234dbedfdbcSguenther print_timespec(&statp->st_mtim, 0); 235dbedfdbcSguenther printf(", ctime="); 236dbedfdbcSguenther print_timespec(&statp->st_ctim, 0); 2374b9a7a17Skrw printf(", size=%lld, blocks=%lld, blksize=%d, flags=0x%x, gen=0x%x", 238dbedfdbcSguenther statp->st_size, statp->st_blocks, statp->st_blksize, 239dbedfdbcSguenther statp->st_flags, statp->st_gen); 240dbedfdbcSguenther printf(" }\n"); 241dbedfdbcSguenther } 242dbedfdbcSguenther 243dbedfdbcSguenther static void 244dbedfdbcSguenther ktrtimespec(const struct timespec *tsp, int relative) 245dbedfdbcSguenther { 246dbedfdbcSguenther printf("struct timespec { "); 247dbedfdbcSguenther print_timespec(tsp, relative); 248dbedfdbcSguenther printf(" }\n"); 249dbedfdbcSguenther } 250dbedfdbcSguenther 251dbedfdbcSguenther static void 2527f86807eSguenther print_timeval(const struct timeval *tvp, int relative) 253dbedfdbcSguenther { 254154ec7daSguenther print_time(tvp->tv_sec, relative, tvp->tv_usec); 255dbedfdbcSguenther if (tvp->tv_usec != 0) 256154ec7daSguenther printf(".%06ld", tvp->tv_sec >= 0 ? tvp->tv_usec : 257154ec7daSguenther 1000000 - tvp->tv_usec); 2580bcd1a52Sguenther } 2597f86807eSguenther 2607f86807eSguenther static void 2617f86807eSguenther ktrtimeval(const struct timeval *tvp, int relative) 2627f86807eSguenther { 2637f86807eSguenther printf("struct timeval { "); 2647f86807eSguenther print_timeval(tvp, relative); 265dbedfdbcSguenther printf(" }\n"); 266dbedfdbcSguenther } 267dbedfdbcSguenther 268dbedfdbcSguenther static void 269*a984a0c3Sguenther ktritimerval(const struct itimerval *itvp) 270*a984a0c3Sguenther { 271*a984a0c3Sguenther printf("struct itimerval { value="); 272*a984a0c3Sguenther print_timeval(&itvp->it_value, 0); 273*a984a0c3Sguenther if (timerisset(&itvp->it_interval)) { 274*a984a0c3Sguenther printf(", interval="); 275*a984a0c3Sguenther print_timeval(&itvp->it_interval, 1); 276*a984a0c3Sguenther } 277*a984a0c3Sguenther printf(" }\n"); 278*a984a0c3Sguenther } 279*a984a0c3Sguenther 280*a984a0c3Sguenther static void 281dbedfdbcSguenther ktrsigaction(const struct sigaction *sa) 282dbedfdbcSguenther { 283dbedfdbcSguenther /* 284dbedfdbcSguenther * note: ktrstruct() has already verified that sa points to a 285dbedfdbcSguenther * buffer exactly sizeof(struct sigaction) bytes long. 286dbedfdbcSguenther */ 2871357eed1Sguenther /* 2881357eed1Sguenther * Fuck! Comparison of function pointers on hppa assumes you can 2891357eed1Sguenther * dereference them if they're plabels! Cast everything to void * 2901357eed1Sguenther * to suppress that extra logic; sorry folks, the address we report 2911357eed1Sguenther * here might not match what you see in your executable... 2921357eed1Sguenther */ 293dbedfdbcSguenther printf("struct sigaction { "); 2941357eed1Sguenther if ((void *)sa->sa_handler == (void *)SIG_DFL) 295dbedfdbcSguenther printf("handler=SIG_DFL"); 2961357eed1Sguenther else if ((void *)sa->sa_handler == (void *)SIG_IGN) 297dbedfdbcSguenther printf("handler=SIG_IGN"); 298dbedfdbcSguenther else if (sa->sa_flags & SA_SIGINFO) 299dbedfdbcSguenther printf("sigaction=%p", (void *)sa->sa_sigaction); 300dbedfdbcSguenther else 301dbedfdbcSguenther printf("handler=%p", (void *)sa->sa_handler); 302dbedfdbcSguenther printf(", mask="); 303dbedfdbcSguenther sigset(sa->sa_mask); 304dbedfdbcSguenther printf(", flags="); 305dbedfdbcSguenther sigactionflagname(sa->sa_flags); 306dbedfdbcSguenther printf(" }\n"); 307dbedfdbcSguenther } 308dbedfdbcSguenther 309dbedfdbcSguenther static void 310dbedfdbcSguenther print_rlim(rlim_t lim) 311dbedfdbcSguenther { 312dbedfdbcSguenther if (lim == RLIM_INFINITY) 313dbedfdbcSguenther printf("infinite"); 314dbedfdbcSguenther else 315dbedfdbcSguenther printf("%llu", (unsigned long long)lim); 316dbedfdbcSguenther } 317dbedfdbcSguenther 318dbedfdbcSguenther static void 319dbedfdbcSguenther ktrrlimit(const struct rlimit *limp) 320dbedfdbcSguenther { 321dbedfdbcSguenther printf("struct rlimit { "); 322dbedfdbcSguenther printf("cur="); 323dbedfdbcSguenther print_rlim(limp->rlim_cur); 324dbedfdbcSguenther printf(", max="); 325dbedfdbcSguenther print_rlim(limp->rlim_max); 326dbedfdbcSguenther printf(" }\n"); 327dbedfdbcSguenther } 328dbedfdbcSguenther 329dbedfdbcSguenther static void 330dbedfdbcSguenther ktrtfork(const struct __tfork *tf) 331dbedfdbcSguenther { 332dbedfdbcSguenther printf("struct __tfork { tcb=%p, tid=%p, stack=%p }\n", 333dbedfdbcSguenther tf->tf_tcb, (void *)tf->tf_tid, tf->tf_stack); 334dbedfdbcSguenther } 335dbedfdbcSguenther 336dbedfdbcSguenther static void 337ee71c3a5Sguenther ktrfds(const char *data, size_t count) 338ee71c3a5Sguenther { 339ee71c3a5Sguenther size_t i; 340ee71c3a5Sguenther int fd; 341ee71c3a5Sguenther 3425f257f27Sotto printf("int"); 3435f257f27Sotto if (count > 1) 3445f257f27Sotto printf(" [%zu] { ", count); 3455f257f27Sotto for (i = 0; i < count; i++) { 346ee71c3a5Sguenther memcpy(&fd, &data[i * sizeof(fd)], sizeof(fd)); 3475f257f27Sotto printf("%d%s", fd, i < count - 1 ? ", " : ""); 348ee71c3a5Sguenther } 3495f257f27Sotto if (count > 1) 3505f257f27Sotto printf(" }"); 3515f257f27Sotto printf("\n"); 352ee71c3a5Sguenther } 353ee71c3a5Sguenther 354ee71c3a5Sguenther static void 355aaf6c75dSguenther ktrfdset(struct fd_set *fds, int len) 356dbedfdbcSguenther { 357dbedfdbcSguenther int nfds, i, start = -1; 358dbedfdbcSguenther char sep = ' '; 359dbedfdbcSguenther 360dbedfdbcSguenther nfds = len * NBBY; 361dbedfdbcSguenther printf("struct fd_set {"); 362dbedfdbcSguenther for (i = 0; i <= nfds; i++) 363dbedfdbcSguenther if (i != nfds && FD_ISSET(i, fds)) { 364dbedfdbcSguenther if (start == -1) 365dbedfdbcSguenther start = i; 366dbedfdbcSguenther } else if (start != -1) { 367dbedfdbcSguenther putchar(sep); 368dbedfdbcSguenther if (start == i - 1) 369dbedfdbcSguenther printf("%d", start); 370dbedfdbcSguenther else if (start == i - 2) 371dbedfdbcSguenther printf("%d,%d", start, i - 1); 372dbedfdbcSguenther else 373dbedfdbcSguenther printf("%d-%d", start, i - 1); 374dbedfdbcSguenther sep = ','; 375dbedfdbcSguenther start = -1; 376dbedfdbcSguenther } 377dbedfdbcSguenther 378dbedfdbcSguenther printf(" }\n"); 379dbedfdbcSguenther } 380dbedfdbcSguenther 3817f86807eSguenther static void 3827f86807eSguenther ktrrusage(const struct rusage *rup) 3837f86807eSguenther { 3847f86807eSguenther printf("struct rusage { utime="); 3857f86807eSguenther print_timeval(&rup->ru_utime, 1); 3867f86807eSguenther printf(", stime="); 3877f86807eSguenther print_timeval(&rup->ru_stime, 1); 3887f86807eSguenther printf(", maxrss=%ld, ixrss=%ld, idrss=%ld, isrss=%ld," 3897f86807eSguenther " minflt=%ld, majflt=%ld, nswap=%ld, inblock=%ld," 3907f86807eSguenther " oublock=%ld, msgsnd=%ld, msgrcv=%ld, nsignals=%ld," 3917f86807eSguenther " nvcsw=%ld, nivcsw=%ld }\n", 3927f86807eSguenther rup->ru_maxrss, rup->ru_ixrss, rup->ru_idrss, rup->ru_isrss, 3937f86807eSguenther rup->ru_minflt, rup->ru_majflt, rup->ru_nswap, rup->ru_inblock, 3947f86807eSguenther rup->ru_oublock, rup->ru_msgsnd, rup->ru_msgrcv, rup->ru_nsignals, 3957f86807eSguenther rup->ru_nvcsw, rup->ru_nivcsw); 3967f86807eSguenther } 3977f86807eSguenther 3981338505aSguenther static void 3991338505aSguenther ktrquota(const struct dqblk *quota) 4001338505aSguenther { 4011338505aSguenther printf("struct dqblk { bhardlimit=%u, bsoftlimit=%u, curblocks=%u," 4021338505aSguenther " ihardlimit=%u, isoftlimit=%u, curinodes=%u, btime=", 4031338505aSguenther quota->dqb_bhardlimit, quota->dqb_bsoftlimit, 4041338505aSguenther quota->dqb_curblocks, quota->dqb_ihardlimit, 4051338505aSguenther quota->dqb_isoftlimit, quota->dqb_curinodes); 406154ec7daSguenther print_time(quota->dqb_btime, 0, 0); 4071338505aSguenther printf(", itime="); 408154ec7daSguenther print_time(quota->dqb_itime, 0, 0); 4091338505aSguenther printf(" }\n"); 4101338505aSguenther } 4111338505aSguenther 4127003901fSguenther static void 4137b0c308aSmbuhl ktrmmsghdr(const struct mmsghdr *mmsg) 4147b0c308aSmbuhl { 4157b0c308aSmbuhl printf("struct mmsghdr { msg_hdr = { name=%p, namelen=%u, " 4167b0c308aSmbuhl "iov=%p, iovlen=%u, control=%p, controllen=%u, flags=", 4177b0c308aSmbuhl mmsg->msg_hdr.msg_name, mmsg->msg_hdr.msg_namelen, 4187b0c308aSmbuhl mmsg->msg_hdr.msg_iov, mmsg->msg_hdr.msg_iovlen, 4197b0c308aSmbuhl mmsg->msg_hdr.msg_control, mmsg->msg_hdr.msg_controllen); 4207b0c308aSmbuhl sendrecvflagsname(mmsg->msg_hdr.msg_flags); 4217b0c308aSmbuhl printf(" }, msg_len = %u }\n", mmsg->msg_len); 4227b0c308aSmbuhl } 4237b0c308aSmbuhl 4247b0c308aSmbuhl static void 4257003901fSguenther ktrmsghdr(const struct msghdr *msg) 4267003901fSguenther { 4277003901fSguenther printf("struct msghdr { name=%p, namelen=%u, iov=%p, iovlen=%u," 4288449a441Sguenther " control=%p, controllen=%u, flags=", 4297003901fSguenther msg->msg_name, msg->msg_namelen, msg->msg_iov, msg->msg_iovlen, 4308449a441Sguenther msg->msg_control, msg->msg_controllen); 4318449a441Sguenther sendrecvflagsname(msg->msg_flags); 4328449a441Sguenther printf(" }\n"); 4337003901fSguenther } 4347003901fSguenther 4357003901fSguenther static void 4367003901fSguenther ktriovec(const char *data, int count) 4377003901fSguenther { 4387003901fSguenther struct iovec iov; 4397003901fSguenther int i; 4407003901fSguenther 4417003901fSguenther printf("struct iovec"); 4427003901fSguenther if (count > 1) 4437003901fSguenther printf(" [%d]", count); 4447003901fSguenther for (i = 0; i < count; i++) { 4457003901fSguenther memcpy(&iov, data, sizeof(iov)); 4467003901fSguenther data += sizeof(iov); 4477003901fSguenther printf(" { base=%p, len=%lu }", iov.iov_base, iov.iov_len); 4487003901fSguenther } 4497003901fSguenther printf("\n"); 4507003901fSguenther } 4517003901fSguenther 4527003901fSguenther static void 4531a72e1b0Stedu ktrevent(const char *data, int count) 4541a72e1b0Stedu { 4551a72e1b0Stedu struct kevent kev; 4561a72e1b0Stedu int i; 4571a72e1b0Stedu 4581a72e1b0Stedu printf("struct kevent"); 4591a72e1b0Stedu if (count > 1) 4601a72e1b0Stedu printf(" [%d]", count); 4611a72e1b0Stedu for (i = 0; i < count; i++) { 4621a72e1b0Stedu memcpy(&kev, data, sizeof(kev)); 4631a72e1b0Stedu data += sizeof(kev); 4648449a441Sguenther printf(" { ident=%lu, filter=", kev.ident); 4658449a441Sguenther evfiltername(kev.filter); 4668449a441Sguenther printf(", flags="); 4678449a441Sguenther evflagsname(kev.flags); 4688449a441Sguenther printf(", fflags="); 4698449a441Sguenther evfflagsname(kev.filter, kev.fflags); 4708449a441Sguenther printf(", data=%llu", kev.data); 4718449a441Sguenther if ((kev.flags & EV_ERROR) && fancy) { 4728449a441Sguenther printf("<\"%s\">", strerror(kev.data)); 47329174d74Stedu } 4748449a441Sguenther printf(", udata=%p }", kev.udata); 4751a72e1b0Stedu } 4761a72e1b0Stedu printf("\n"); 4771a72e1b0Stedu } 4781a72e1b0Stedu 4791a72e1b0Stedu static void 480cd632112Sderaadt ktrpollfd(const char *data, int count) 481cd632112Sderaadt { 482cd632112Sderaadt struct pollfd pfd; 483cd632112Sderaadt int i; 484cd632112Sderaadt 485cd632112Sderaadt printf("struct pollfd"); 486cd632112Sderaadt if (count > 1) 487cd632112Sderaadt printf(" [%d]", count); 488cd632112Sderaadt for (i = 0; i < count; i++) { 489cd632112Sderaadt memcpy(&pfd, data, sizeof(pfd)); 490cd632112Sderaadt data += sizeof(pfd); 491cd632112Sderaadt printf(" { fd=%d, events=", pfd.fd); 492cd632112Sderaadt pollfdeventname(pfd.events); 493cd632112Sderaadt printf(", revents="); 494cd632112Sderaadt pollfdeventname(pfd.revents); 495cd632112Sderaadt printf(" }"); 496cd632112Sderaadt } 497cd632112Sderaadt printf("\n"); 498cd632112Sderaadt } 499cd632112Sderaadt 500cd632112Sderaadt static void 5017003901fSguenther ktrcmsghdr(char *data, socklen_t len) 5027003901fSguenther { 5037003901fSguenther struct msghdr msg; 5047003901fSguenther struct cmsghdr *cmsg; 5057003901fSguenther int i, count, *fds; 5067003901fSguenther 5077003901fSguenther msg.msg_control = data; 5087003901fSguenther msg.msg_controllen = len; 5097003901fSguenther 5107003901fSguenther /* count the control messages */ 5117003901fSguenther count = 0; 5127003901fSguenther for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; 5137003901fSguenther cmsg = CMSG_NXTHDR(&msg, cmsg)) { 5147003901fSguenther count++; 5157003901fSguenther } 5167003901fSguenther 5177003901fSguenther printf("struct cmsghdr"); 5187003901fSguenther if (count > 1) 5197003901fSguenther printf(" [%d]", count); 5207003901fSguenther 5217003901fSguenther for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; 5227003901fSguenther cmsg = CMSG_NXTHDR(&msg, cmsg)) { 5237003901fSguenther printf(" { len=%u, level=", cmsg->cmsg_len); 5247003901fSguenther if (cmsg->cmsg_level == SOL_SOCKET) { 5257003901fSguenther printf("SOL_SOCKET, type="); 5267003901fSguenther switch (cmsg->cmsg_type) { 5277003901fSguenther case SCM_RIGHTS: 5287003901fSguenther printf("SCM_RIGHTS, data="); 5297003901fSguenther fds = (int *)CMSG_DATA(cmsg); 5307003901fSguenther for (i = 0; 5312ff740a6Sclaudio cmsg->cmsg_len > CMSG_LEN(sizeof(int) * i) 5322ff740a6Sclaudio && (char *)fds + (i + 1) * sizeof(int) <= 5332ff740a6Sclaudio data + len; 5347003901fSguenther i++) { 5357003901fSguenther printf("%s%d", i ? "," : "", fds[i]); 5367003901fSguenther } 5377003901fSguenther break; 5387003901fSguenther case SCM_TIMESTAMP: 5397003901fSguenther default: 5407003901fSguenther printf("%d", cmsg->cmsg_type); 5417003901fSguenther break; 5427003901fSguenther } 5437003901fSguenther } else { 5447003901fSguenther struct protoent *p = getprotobynumber(cmsg->cmsg_level); 5457003901fSguenther 5467003901fSguenther printf("%u<%s>, type=%d", cmsg->cmsg_level, 5477003901fSguenther p != NULL ? p->p_name : "unknown", cmsg->cmsg_type); 5487003901fSguenther } 5497003901fSguenther printf(" }"); 5507003901fSguenther } 5517003901fSguenther printf("\n"); 5527003901fSguenther } 5537003901fSguenther 5545c402730Santon static void 5555c402730Santon ktrflock(const struct flock *fl) 5565c402730Santon { 5575c402730Santon printf("struct flock { start=%lld, len=%lld, pid=%d, type=", 5585c402730Santon fl->l_start, fl->l_len, fl->l_pid); 5595c402730Santon flocktypename(fl->l_type); 5605c402730Santon printf(", whence="); 5615c402730Santon whencename(fl->l_whence); 5625c402730Santon printf(" }\n"); 5635c402730Santon } 5645c402730Santon 56579b24ea9Sguenther static void 56679b24ea9Sguenther ktrsiginfo(const siginfo_t *si) 56779b24ea9Sguenther { 56879b24ea9Sguenther printf("siginfo_t { "); 56979b24ea9Sguenther siginfo(si, 1); 57079b24ea9Sguenther printf(" }\n"); 57179b24ea9Sguenther } 57279b24ea9Sguenther 573dbedfdbcSguenther void 574dbedfdbcSguenther ktrstruct(char *buf, size_t buflen) 575dbedfdbcSguenther { 576dbedfdbcSguenther char *name, *data; 577dbedfdbcSguenther size_t namelen, datalen; 578dbedfdbcSguenther int i; 579dbedfdbcSguenther 580dbedfdbcSguenther for (name = buf, namelen = 0; namelen < buflen && name[namelen] != '\0'; 581dbedfdbcSguenther ++namelen) 582dbedfdbcSguenther /* nothing */; 583dbedfdbcSguenther if (namelen == buflen) 584dbedfdbcSguenther goto invalid; 585dbedfdbcSguenther if (name[namelen] != '\0') 586dbedfdbcSguenther goto invalid; 587dbedfdbcSguenther data = buf + namelen + 1; 588dbedfdbcSguenther datalen = buflen - namelen - 1; 5895f257f27Sotto 590dbedfdbcSguenther /* sanity check */ 591dbedfdbcSguenther for (i = 0; i < namelen; ++i) 592dbedfdbcSguenther if (!isalpha((unsigned char)name[i])) 593dbedfdbcSguenther goto invalid; 594dbedfdbcSguenther if (strcmp(name, "stat") == 0) { 595dbedfdbcSguenther struct stat sb; 596dbedfdbcSguenther 597dbedfdbcSguenther if (datalen != sizeof(struct stat)) 598dbedfdbcSguenther goto invalid; 599dbedfdbcSguenther memcpy(&sb, data, datalen); 600dbedfdbcSguenther ktrstat(&sb); 601dbedfdbcSguenther } else if (strcmp(name, "sockaddr") == 0) { 602dbedfdbcSguenther struct sockaddr_storage ss; 603dbedfdbcSguenther 604dbedfdbcSguenther if (datalen > sizeof(ss)) 605dbedfdbcSguenther goto invalid; 6065f257f27Sotto if (datalen < offsetof(struct sockaddr_storage, ss_len) + 6075f257f27Sotto sizeof(ss.ss_len)) 6085f257f27Sotto goto invalid; 609dbedfdbcSguenther memcpy(&ss, data, datalen); 610dbedfdbcSguenther if ((ss.ss_family != AF_UNIX && 611dbedfdbcSguenther datalen < sizeof(struct sockaddr)) || datalen != ss.ss_len) 612dbedfdbcSguenther goto invalid; 613dbedfdbcSguenther ktrsockaddr((struct sockaddr *)&ss); 614dbedfdbcSguenther } else if (strcmp(name, "abstimespec") == 0 || 615dbedfdbcSguenther strcmp(name, "reltimespec") == 0) { 616dbedfdbcSguenther struct timespec ts; 617dbedfdbcSguenther 618dbedfdbcSguenther if (datalen != sizeof(ts)) 619dbedfdbcSguenther goto invalid; 620dbedfdbcSguenther memcpy(&ts, data, datalen); 621dbedfdbcSguenther ktrtimespec(&ts, name[0] == 'r'); 622dbedfdbcSguenther } else if (strcmp(name, "abstimeval") == 0 || 623dbedfdbcSguenther strcmp(name, "reltimeval") == 0) { 624dbedfdbcSguenther struct timeval tv; 625dbedfdbcSguenther 626dbedfdbcSguenther if (datalen != sizeof(tv)) 627dbedfdbcSguenther goto invalid; 628dbedfdbcSguenther memcpy(&tv, data, datalen); 629dbedfdbcSguenther ktrtimeval(&tv, name[0] == 'r'); 630*a984a0c3Sguenther } else if (strcmp(name, "itimerval") == 0) { 631*a984a0c3Sguenther struct itimerval itv; 632*a984a0c3Sguenther 633*a984a0c3Sguenther if (datalen != sizeof(itv)) 634*a984a0c3Sguenther goto invalid; 635*a984a0c3Sguenther memcpy(&itv, data, datalen); 636*a984a0c3Sguenther ktritimerval(&itv); 637dbedfdbcSguenther } else if (strcmp(name, "sigaction") == 0) { 638dbedfdbcSguenther struct sigaction sa; 639dbedfdbcSguenther 640dbedfdbcSguenther if (datalen != sizeof(sa)) 641dbedfdbcSguenther goto invalid; 642dbedfdbcSguenther memcpy(&sa, data, datalen); 643dbedfdbcSguenther ktrsigaction(&sa); 644dbedfdbcSguenther } else if (strcmp(name, "rlimit") == 0) { 645dbedfdbcSguenther struct rlimit lim; 646dbedfdbcSguenther 647dbedfdbcSguenther if (datalen != sizeof(lim)) 648dbedfdbcSguenther goto invalid; 649dbedfdbcSguenther memcpy(&lim, data, datalen); 650dbedfdbcSguenther ktrrlimit(&lim); 6517f86807eSguenther } else if (strcmp(name, "rusage") == 0) { 6527f86807eSguenther struct rusage ru; 6537f86807eSguenther 6547f86807eSguenther if (datalen != sizeof(ru)) 6557f86807eSguenther goto invalid; 6567f86807eSguenther memcpy(&ru, data, datalen); 6577f86807eSguenther ktrrusage(&ru); 658dbedfdbcSguenther } else if (strcmp(name, "tfork") == 0) { 659dbedfdbcSguenther struct __tfork tf; 660dbedfdbcSguenther 661dbedfdbcSguenther if (datalen != sizeof(tf)) 662dbedfdbcSguenther goto invalid; 663dbedfdbcSguenther memcpy(&tf, data, datalen); 664dbedfdbcSguenther ktrtfork(&tf); 665ee71c3a5Sguenther } else if (strcmp(name, "fds") == 0) { 666ee71c3a5Sguenther if (datalen % sizeof(int)) 667ee71c3a5Sguenther goto invalid; 668ee71c3a5Sguenther ktrfds(data, datalen / sizeof(int)); 669dbedfdbcSguenther } else if (strcmp(name, "fdset") == 0) { 670dbedfdbcSguenther struct fd_set *fds; 6717003901fSguenther 672dbedfdbcSguenther if ((fds = malloc(datalen)) == NULL) 673dbedfdbcSguenther err(1, "malloc"); 674dbedfdbcSguenther memcpy(fds, data, datalen); 675dbedfdbcSguenther ktrfdset(fds, datalen); 676dbedfdbcSguenther free(fds); 6771338505aSguenther } else if (strcmp(name, "quota") == 0) { 6781338505aSguenther struct dqblk quota; 6791338505aSguenther 6801338505aSguenther if (datalen != sizeof(quota)) 6811338505aSguenther goto invalid; 6821338505aSguenther memcpy("a, data, datalen); 6831338505aSguenther ktrquota("a); 6847003901fSguenther } else if (strcmp(name, "msghdr") == 0) { 6857003901fSguenther struct msghdr msg; 6867003901fSguenther 6877003901fSguenther if (datalen != sizeof(msg)) 6887003901fSguenther goto invalid; 6897003901fSguenther memcpy(&msg, data, datalen); 6907003901fSguenther ktrmsghdr(&msg); 6917b0c308aSmbuhl } else if (strcmp(name, "mmsghdr") == 0) { 6927b0c308aSmbuhl struct mmsghdr mmsg; 6937b0c308aSmbuhl 6947b0c308aSmbuhl if (datalen != sizeof(mmsg)) 6957b0c308aSmbuhl goto invalid; 6967b0c308aSmbuhl memcpy(&mmsg, data, datalen); 6977b0c308aSmbuhl ktrmmsghdr(&mmsg); 6987003901fSguenther } else if (strcmp(name, "iovec") == 0) { 6997003901fSguenther if (datalen % sizeof(struct iovec)) 7007003901fSguenther goto invalid; 7017003901fSguenther ktriovec(data, datalen / sizeof(struct iovec)); 7021a72e1b0Stedu } else if (strcmp(name, "kevent") == 0) { 7031a72e1b0Stedu if (datalen % sizeof(struct kevent)) 7041a72e1b0Stedu goto invalid; 7051a72e1b0Stedu ktrevent(data, datalen / sizeof(struct kevent)); 706cd632112Sderaadt } else if (strcmp(name, "pollfd") == 0) { 707cd632112Sderaadt if (datalen % sizeof(struct pollfd)) 708cd632112Sderaadt goto invalid; 709cd632112Sderaadt ktrpollfd(data, datalen / sizeof(struct pollfd)); 7107003901fSguenther } else if (strcmp(name, "cmsghdr") == 0) { 7117003901fSguenther char *cmsg; 7127003901fSguenther 7135f257f27Sotto if (datalen == 0) 7145f257f27Sotto goto invalid; 7155f257f27Sotto 7167003901fSguenther if ((cmsg = malloc(datalen)) == NULL) 7177003901fSguenther err(1, "malloc"); 7187003901fSguenther memcpy(cmsg, data, datalen); 7197003901fSguenther ktrcmsghdr(cmsg, datalen); 7207003901fSguenther free(cmsg); 7210bd1216cSderaadt } else if (strcmp(name, "pledgereq") == 0) { 7224ea7ed56Sderaadt printf("promise="); 7234ea7ed56Sderaadt showbufc(basecol + sizeof("promise=") - 1, 72480bc2255Sguenther (unsigned char *)data, datalen, VIS_DQ | VIS_TAB | VIS_NL); 7254ea7ed56Sderaadt } else if (strcmp(name, "pledgeexecreq") == 0) { 7264ea7ed56Sderaadt printf("execpromise="); 7274ea7ed56Sderaadt showbufc(basecol + sizeof("execpromise=") - 1, 72880bc2255Sguenther (unsigned char *)data, datalen, VIS_DQ | VIS_TAB | VIS_NL); 7298b23add8Sbeck } else if (strcmp(name, "unveil") == 0) { 7308b23add8Sbeck printf("flags="); 7318b23add8Sbeck showbufc(basecol + sizeof("flags=") - 1, 7328b23add8Sbeck (unsigned char *)data, datalen, VIS_DQ | VIS_TAB | VIS_NL); 7335c402730Santon } else if (strcmp(name, "flock") == 0) { 7345c402730Santon struct flock fl; 7355c402730Santon 7365c402730Santon if (datalen != sizeof(fl)) 7375c402730Santon goto invalid; 7385c402730Santon memcpy(&fl, data, datalen); 7395c402730Santon ktrflock(&fl); 74079b24ea9Sguenther } else if (strcmp(name, "siginfo") == 0) { 74179b24ea9Sguenther siginfo_t si; 74279b24ea9Sguenther 74379b24ea9Sguenther if (datalen != sizeof(si)) 74479b24ea9Sguenther goto invalid; 74579b24ea9Sguenther memcpy(&si, data, datalen); 74679b24ea9Sguenther ktrsiginfo(&si); 747dbedfdbcSguenther } else { 748dbedfdbcSguenther printf("unknown structure %s\n", name); 749dbedfdbcSguenther } 750dbedfdbcSguenther return; 751dbedfdbcSguenther invalid: 752dbedfdbcSguenther printf("invalid record\n"); 753dbedfdbcSguenther } 754