1 /* $OpenBSD: ktrstruct.c,v 1.31 2022/12/29 01:36:36 guenther 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/types.h> 33 #include <sys/resource.h> 34 #include <sys/socket.h> 35 #include <sys/select.h> 36 #include <sys/stat.h> 37 #include <sys/time.h> 38 #include <sys/event.h> 39 #include <sys/un.h> 40 #include <sys/fcntl.h> 41 #include <ufs/ufs/quota.h> 42 #include <netinet/in.h> 43 #include <arpa/inet.h> 44 45 #include <ctype.h> 46 #include <err.h> 47 #include <limits.h> 48 #include <netdb.h> 49 #include <poll.h> 50 #include <signal.h> 51 #include <stddef.h> 52 #include <stdio.h> 53 #include <stdlib.h> 54 #include <stdint.h> 55 #include <string.h> 56 #include <grp.h> 57 #include <pwd.h> 58 #include <unistd.h> 59 #include <vis.h> 60 61 #include "kdump.h" 62 #include "kdump_subr.h" 63 64 #define TIME_FORMAT "%b %e %T %Y" 65 66 static void 67 ktrsockaddr(struct sockaddr *sa) 68 { 69 /* 70 * TODO: Support additional address families 71 * #include <netmpls/mpls.h> 72 * struct sockaddr_mpls *mpls; 73 */ 74 75 /* 76 * note: ktrstruct() has already verified that sa points to a 77 * buffer at least sizeof(struct sockaddr) bytes long and exactly 78 * sa->sa_len bytes long. 79 */ 80 printf("struct sockaddr { "); 81 sockfamilyname(sa->sa_family); 82 printf(", "); 83 84 #define check_sockaddr_len(n) \ 85 if (sa_##n->s##n##_len < sizeof(struct sockaddr_##n)) { \ 86 printf("invalid"); \ 87 break; \ 88 } 89 90 switch(sa->sa_family) { 91 case AF_INET: { 92 struct sockaddr_in *sa_in; 93 char addr[INET_ADDRSTRLEN]; 94 95 sa_in = (struct sockaddr_in *)sa; 96 check_sockaddr_len(in); 97 inet_ntop(AF_INET, &sa_in->sin_addr, addr, sizeof addr); 98 printf("%s:%u", addr, ntohs(sa_in->sin_port)); 99 break; 100 } 101 case AF_INET6: { 102 struct sockaddr_in6 *sa_in6; 103 char addr[INET6_ADDRSTRLEN], scope[12] = { 0 }; 104 105 sa_in6 = (struct sockaddr_in6 *)sa; 106 check_sockaddr_len(in6); 107 inet_ntop(AF_INET6, &sa_in6->sin6_addr, addr, sizeof addr); 108 if (sa_in6->sin6_scope_id) 109 snprintf(scope, sizeof(scope), "%%%u", 110 sa_in6->sin6_scope_id); 111 printf("[%s%s]:%u", addr, scope, htons(sa_in6->sin6_port)); 112 break; 113 } 114 case AF_UNIX: { 115 struct sockaddr_un *sa_un; 116 char path[4 * sizeof(sa_un->sun_path) + 1]; 117 size_t len; 118 119 sa_un = (struct sockaddr_un *)sa; 120 len = sa_un->sun_len; 121 if (len <= offsetof(struct sockaddr_un, sun_path)) { 122 printf("invalid"); 123 break; 124 } 125 len -= offsetof(struct sockaddr_un, sun_path); 126 if (len > sizeof(sa_un->sun_path)) { 127 printf("too long"); 128 break; 129 } 130 /* format, stopping at first NUL */ 131 len = strnlen(sa_un->sun_path, len); 132 strvisx(path, sa_un->sun_path, len, 133 VIS_CSTYLE | VIS_DQ | VIS_TAB | VIS_NL); 134 printf("\"%s\"", path); 135 break; 136 } 137 default: 138 printf("unknown address family"); 139 } 140 printf(" }\n"); 141 } 142 143 static void 144 print_time(time_t t, int relative, int have_subsec) 145 { 146 char timestr[PATH_MAX + 4]; 147 struct tm *tm; 148 149 if (t < 0 && have_subsec) { 150 /* negative times with non-zero subsecs require care */ 151 printf("-%jd", -(intmax_t)(t + 1)); 152 } else 153 printf("%jd", (intmax_t)t); 154 155 /* 1970s times are probably relative */ 156 if (!relative && t > (10 * 365 * 24 * 3600)) { 157 tm = localtime(&t); 158 if (tm != NULL) { 159 (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, 160 tm); 161 printf("<\"%s\">", timestr); 162 } 163 } 164 } 165 166 static void 167 print_timespec(const struct timespec *tsp, int relative) 168 { 169 if (tsp->tv_nsec == UTIME_NOW) 170 printf("UTIME_NOW"); 171 else if (tsp->tv_nsec == UTIME_OMIT) 172 printf("UTIME_OMIT"); 173 else { 174 print_time(tsp->tv_sec, relative, tsp->tv_nsec); 175 if (tsp->tv_nsec != 0) 176 printf(".%09ld", tsp->tv_sec >= 0 ? tsp->tv_nsec : 177 1000000000 - tsp->tv_nsec); 178 } 179 } 180 181 void 182 uidname(int uid) 183 { 184 const char *name; 185 186 if (uid == -1) 187 printf("-1"); 188 else { 189 printf("%u<", (unsigned)uid); 190 if (uid > UID_MAX || (name = user_from_uid(uid, 1)) == NULL) 191 printf("unknown>"); 192 else 193 printf("\"%s\">", name); 194 } 195 } 196 197 void 198 gidname(int gid) 199 { 200 const char *name; 201 202 if (gid == -1) 203 printf("-1"); 204 else { 205 printf("%u<", (unsigned)gid); 206 if (gid > GID_MAX || (name = group_from_gid(gid, 1)) == NULL) 207 printf("unknown>"); 208 else 209 printf("\"%s\">", name); 210 } 211 } 212 213 static void 214 ktrstat(const struct stat *statp) 215 { 216 char mode[12]; 217 218 /* 219 * note: ktrstruct() has already verified that statp points to a 220 * buffer exactly sizeof(struct stat) bytes long. 221 */ 222 printf("struct stat { "); 223 strmode(statp->st_mode, mode); 224 printf("dev=%d, ino=%llu, mode=%s, nlink=%u, uid=", 225 statp->st_dev, (unsigned long long)statp->st_ino, 226 mode, statp->st_nlink); 227 uidname(statp->st_uid); 228 printf(", gid="); 229 gidname(statp->st_gid); 230 printf(", rdev=%d, ", statp->st_rdev); 231 printf("atime="); 232 print_timespec(&statp->st_atim, 0); 233 printf(", mtime="); 234 print_timespec(&statp->st_mtim, 0); 235 printf(", ctime="); 236 print_timespec(&statp->st_ctim, 0); 237 printf(", size=%lld, blocks=%lld, blksize=%d, flags=0x%x, gen=0x%x", 238 statp->st_size, statp->st_blocks, statp->st_blksize, 239 statp->st_flags, statp->st_gen); 240 printf(" }\n"); 241 } 242 243 static void 244 ktrtimespec(const struct timespec *tsp, int relative) 245 { 246 printf("struct timespec { "); 247 print_timespec(tsp, relative); 248 printf(" }\n"); 249 } 250 251 static void 252 print_timeval(const struct timeval *tvp, int relative) 253 { 254 print_time(tvp->tv_sec, relative, tvp->tv_usec); 255 if (tvp->tv_usec != 0) 256 printf(".%06ld", tvp->tv_sec >= 0 ? tvp->tv_usec : 257 1000000 - tvp->tv_usec); 258 } 259 260 static void 261 ktrtimeval(const struct timeval *tvp, int relative) 262 { 263 printf("struct timeval { "); 264 print_timeval(tvp, relative); 265 printf(" }\n"); 266 } 267 268 static void 269 ktrsigaction(const struct sigaction *sa) 270 { 271 /* 272 * note: ktrstruct() has already verified that sa points to a 273 * buffer exactly sizeof(struct sigaction) bytes long. 274 */ 275 /* 276 * Fuck! Comparison of function pointers on hppa assumes you can 277 * dereference them if they're plabels! Cast everything to void * 278 * to suppress that extra logic; sorry folks, the address we report 279 * here might not match what you see in your executable... 280 */ 281 printf("struct sigaction { "); 282 if ((void *)sa->sa_handler == (void *)SIG_DFL) 283 printf("handler=SIG_DFL"); 284 else if ((void *)sa->sa_handler == (void *)SIG_IGN) 285 printf("handler=SIG_IGN"); 286 else if (sa->sa_flags & SA_SIGINFO) 287 printf("sigaction=%p", (void *)sa->sa_sigaction); 288 else 289 printf("handler=%p", (void *)sa->sa_handler); 290 printf(", mask="); 291 sigset(sa->sa_mask); 292 printf(", flags="); 293 sigactionflagname(sa->sa_flags); 294 printf(" }\n"); 295 } 296 297 static void 298 print_rlim(rlim_t lim) 299 { 300 if (lim == RLIM_INFINITY) 301 printf("infinite"); 302 else 303 printf("%llu", (unsigned long long)lim); 304 } 305 306 static void 307 ktrrlimit(const struct rlimit *limp) 308 { 309 printf("struct rlimit { "); 310 printf("cur="); 311 print_rlim(limp->rlim_cur); 312 printf(", max="); 313 print_rlim(limp->rlim_max); 314 printf(" }\n"); 315 } 316 317 static void 318 ktrtfork(const struct __tfork *tf) 319 { 320 printf("struct __tfork { tcb=%p, tid=%p, stack=%p }\n", 321 tf->tf_tcb, (void *)tf->tf_tid, tf->tf_stack); 322 } 323 324 static void 325 ktrfds(const char *data, size_t count) 326 { 327 size_t i; 328 int fd; 329 330 printf("int"); 331 if (count > 1) 332 printf(" [%zu] { ", count); 333 for (i = 0; i < count; i++) { 334 memcpy(&fd, &data[i * sizeof(fd)], sizeof(fd)); 335 printf("%d%s", fd, i < count - 1 ? ", " : ""); 336 } 337 if (count > 1) 338 printf(" }"); 339 printf("\n"); 340 } 341 342 static void 343 ktrfdset(struct fd_set *fds, int len) 344 { 345 int nfds, i, start = -1; 346 char sep = ' '; 347 348 nfds = len * NBBY; 349 printf("struct fd_set {"); 350 for (i = 0; i <= nfds; i++) 351 if (i != nfds && FD_ISSET(i, fds)) { 352 if (start == -1) 353 start = i; 354 } else if (start != -1) { 355 putchar(sep); 356 if (start == i - 1) 357 printf("%d", start); 358 else if (start == i - 2) 359 printf("%d,%d", start, i - 1); 360 else 361 printf("%d-%d", start, i - 1); 362 sep = ','; 363 start = -1; 364 } 365 366 printf(" }\n"); 367 } 368 369 static void 370 ktrrusage(const struct rusage *rup) 371 { 372 printf("struct rusage { utime="); 373 print_timeval(&rup->ru_utime, 1); 374 printf(", stime="); 375 print_timeval(&rup->ru_stime, 1); 376 printf(", maxrss=%ld, ixrss=%ld, idrss=%ld, isrss=%ld," 377 " minflt=%ld, majflt=%ld, nswap=%ld, inblock=%ld," 378 " oublock=%ld, msgsnd=%ld, msgrcv=%ld, nsignals=%ld," 379 " nvcsw=%ld, nivcsw=%ld }\n", 380 rup->ru_maxrss, rup->ru_ixrss, rup->ru_idrss, rup->ru_isrss, 381 rup->ru_minflt, rup->ru_majflt, rup->ru_nswap, rup->ru_inblock, 382 rup->ru_oublock, rup->ru_msgsnd, rup->ru_msgrcv, rup->ru_nsignals, 383 rup->ru_nvcsw, rup->ru_nivcsw); 384 } 385 386 static void 387 ktrquota(const struct dqblk *quota) 388 { 389 printf("struct dqblk { bhardlimit=%u, bsoftlimit=%u, curblocks=%u," 390 " ihardlimit=%u, isoftlimit=%u, curinodes=%u, btime=", 391 quota->dqb_bhardlimit, quota->dqb_bsoftlimit, 392 quota->dqb_curblocks, quota->dqb_ihardlimit, 393 quota->dqb_isoftlimit, quota->dqb_curinodes); 394 print_time(quota->dqb_btime, 0, 0); 395 printf(", itime="); 396 print_time(quota->dqb_itime, 0, 0); 397 printf(" }\n"); 398 } 399 400 static void 401 ktrmmsghdr(const struct mmsghdr *mmsg) 402 { 403 printf("struct mmsghdr { msg_hdr = { name=%p, namelen=%u, " 404 "iov=%p, iovlen=%u, control=%p, controllen=%u, flags=", 405 mmsg->msg_hdr.msg_name, mmsg->msg_hdr.msg_namelen, 406 mmsg->msg_hdr.msg_iov, mmsg->msg_hdr.msg_iovlen, 407 mmsg->msg_hdr.msg_control, mmsg->msg_hdr.msg_controllen); 408 sendrecvflagsname(mmsg->msg_hdr.msg_flags); 409 printf(" }, msg_len = %u }\n", mmsg->msg_len); 410 } 411 412 static void 413 ktrmsghdr(const struct msghdr *msg) 414 { 415 printf("struct msghdr { name=%p, namelen=%u, iov=%p, iovlen=%u," 416 " control=%p, controllen=%u, flags=", 417 msg->msg_name, msg->msg_namelen, msg->msg_iov, msg->msg_iovlen, 418 msg->msg_control, msg->msg_controllen); 419 sendrecvflagsname(msg->msg_flags); 420 printf(" }\n"); 421 } 422 423 static void 424 ktriovec(const char *data, int count) 425 { 426 struct iovec iov; 427 int i; 428 429 printf("struct iovec"); 430 if (count > 1) 431 printf(" [%d]", count); 432 for (i = 0; i < count; i++) { 433 memcpy(&iov, data, sizeof(iov)); 434 data += sizeof(iov); 435 printf(" { base=%p, len=%lu }", iov.iov_base, iov.iov_len); 436 } 437 printf("\n"); 438 } 439 440 static void 441 ktrevent(const char *data, int count) 442 { 443 struct kevent kev; 444 int i; 445 446 printf("struct kevent"); 447 if (count > 1) 448 printf(" [%d]", count); 449 for (i = 0; i < count; i++) { 450 memcpy(&kev, data, sizeof(kev)); 451 data += sizeof(kev); 452 printf(" { ident=%lu, filter=", kev.ident); 453 evfiltername(kev.filter); 454 printf(", flags="); 455 evflagsname(kev.flags); 456 printf(", fflags="); 457 evfflagsname(kev.filter, kev.fflags); 458 printf(", data=%llu", kev.data); 459 if ((kev.flags & EV_ERROR) && fancy) { 460 printf("<\"%s\">", strerror(kev.data)); 461 } 462 printf(", udata=%p }", kev.udata); 463 } 464 printf("\n"); 465 } 466 467 static void 468 ktrpollfd(const char *data, int count) 469 { 470 struct pollfd pfd; 471 int i; 472 473 printf("struct pollfd"); 474 if (count > 1) 475 printf(" [%d]", count); 476 for (i = 0; i < count; i++) { 477 memcpy(&pfd, data, sizeof(pfd)); 478 data += sizeof(pfd); 479 printf(" { fd=%d, events=", pfd.fd); 480 pollfdeventname(pfd.events); 481 printf(", revents="); 482 pollfdeventname(pfd.revents); 483 printf(" }"); 484 } 485 printf("\n"); 486 } 487 488 static void 489 ktrcmsghdr(char *data, socklen_t len) 490 { 491 struct msghdr msg; 492 struct cmsghdr *cmsg; 493 int i, count, *fds; 494 495 msg.msg_control = data; 496 msg.msg_controllen = len; 497 498 /* count the control messages */ 499 count = 0; 500 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; 501 cmsg = CMSG_NXTHDR(&msg, cmsg)) { 502 count++; 503 } 504 505 printf("struct cmsghdr"); 506 if (count > 1) 507 printf(" [%d]", count); 508 509 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; 510 cmsg = CMSG_NXTHDR(&msg, cmsg)) { 511 printf(" { len=%u, level=", cmsg->cmsg_len); 512 if (cmsg->cmsg_level == SOL_SOCKET) { 513 printf("SOL_SOCKET, type="); 514 switch (cmsg->cmsg_type) { 515 case SCM_RIGHTS: 516 printf("SCM_RIGHTS, data="); 517 fds = (int *)CMSG_DATA(cmsg); 518 for (i = 0; 519 cmsg->cmsg_len > CMSG_LEN(sizeof(int) * i) 520 && (char *)fds + (i + 1) * sizeof(int) <= 521 data + len; 522 i++) { 523 printf("%s%d", i ? "," : "", fds[i]); 524 } 525 break; 526 case SCM_TIMESTAMP: 527 default: 528 printf("%d", cmsg->cmsg_type); 529 break; 530 } 531 } else { 532 struct protoent *p = getprotobynumber(cmsg->cmsg_level); 533 534 printf("%u<%s>, type=%d", cmsg->cmsg_level, 535 p != NULL ? p->p_name : "unknown", cmsg->cmsg_type); 536 } 537 printf(" }"); 538 } 539 printf("\n"); 540 } 541 542 static void 543 ktrflock(const struct flock *fl) 544 { 545 printf("struct flock { start=%lld, len=%lld, pid=%d, type=", 546 fl->l_start, fl->l_len, fl->l_pid); 547 flocktypename(fl->l_type); 548 printf(", whence="); 549 whencename(fl->l_whence); 550 printf(" }\n"); 551 } 552 553 static void 554 ktrsiginfo(const siginfo_t *si) 555 { 556 printf("siginfo_t { "); 557 siginfo(si, 1); 558 printf(" }\n"); 559 } 560 561 void 562 ktrstruct(char *buf, size_t buflen) 563 { 564 char *name, *data; 565 size_t namelen, datalen; 566 int i; 567 568 for (name = buf, namelen = 0; namelen < buflen && name[namelen] != '\0'; 569 ++namelen) 570 /* nothing */; 571 if (namelen == buflen) 572 goto invalid; 573 if (name[namelen] != '\0') 574 goto invalid; 575 data = buf + namelen + 1; 576 datalen = buflen - namelen - 1; 577 578 /* sanity check */ 579 for (i = 0; i < namelen; ++i) 580 if (!isalpha((unsigned char)name[i])) 581 goto invalid; 582 if (strcmp(name, "stat") == 0) { 583 struct stat sb; 584 585 if (datalen != sizeof(struct stat)) 586 goto invalid; 587 memcpy(&sb, data, datalen); 588 ktrstat(&sb); 589 } else if (strcmp(name, "sockaddr") == 0) { 590 struct sockaddr_storage ss; 591 592 if (datalen > sizeof(ss)) 593 goto invalid; 594 if (datalen < offsetof(struct sockaddr_storage, ss_len) + 595 sizeof(ss.ss_len)) 596 goto invalid; 597 memcpy(&ss, data, datalen); 598 if ((ss.ss_family != AF_UNIX && 599 datalen < sizeof(struct sockaddr)) || datalen != ss.ss_len) 600 goto invalid; 601 ktrsockaddr((struct sockaddr *)&ss); 602 } else if (strcmp(name, "abstimespec") == 0 || 603 strcmp(name, "reltimespec") == 0) { 604 struct timespec ts; 605 606 if (datalen != sizeof(ts)) 607 goto invalid; 608 memcpy(&ts, data, datalen); 609 ktrtimespec(&ts, name[0] == 'r'); 610 } else if (strcmp(name, "abstimeval") == 0 || 611 strcmp(name, "reltimeval") == 0) { 612 struct timeval tv; 613 614 if (datalen != sizeof(tv)) 615 goto invalid; 616 memcpy(&tv, data, datalen); 617 ktrtimeval(&tv, name[0] == 'r'); 618 } else if (strcmp(name, "sigaction") == 0) { 619 struct sigaction sa; 620 621 if (datalen != sizeof(sa)) 622 goto invalid; 623 memcpy(&sa, data, datalen); 624 ktrsigaction(&sa); 625 } else if (strcmp(name, "rlimit") == 0) { 626 struct rlimit lim; 627 628 if (datalen != sizeof(lim)) 629 goto invalid; 630 memcpy(&lim, data, datalen); 631 ktrrlimit(&lim); 632 } else if (strcmp(name, "rusage") == 0) { 633 struct rusage ru; 634 635 if (datalen != sizeof(ru)) 636 goto invalid; 637 memcpy(&ru, data, datalen); 638 ktrrusage(&ru); 639 } else if (strcmp(name, "tfork") == 0) { 640 struct __tfork tf; 641 642 if (datalen != sizeof(tf)) 643 goto invalid; 644 memcpy(&tf, data, datalen); 645 ktrtfork(&tf); 646 } else if (strcmp(name, "fds") == 0) { 647 if (datalen % sizeof(int)) 648 goto invalid; 649 ktrfds(data, datalen / sizeof(int)); 650 } else if (strcmp(name, "fdset") == 0) { 651 struct fd_set *fds; 652 653 if ((fds = malloc(datalen)) == NULL) 654 err(1, "malloc"); 655 memcpy(fds, data, datalen); 656 ktrfdset(fds, datalen); 657 free(fds); 658 } else if (strcmp(name, "quota") == 0) { 659 struct dqblk quota; 660 661 if (datalen != sizeof(quota)) 662 goto invalid; 663 memcpy("a, data, datalen); 664 ktrquota("a); 665 } else if (strcmp(name, "msghdr") == 0) { 666 struct msghdr msg; 667 668 if (datalen != sizeof(msg)) 669 goto invalid; 670 memcpy(&msg, data, datalen); 671 ktrmsghdr(&msg); 672 } else if (strcmp(name, "mmsghdr") == 0) { 673 struct mmsghdr mmsg; 674 675 if (datalen != sizeof(mmsg)) 676 goto invalid; 677 memcpy(&mmsg, data, datalen); 678 ktrmmsghdr(&mmsg); 679 } else if (strcmp(name, "iovec") == 0) { 680 if (datalen % sizeof(struct iovec)) 681 goto invalid; 682 ktriovec(data, datalen / sizeof(struct iovec)); 683 } else if (strcmp(name, "kevent") == 0) { 684 if (datalen % sizeof(struct kevent)) 685 goto invalid; 686 ktrevent(data, datalen / sizeof(struct kevent)); 687 } else if (strcmp(name, "pollfd") == 0) { 688 if (datalen % sizeof(struct pollfd)) 689 goto invalid; 690 ktrpollfd(data, datalen / sizeof(struct pollfd)); 691 } else if (strcmp(name, "cmsghdr") == 0) { 692 char *cmsg; 693 694 if (datalen == 0) 695 goto invalid; 696 697 if ((cmsg = malloc(datalen)) == NULL) 698 err(1, "malloc"); 699 memcpy(cmsg, data, datalen); 700 ktrcmsghdr(cmsg, datalen); 701 free(cmsg); 702 } else if (strcmp(name, "pledgereq") == 0) { 703 printf("promise="); 704 showbufc(basecol + sizeof("promise=") - 1, 705 (unsigned char *)data, datalen, VIS_DQ | VIS_TAB | VIS_NL); 706 } else if (strcmp(name, "pledgeexecreq") == 0) { 707 printf("execpromise="); 708 showbufc(basecol + sizeof("execpromise=") - 1, 709 (unsigned char *)data, datalen, VIS_DQ | VIS_TAB | VIS_NL); 710 } else if (strcmp(name, "unveil") == 0) { 711 printf("flags="); 712 showbufc(basecol + sizeof("flags=") - 1, 713 (unsigned char *)data, datalen, VIS_DQ | VIS_TAB | VIS_NL); 714 } else if (strcmp(name, "flock") == 0) { 715 struct flock fl; 716 717 if (datalen != sizeof(fl)) 718 goto invalid; 719 memcpy(&fl, data, datalen); 720 ktrflock(&fl); 721 } else if (strcmp(name, "siginfo") == 0) { 722 siginfo_t si; 723 724 if (datalen != sizeof(si)) 725 goto invalid; 726 memcpy(&si, data, datalen); 727 ktrsiginfo(&si); 728 } else { 729 printf("unknown structure %s\n", name); 730 } 731 return; 732 invalid: 733 printf("invalid record\n"); 734 } 735