1 /* $OpenBSD: ktrstruct.c,v 1.32 2024/07/26 19:16:31 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 ktritimerval(const struct itimerval *itvp) 270 { 271 printf("struct itimerval { value="); 272 print_timeval(&itvp->it_value, 0); 273 if (timerisset(&itvp->it_interval)) { 274 printf(", interval="); 275 print_timeval(&itvp->it_interval, 1); 276 } 277 printf(" }\n"); 278 } 279 280 static void 281 ktrsigaction(const struct sigaction *sa) 282 { 283 /* 284 * note: ktrstruct() has already verified that sa points to a 285 * buffer exactly sizeof(struct sigaction) bytes long. 286 */ 287 /* 288 * Fuck! Comparison of function pointers on hppa assumes you can 289 * dereference them if they're plabels! Cast everything to void * 290 * to suppress that extra logic; sorry folks, the address we report 291 * here might not match what you see in your executable... 292 */ 293 printf("struct sigaction { "); 294 if ((void *)sa->sa_handler == (void *)SIG_DFL) 295 printf("handler=SIG_DFL"); 296 else if ((void *)sa->sa_handler == (void *)SIG_IGN) 297 printf("handler=SIG_IGN"); 298 else if (sa->sa_flags & SA_SIGINFO) 299 printf("sigaction=%p", (void *)sa->sa_sigaction); 300 else 301 printf("handler=%p", (void *)sa->sa_handler); 302 printf(", mask="); 303 sigset(sa->sa_mask); 304 printf(", flags="); 305 sigactionflagname(sa->sa_flags); 306 printf(" }\n"); 307 } 308 309 static void 310 print_rlim(rlim_t lim) 311 { 312 if (lim == RLIM_INFINITY) 313 printf("infinite"); 314 else 315 printf("%llu", (unsigned long long)lim); 316 } 317 318 static void 319 ktrrlimit(const struct rlimit *limp) 320 { 321 printf("struct rlimit { "); 322 printf("cur="); 323 print_rlim(limp->rlim_cur); 324 printf(", max="); 325 print_rlim(limp->rlim_max); 326 printf(" }\n"); 327 } 328 329 static void 330 ktrtfork(const struct __tfork *tf) 331 { 332 printf("struct __tfork { tcb=%p, tid=%p, stack=%p }\n", 333 tf->tf_tcb, (void *)tf->tf_tid, tf->tf_stack); 334 } 335 336 static void 337 ktrfds(const char *data, size_t count) 338 { 339 size_t i; 340 int fd; 341 342 printf("int"); 343 if (count > 1) 344 printf(" [%zu] { ", count); 345 for (i = 0; i < count; i++) { 346 memcpy(&fd, &data[i * sizeof(fd)], sizeof(fd)); 347 printf("%d%s", fd, i < count - 1 ? ", " : ""); 348 } 349 if (count > 1) 350 printf(" }"); 351 printf("\n"); 352 } 353 354 static void 355 ktrfdset(struct fd_set *fds, int len) 356 { 357 int nfds, i, start = -1; 358 char sep = ' '; 359 360 nfds = len * NBBY; 361 printf("struct fd_set {"); 362 for (i = 0; i <= nfds; i++) 363 if (i != nfds && FD_ISSET(i, fds)) { 364 if (start == -1) 365 start = i; 366 } else if (start != -1) { 367 putchar(sep); 368 if (start == i - 1) 369 printf("%d", start); 370 else if (start == i - 2) 371 printf("%d,%d", start, i - 1); 372 else 373 printf("%d-%d", start, i - 1); 374 sep = ','; 375 start = -1; 376 } 377 378 printf(" }\n"); 379 } 380 381 static void 382 ktrrusage(const struct rusage *rup) 383 { 384 printf("struct rusage { utime="); 385 print_timeval(&rup->ru_utime, 1); 386 printf(", stime="); 387 print_timeval(&rup->ru_stime, 1); 388 printf(", maxrss=%ld, ixrss=%ld, idrss=%ld, isrss=%ld," 389 " minflt=%ld, majflt=%ld, nswap=%ld, inblock=%ld," 390 " oublock=%ld, msgsnd=%ld, msgrcv=%ld, nsignals=%ld," 391 " nvcsw=%ld, nivcsw=%ld }\n", 392 rup->ru_maxrss, rup->ru_ixrss, rup->ru_idrss, rup->ru_isrss, 393 rup->ru_minflt, rup->ru_majflt, rup->ru_nswap, rup->ru_inblock, 394 rup->ru_oublock, rup->ru_msgsnd, rup->ru_msgrcv, rup->ru_nsignals, 395 rup->ru_nvcsw, rup->ru_nivcsw); 396 } 397 398 static void 399 ktrquota(const struct dqblk *quota) 400 { 401 printf("struct dqblk { bhardlimit=%u, bsoftlimit=%u, curblocks=%u," 402 " ihardlimit=%u, isoftlimit=%u, curinodes=%u, btime=", 403 quota->dqb_bhardlimit, quota->dqb_bsoftlimit, 404 quota->dqb_curblocks, quota->dqb_ihardlimit, 405 quota->dqb_isoftlimit, quota->dqb_curinodes); 406 print_time(quota->dqb_btime, 0, 0); 407 printf(", itime="); 408 print_time(quota->dqb_itime, 0, 0); 409 printf(" }\n"); 410 } 411 412 static void 413 ktrmmsghdr(const struct mmsghdr *mmsg) 414 { 415 printf("struct mmsghdr { msg_hdr = { name=%p, namelen=%u, " 416 "iov=%p, iovlen=%u, control=%p, controllen=%u, flags=", 417 mmsg->msg_hdr.msg_name, mmsg->msg_hdr.msg_namelen, 418 mmsg->msg_hdr.msg_iov, mmsg->msg_hdr.msg_iovlen, 419 mmsg->msg_hdr.msg_control, mmsg->msg_hdr.msg_controllen); 420 sendrecvflagsname(mmsg->msg_hdr.msg_flags); 421 printf(" }, msg_len = %u }\n", mmsg->msg_len); 422 } 423 424 static void 425 ktrmsghdr(const struct msghdr *msg) 426 { 427 printf("struct msghdr { name=%p, namelen=%u, iov=%p, iovlen=%u," 428 " control=%p, controllen=%u, flags=", 429 msg->msg_name, msg->msg_namelen, msg->msg_iov, msg->msg_iovlen, 430 msg->msg_control, msg->msg_controllen); 431 sendrecvflagsname(msg->msg_flags); 432 printf(" }\n"); 433 } 434 435 static void 436 ktriovec(const char *data, int count) 437 { 438 struct iovec iov; 439 int i; 440 441 printf("struct iovec"); 442 if (count > 1) 443 printf(" [%d]", count); 444 for (i = 0; i < count; i++) { 445 memcpy(&iov, data, sizeof(iov)); 446 data += sizeof(iov); 447 printf(" { base=%p, len=%lu }", iov.iov_base, iov.iov_len); 448 } 449 printf("\n"); 450 } 451 452 static void 453 ktrevent(const char *data, int count) 454 { 455 struct kevent kev; 456 int i; 457 458 printf("struct kevent"); 459 if (count > 1) 460 printf(" [%d]", count); 461 for (i = 0; i < count; i++) { 462 memcpy(&kev, data, sizeof(kev)); 463 data += sizeof(kev); 464 printf(" { ident=%lu, filter=", kev.ident); 465 evfiltername(kev.filter); 466 printf(", flags="); 467 evflagsname(kev.flags); 468 printf(", fflags="); 469 evfflagsname(kev.filter, kev.fflags); 470 printf(", data=%llu", kev.data); 471 if ((kev.flags & EV_ERROR) && fancy) { 472 printf("<\"%s\">", strerror(kev.data)); 473 } 474 printf(", udata=%p }", kev.udata); 475 } 476 printf("\n"); 477 } 478 479 static void 480 ktrpollfd(const char *data, int count) 481 { 482 struct pollfd pfd; 483 int i; 484 485 printf("struct pollfd"); 486 if (count > 1) 487 printf(" [%d]", count); 488 for (i = 0; i < count; i++) { 489 memcpy(&pfd, data, sizeof(pfd)); 490 data += sizeof(pfd); 491 printf(" { fd=%d, events=", pfd.fd); 492 pollfdeventname(pfd.events); 493 printf(", revents="); 494 pollfdeventname(pfd.revents); 495 printf(" }"); 496 } 497 printf("\n"); 498 } 499 500 static void 501 ktrcmsghdr(char *data, socklen_t len) 502 { 503 struct msghdr msg; 504 struct cmsghdr *cmsg; 505 int i, count, *fds; 506 507 msg.msg_control = data; 508 msg.msg_controllen = len; 509 510 /* count the control messages */ 511 count = 0; 512 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; 513 cmsg = CMSG_NXTHDR(&msg, cmsg)) { 514 count++; 515 } 516 517 printf("struct cmsghdr"); 518 if (count > 1) 519 printf(" [%d]", count); 520 521 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; 522 cmsg = CMSG_NXTHDR(&msg, cmsg)) { 523 printf(" { len=%u, level=", cmsg->cmsg_len); 524 if (cmsg->cmsg_level == SOL_SOCKET) { 525 printf("SOL_SOCKET, type="); 526 switch (cmsg->cmsg_type) { 527 case SCM_RIGHTS: 528 printf("SCM_RIGHTS, data="); 529 fds = (int *)CMSG_DATA(cmsg); 530 for (i = 0; 531 cmsg->cmsg_len > CMSG_LEN(sizeof(int) * i) 532 && (char *)fds + (i + 1) * sizeof(int) <= 533 data + len; 534 i++) { 535 printf("%s%d", i ? "," : "", fds[i]); 536 } 537 break; 538 case SCM_TIMESTAMP: 539 default: 540 printf("%d", cmsg->cmsg_type); 541 break; 542 } 543 } else { 544 struct protoent *p = getprotobynumber(cmsg->cmsg_level); 545 546 printf("%u<%s>, type=%d", cmsg->cmsg_level, 547 p != NULL ? p->p_name : "unknown", cmsg->cmsg_type); 548 } 549 printf(" }"); 550 } 551 printf("\n"); 552 } 553 554 static void 555 ktrflock(const struct flock *fl) 556 { 557 printf("struct flock { start=%lld, len=%lld, pid=%d, type=", 558 fl->l_start, fl->l_len, fl->l_pid); 559 flocktypename(fl->l_type); 560 printf(", whence="); 561 whencename(fl->l_whence); 562 printf(" }\n"); 563 } 564 565 static void 566 ktrsiginfo(const siginfo_t *si) 567 { 568 printf("siginfo_t { "); 569 siginfo(si, 1); 570 printf(" }\n"); 571 } 572 573 void 574 ktrstruct(char *buf, size_t buflen) 575 { 576 char *name, *data; 577 size_t namelen, datalen; 578 int i; 579 580 for (name = buf, namelen = 0; namelen < buflen && name[namelen] != '\0'; 581 ++namelen) 582 /* nothing */; 583 if (namelen == buflen) 584 goto invalid; 585 if (name[namelen] != '\0') 586 goto invalid; 587 data = buf + namelen + 1; 588 datalen = buflen - namelen - 1; 589 590 /* sanity check */ 591 for (i = 0; i < namelen; ++i) 592 if (!isalpha((unsigned char)name[i])) 593 goto invalid; 594 if (strcmp(name, "stat") == 0) { 595 struct stat sb; 596 597 if (datalen != sizeof(struct stat)) 598 goto invalid; 599 memcpy(&sb, data, datalen); 600 ktrstat(&sb); 601 } else if (strcmp(name, "sockaddr") == 0) { 602 struct sockaddr_storage ss; 603 604 if (datalen > sizeof(ss)) 605 goto invalid; 606 if (datalen < offsetof(struct sockaddr_storage, ss_len) + 607 sizeof(ss.ss_len)) 608 goto invalid; 609 memcpy(&ss, data, datalen); 610 if ((ss.ss_family != AF_UNIX && 611 datalen < sizeof(struct sockaddr)) || datalen != ss.ss_len) 612 goto invalid; 613 ktrsockaddr((struct sockaddr *)&ss); 614 } else if (strcmp(name, "abstimespec") == 0 || 615 strcmp(name, "reltimespec") == 0) { 616 struct timespec ts; 617 618 if (datalen != sizeof(ts)) 619 goto invalid; 620 memcpy(&ts, data, datalen); 621 ktrtimespec(&ts, name[0] == 'r'); 622 } else if (strcmp(name, "abstimeval") == 0 || 623 strcmp(name, "reltimeval") == 0) { 624 struct timeval tv; 625 626 if (datalen != sizeof(tv)) 627 goto invalid; 628 memcpy(&tv, data, datalen); 629 ktrtimeval(&tv, name[0] == 'r'); 630 } else if (strcmp(name, "itimerval") == 0) { 631 struct itimerval itv; 632 633 if (datalen != sizeof(itv)) 634 goto invalid; 635 memcpy(&itv, data, datalen); 636 ktritimerval(&itv); 637 } else if (strcmp(name, "sigaction") == 0) { 638 struct sigaction sa; 639 640 if (datalen != sizeof(sa)) 641 goto invalid; 642 memcpy(&sa, data, datalen); 643 ktrsigaction(&sa); 644 } else if (strcmp(name, "rlimit") == 0) { 645 struct rlimit lim; 646 647 if (datalen != sizeof(lim)) 648 goto invalid; 649 memcpy(&lim, data, datalen); 650 ktrrlimit(&lim); 651 } else if (strcmp(name, "rusage") == 0) { 652 struct rusage ru; 653 654 if (datalen != sizeof(ru)) 655 goto invalid; 656 memcpy(&ru, data, datalen); 657 ktrrusage(&ru); 658 } else if (strcmp(name, "tfork") == 0) { 659 struct __tfork tf; 660 661 if (datalen != sizeof(tf)) 662 goto invalid; 663 memcpy(&tf, data, datalen); 664 ktrtfork(&tf); 665 } else if (strcmp(name, "fds") == 0) { 666 if (datalen % sizeof(int)) 667 goto invalid; 668 ktrfds(data, datalen / sizeof(int)); 669 } else if (strcmp(name, "fdset") == 0) { 670 struct fd_set *fds; 671 672 if ((fds = malloc(datalen)) == NULL) 673 err(1, "malloc"); 674 memcpy(fds, data, datalen); 675 ktrfdset(fds, datalen); 676 free(fds); 677 } else if (strcmp(name, "quota") == 0) { 678 struct dqblk quota; 679 680 if (datalen != sizeof(quota)) 681 goto invalid; 682 memcpy("a, data, datalen); 683 ktrquota("a); 684 } else if (strcmp(name, "msghdr") == 0) { 685 struct msghdr msg; 686 687 if (datalen != sizeof(msg)) 688 goto invalid; 689 memcpy(&msg, data, datalen); 690 ktrmsghdr(&msg); 691 } else if (strcmp(name, "mmsghdr") == 0) { 692 struct mmsghdr mmsg; 693 694 if (datalen != sizeof(mmsg)) 695 goto invalid; 696 memcpy(&mmsg, data, datalen); 697 ktrmmsghdr(&mmsg); 698 } else if (strcmp(name, "iovec") == 0) { 699 if (datalen % sizeof(struct iovec)) 700 goto invalid; 701 ktriovec(data, datalen / sizeof(struct iovec)); 702 } else if (strcmp(name, "kevent") == 0) { 703 if (datalen % sizeof(struct kevent)) 704 goto invalid; 705 ktrevent(data, datalen / sizeof(struct kevent)); 706 } else if (strcmp(name, "pollfd") == 0) { 707 if (datalen % sizeof(struct pollfd)) 708 goto invalid; 709 ktrpollfd(data, datalen / sizeof(struct pollfd)); 710 } else if (strcmp(name, "cmsghdr") == 0) { 711 char *cmsg; 712 713 if (datalen == 0) 714 goto invalid; 715 716 if ((cmsg = malloc(datalen)) == NULL) 717 err(1, "malloc"); 718 memcpy(cmsg, data, datalen); 719 ktrcmsghdr(cmsg, datalen); 720 free(cmsg); 721 } else if (strcmp(name, "pledgereq") == 0) { 722 printf("promise="); 723 showbufc(basecol + sizeof("promise=") - 1, 724 (unsigned char *)data, datalen, VIS_DQ | VIS_TAB | VIS_NL); 725 } else if (strcmp(name, "pledgeexecreq") == 0) { 726 printf("execpromise="); 727 showbufc(basecol + sizeof("execpromise=") - 1, 728 (unsigned char *)data, datalen, VIS_DQ | VIS_TAB | VIS_NL); 729 } else if (strcmp(name, "unveil") == 0) { 730 printf("flags="); 731 showbufc(basecol + sizeof("flags=") - 1, 732 (unsigned char *)data, datalen, VIS_DQ | VIS_TAB | VIS_NL); 733 } else if (strcmp(name, "flock") == 0) { 734 struct flock fl; 735 736 if (datalen != sizeof(fl)) 737 goto invalid; 738 memcpy(&fl, data, datalen); 739 ktrflock(&fl); 740 } else if (strcmp(name, "siginfo") == 0) { 741 siginfo_t si; 742 743 if (datalen != sizeof(si)) 744 goto invalid; 745 memcpy(&si, data, datalen); 746 ktrsiginfo(&si); 747 } else { 748 printf("unknown structure %s\n", name); 749 } 750 return; 751 invalid: 752 printf("invalid record\n"); 753 } 754