1 /* 2 * Copyright (c) 2006 "David Kirchner" <dpk@dpk.net>. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 */ 25 26 #define L2CAP_SOCKET_CHECKED 27 28 #include <sys/types.h> 29 #include <sys/acl.h> 30 #include <sys/capsicum.h> 31 #include <sys/event.h> 32 #include <sys/extattr.h> 33 #include <sys/inotify.h> 34 #include <sys/linker.h> 35 #include <sys/mman.h> 36 #include <sys/mount.h> 37 #include <sys/poll.h> 38 #include <sys/procctl.h> 39 #include <sys/ptrace.h> 40 #include <sys/reboot.h> 41 #include <sys/resource.h> 42 #include <sys/rtprio.h> 43 #include <sys/sem.h> 44 #include <sys/shm.h> 45 #include <sys/socket.h> 46 #include <sys/stat.h> 47 #include <sys/thr.h> 48 #include <sys/umtx.h> 49 #include <machine/sysarch.h> 50 #include <netinet/in.h> 51 #include <netinet/sctp.h> 52 #include <netinet/tcp.h> 53 #include <netinet/udp.h> 54 #include <netinet/udplite.h> 55 #include <nfsserver/nfs.h> 56 #include <ufs/ufs/quota.h> 57 #include <vm/vm.h> 58 #include <vm/vm_param.h> 59 #include <aio.h> 60 #include <fcntl.h> 61 #include <sched.h> 62 #include <stdbool.h> 63 #include <stdio.h> 64 #include <stdlib.h> 65 #include <strings.h> 66 #include <sysdecode.h> 67 #include <unistd.h> 68 #include <sys/bitstring.h> 69 #include <netgraph/bluetooth/include/ng_hci.h> 70 #include <netgraph/bluetooth/include/ng_l2cap.h> 71 #include <netgraph/bluetooth/include/ng_btsocket.h> 72 #include <netpfil/pf/pf_nl.h> 73 74 #include "support.h" 75 76 #define X(a) { a, #a }, 77 #define XEND { 0, NULL } 78 79 #define TABLE_START(n) static struct name_table n[] = { 80 #define TABLE_ENTRY X 81 #define TABLE_END XEND }; 82 83 #include "tables.h" 84 85 #undef TABLE_START 86 #undef TABLE_ENTRY 87 #undef TABLE_END 88 89 const char * 90 sysdecode_atfd(int fd) 91 { 92 93 if (fd == AT_FDCWD) 94 return ("AT_FDCWD"); 95 return (NULL); 96 } 97 98 bool 99 sysdecode_atflags(FILE *fp, int flag, int *rem) 100 { 101 102 return (print_mask_int(fp, atflags, flag, rem)); 103 } 104 105 static struct name_table semctlops[] = { 106 X(GETNCNT) X(GETPID) X(GETVAL) X(GETALL) X(GETZCNT) X(SETVAL) X(SETALL) 107 X(IPC_RMID) X(IPC_SET) X(IPC_STAT) XEND 108 }; 109 110 const char * 111 sysdecode_semctl_cmd(int cmd) 112 { 113 114 return (lookup_value(semctlops, cmd)); 115 } 116 117 static struct name_table shmctlops[] = { 118 X(IPC_RMID) X(IPC_SET) X(IPC_STAT) XEND 119 }; 120 121 const char * 122 sysdecode_shmctl_cmd(int cmd) 123 { 124 125 return (lookup_value(shmctlops, cmd)); 126 } 127 128 const char * 129 sysdecode_msgctl_cmd(int cmd) 130 { 131 132 return (sysdecode_shmctl_cmd(cmd)); 133 } 134 135 static struct name_table semgetflags[] = { 136 X(IPC_CREAT) X(IPC_EXCL) X(SEM_R) X(SEM_A) X((SEM_R>>3)) X((SEM_A>>3)) 137 X((SEM_R>>6)) X((SEM_A>>6)) XEND 138 }; 139 140 bool 141 sysdecode_semget_flags(FILE *fp, int flag, int *rem) 142 { 143 144 return (print_mask_int(fp, semgetflags, flag, rem)); 145 } 146 147 static struct name_table idtypes[] = { 148 X(P_PID) X(P_PPID) X(P_PGID) X(P_SID) X(P_CID) X(P_UID) X(P_GID) 149 X(P_ALL) X(P_LWPID) X(P_TASKID) X(P_PROJID) X(P_POOLID) X(P_JAILID) 150 X(P_CTID) X(P_CPUID) X(P_PSETID) XEND 151 }; 152 153 /* XXX: idtype is really an idtype_t */ 154 const char * 155 sysdecode_idtype(int idtype) 156 { 157 158 return (lookup_value(idtypes, idtype)); 159 } 160 161 /* 162 * [g|s]etsockopt's level argument can either be SOL_SOCKET or a 163 * protocol-specific value. 164 */ 165 const char * 166 sysdecode_sockopt_level(int level) 167 { 168 const char *str; 169 170 if (level == SOL_SOCKET) 171 return ("SOL_SOCKET"); 172 173 /* SOL_* constants for Bluetooth sockets. */ 174 str = lookup_value(ngbtsolevel, level); 175 if (str != NULL) 176 return (str); 177 178 /* 179 * IP and Infiniband sockets use IP protocols as levels. Not all 180 * protocols are valid but it is simpler to just allow all of them. 181 * 182 * XXX: IPPROTO_IP == 0, but UNIX domain sockets use a level of 0 183 * for private options. 184 */ 185 str = sysdecode_ipproto(level); 186 if (str != NULL) 187 return (str); 188 189 return (NULL); 190 } 191 192 bool 193 sysdecode_vmprot(FILE *fp, int type, int *rem) 194 { 195 196 return (print_mask_int(fp, vmprot, type, rem)); 197 } 198 199 static struct name_table sockflags[] = { 200 X(SOCK_CLOEXEC) X(SOCK_CLOFORK) X(SOCK_NONBLOCK) XEND 201 }; 202 203 bool 204 sysdecode_socket_type(FILE *fp, int type, int *rem) 205 { 206 const char *str; 207 uintmax_t val; 208 bool printed; 209 210 str = lookup_value(socktype, 211 type & ~(SOCK_CLOEXEC | SOCK_CLOFORK | SOCK_NONBLOCK)); 212 if (str != NULL) { 213 fputs(str, fp); 214 *rem = 0; 215 printed = true; 216 } else { 217 *rem = type & ~(SOCK_CLOEXEC | SOCK_CLOFORK | SOCK_NONBLOCK); 218 printed = false; 219 } 220 val = type & (SOCK_CLOEXEC | SOCK_CLOFORK | SOCK_NONBLOCK); 221 print_mask_part(fp, sockflags, &val, &printed); 222 return (printed); 223 } 224 225 bool 226 sysdecode_access_mode(FILE *fp, int mode, int *rem) 227 { 228 229 return (print_mask_int(fp, accessmode, mode, rem)); 230 } 231 232 /* XXX: 'type' is really an acl_type_t. */ 233 const char * 234 sysdecode_acltype(int type) 235 { 236 237 return (lookup_value(acltype, type)); 238 } 239 240 bool 241 sysdecode_cap_fcntlrights(FILE *fp, uint32_t rights, uint32_t *rem) 242 { 243 244 return (print_mask_int(fp, capfcntl, rights, rem)); 245 } 246 247 bool 248 sysdecode_close_range_flags(FILE *fp, int flags, int *rem) 249 { 250 251 return (print_mask_int(fp, closerangeflags, flags, rem)); 252 } 253 254 const char * 255 sysdecode_extattrnamespace(int namespace) 256 { 257 258 return (lookup_value(extattrns, namespace)); 259 } 260 261 const char * 262 sysdecode_fadvice(int advice) 263 { 264 265 return (lookup_value(fadvisebehav, advice)); 266 } 267 268 bool 269 sysdecode_open_flags(FILE *fp, int flags, int *rem) 270 { 271 bool printed; 272 int mode; 273 uintmax_t val; 274 275 mode = flags & O_ACCMODE; 276 flags &= ~O_ACCMODE; 277 switch (mode) { 278 case O_RDONLY: 279 if (flags & O_EXEC) { 280 flags &= ~O_EXEC; 281 fputs("O_EXEC", fp); 282 } else 283 fputs("O_RDONLY", fp); 284 printed = true; 285 mode = 0; 286 break; 287 case O_WRONLY: 288 fputs("O_WRONLY", fp); 289 printed = true; 290 mode = 0; 291 break; 292 case O_RDWR: 293 fputs("O_RDWR", fp); 294 printed = true; 295 mode = 0; 296 break; 297 default: 298 printed = false; 299 } 300 val = (unsigned)flags; 301 print_mask_part(fp, openflags, &val, &printed); 302 if (rem != NULL) 303 *rem = val | mode; 304 return (printed); 305 } 306 307 bool 308 sysdecode_fcntl_fileflags(FILE *fp, int flags, int *rem) 309 { 310 bool printed; 311 int oflags; 312 313 /* 314 * The file flags used with F_GETFL/F_SETFL mostly match the 315 * flags passed to open(2). However, a few open-only flag 316 * bits have been repurposed for fcntl-only flags. 317 */ 318 oflags = flags & ~(O_NOFOLLOW | FRDAHEAD); 319 printed = sysdecode_open_flags(fp, oflags, rem); 320 if (flags & O_NOFOLLOW) { 321 fprintf(fp, "%sFPOIXSHM", printed ? "|" : ""); 322 printed = true; 323 } 324 if (flags & FRDAHEAD) { 325 fprintf(fp, "%sFRDAHEAD", printed ? "|" : ""); 326 printed = true; 327 } 328 return (printed); 329 } 330 331 bool 332 sysdecode_flock_operation(FILE *fp, int operation, int *rem) 333 { 334 335 return (print_mask_int(fp, flockops, operation, rem)); 336 } 337 338 static struct name_table getfsstatmode[] = { 339 X(MNT_WAIT) X(MNT_NOWAIT) XEND 340 }; 341 342 const char * 343 sysdecode_getfsstat_mode(int mode) 344 { 345 346 return (lookup_value(getfsstatmode, mode)); 347 } 348 349 const char * 350 sysdecode_getrusage_who(int who) 351 { 352 353 return (lookup_value(rusage, who)); 354 } 355 356 bool 357 sysdecode_inotifyflags(FILE *fp, int flag, int *rem) 358 { 359 360 return (print_mask_int(fp, inotifyflags, flag, rem)); 361 } 362 363 static struct name_table kevent_user_ffctrl[] = { 364 X(NOTE_FFNOP) X(NOTE_FFAND) X(NOTE_FFOR) X(NOTE_FFCOPY) 365 XEND 366 }; 367 368 static struct name_table kevent_rdwr_fflags[] = { 369 X(NOTE_LOWAT) X(NOTE_FILE_POLL) XEND 370 }; 371 372 static struct name_table kevent_vnode_fflags[] = { 373 X(NOTE_DELETE) X(NOTE_WRITE) X(NOTE_EXTEND) X(NOTE_ATTRIB) 374 X(NOTE_LINK) X(NOTE_RENAME) X(NOTE_REVOKE) X(NOTE_OPEN) X(NOTE_CLOSE) 375 X(NOTE_CLOSE_WRITE) X(NOTE_READ) XEND 376 }; 377 378 static struct name_table kevent_proc_fflags[] = { 379 X(NOTE_EXIT) X(NOTE_FORK) X(NOTE_EXEC) X(NOTE_TRACK) X(NOTE_TRACKERR) 380 X(NOTE_CHILD) XEND 381 }; 382 383 static struct name_table kevent_timer_fflags[] = { 384 X(NOTE_SECONDS) X(NOTE_MSECONDS) X(NOTE_USECONDS) X(NOTE_NSECONDS) 385 X(NOTE_ABSTIME) XEND 386 }; 387 388 void 389 sysdecode_kevent_fflags(FILE *fp, short filter, int fflags, int base) 390 { 391 int rem; 392 393 if (fflags == 0) { 394 fputs("0", fp); 395 return; 396 } 397 398 switch (filter) { 399 case EVFILT_READ: 400 case EVFILT_WRITE: 401 if (!print_mask_int(fp, kevent_rdwr_fflags, fflags, &rem)) 402 fprintf(fp, "%#x", rem); 403 else if (rem != 0) 404 fprintf(fp, "|%#x", rem); 405 break; 406 case EVFILT_VNODE: 407 if (!print_mask_int(fp, kevent_vnode_fflags, fflags, &rem)) 408 fprintf(fp, "%#x", rem); 409 else if (rem != 0) 410 fprintf(fp, "|%#x", rem); 411 break; 412 case EVFILT_PROC: 413 case EVFILT_PROCDESC: 414 if (!print_mask_int(fp, kevent_proc_fflags, fflags, &rem)) 415 fprintf(fp, "%#x", rem); 416 else if (rem != 0) 417 fprintf(fp, "|%#x", rem); 418 break; 419 case EVFILT_TIMER: 420 if (!print_mask_int(fp, kevent_timer_fflags, fflags, &rem)) 421 fprintf(fp, "%#x", rem); 422 else if (rem != 0) 423 fprintf(fp, "|%#x", rem); 424 break; 425 case EVFILT_USER: { 426 unsigned int ctrl, data; 427 428 ctrl = fflags & NOTE_FFCTRLMASK; 429 data = fflags & NOTE_FFLAGSMASK; 430 431 if (fflags & NOTE_TRIGGER) { 432 fputs("NOTE_TRIGGER", fp); 433 if (fflags == NOTE_TRIGGER) 434 return; 435 fputc('|', fp); 436 } 437 438 /* 439 * An event with 'ctrl' == NOTE_FFNOP is either a reported 440 * (output) event for which only 'data' should be output 441 * or a pointless input event. Assume that pointless 442 * input events don't occur in practice. An event with 443 * NOTE_TRIGGER is always an input event. 444 */ 445 if (ctrl != NOTE_FFNOP || fflags & NOTE_TRIGGER) { 446 fprintf(fp, "%s|%#x", 447 lookup_value(kevent_user_ffctrl, ctrl), data); 448 } else { 449 print_integer(fp, data, base); 450 } 451 break; 452 } 453 default: 454 print_integer(fp, fflags, base); 455 break; 456 } 457 } 458 459 bool 460 sysdecode_kevent_flags(FILE *fp, int flags, int *rem) 461 { 462 463 return (print_mask_int(fp, keventflags, flags, rem)); 464 } 465 466 const char * 467 sysdecode_kevent_filter(int filter) 468 { 469 470 return (lookup_value(keventfilters, filter)); 471 } 472 473 const char * 474 sysdecode_kldsym_cmd(int cmd) 475 { 476 477 return (lookup_value(kldsymcmd, cmd)); 478 } 479 480 const char * 481 sysdecode_kldunload_flags(int flags) 482 { 483 484 return (lookup_value(kldunloadfflags, flags)); 485 } 486 487 const char * 488 sysdecode_lio_listio_mode(int mode) 489 { 490 491 return (lookup_value(lio_listiomodes, mode)); 492 } 493 494 const char * 495 sysdecode_madvice(int advice) 496 { 497 498 return (lookup_value(madvisebehav, advice)); 499 } 500 501 const char * 502 sysdecode_minherit_inherit(int inherit) 503 { 504 505 return (lookup_value(minheritflags, inherit)); 506 } 507 508 bool 509 sysdecode_mlockall_flags(FILE *fp, int flags, int *rem) 510 { 511 512 return (print_mask_int(fp, mlockallflags, flags, rem)); 513 } 514 515 bool 516 sysdecode_mmap_prot(FILE *fp, int prot, int *rem) 517 { 518 int protm; 519 bool printed; 520 521 printed = false; 522 protm = PROT_MAX_EXTRACT(prot); 523 prot &= ~PROT_MAX(protm); 524 if (protm != 0) { 525 fputs("PROT_MAX(", fp); 526 printed = print_mask_int(fp, mmapprot, protm, rem); 527 fputs(")|", fp); 528 } 529 return (print_mask_int(fp, mmapprot, prot, rem) || printed); 530 } 531 532 bool 533 sysdecode_fileflags(FILE *fp, fflags_t flags, fflags_t *rem) 534 { 535 536 return (print_mask_0(fp, fileflags, flags, rem)); 537 } 538 539 bool 540 sysdecode_filemode(FILE *fp, int mode, int *rem) 541 { 542 543 return (print_mask_0(fp, filemode, mode, rem)); 544 } 545 546 bool 547 sysdecode_mount_flags(FILE *fp, int flags, int *rem) 548 { 549 550 return (print_mask_int(fp, mountflags, flags, rem)); 551 } 552 553 bool 554 sysdecode_msync_flags(FILE *fp, int flags, int *rem) 555 { 556 557 return (print_mask_int(fp, msyncflags, flags, rem)); 558 } 559 560 const char * 561 sysdecode_nfssvc_flags(int flags) 562 { 563 564 return (lookup_value(nfssvcflags, flags)); 565 } 566 567 static struct name_table pipe2flags[] = { 568 X(O_CLOEXEC) X(O_CLOFORK) X(O_NONBLOCK) XEND 569 }; 570 571 bool 572 sysdecode_pipe2_flags(FILE *fp, int flags, int *rem) 573 { 574 575 return (print_mask_0(fp, pipe2flags, flags, rem)); 576 } 577 578 bool 579 sysdecode_pollfd_events(FILE *fp, int flags, int *rem) 580 { 581 582 return (print_mask_int(fp, pollfdevents, flags, rem)); 583 } 584 585 const char * 586 sysdecode_prio_which(int which) 587 { 588 589 return (lookup_value(prio, which)); 590 } 591 592 const char * 593 sysdecode_procctl_cmd(int cmd) 594 { 595 596 return (lookup_value(procctlcmd, cmd)); 597 } 598 599 const char * 600 sysdecode_ptrace_request(int request) 601 { 602 603 return (lookup_value(ptraceop, request)); 604 } 605 606 static struct name_table quotatypes[] = { 607 X(GRPQUOTA) X(USRQUOTA) XEND 608 }; 609 610 bool 611 sysdecode_quotactl_cmd(FILE *fp, int cmd) 612 { 613 const char *primary, *type; 614 615 primary = lookup_value(quotactlcmds, cmd >> SUBCMDSHIFT); 616 if (primary == NULL) 617 return (false); 618 fprintf(fp, "QCMD(%s,", primary); 619 type = lookup_value(quotatypes, cmd & SUBCMDMASK); 620 if (type != NULL) 621 fprintf(fp, "%s", type); 622 else 623 fprintf(fp, "%#x", cmd & SUBCMDMASK); 624 fprintf(fp, ")"); 625 return (true); 626 } 627 628 bool 629 sysdecode_reboot_howto(FILE *fp, int howto, int *rem) 630 { 631 bool printed; 632 633 /* 634 * RB_AUTOBOOT is special in that its value is zero, but it is 635 * also an implied argument if a different operation is not 636 * requested via RB_HALT, RB_POWERCYCLE, RB_POWEROFF, or 637 * RB_REROOT. 638 */ 639 if (howto != 0 && (howto & (RB_HALT | RB_POWEROFF | RB_REROOT | 640 RB_POWERCYCLE)) == 0) { 641 fputs("RB_AUTOBOOT|", fp); 642 printed = true; 643 } else 644 printed = false; 645 return (print_mask_int(fp, rebootopt, howto, rem) || printed); 646 } 647 648 bool 649 sysdecode_rfork_flags(FILE *fp, int flags, int *rem) 650 { 651 652 return (print_mask_int(fp, rforkflags, flags, rem)); 653 } 654 655 const char * 656 sysdecode_rlimit(int resource) 657 { 658 659 return (lookup_value(rlimit, resource)); 660 } 661 662 const char * 663 sysdecode_scheduler_policy(int policy) 664 { 665 666 return (lookup_value(schedpolicy, policy)); 667 } 668 669 bool 670 sysdecode_sendfile_flags(FILE *fp, int flags, int *rem) 671 { 672 673 return (print_mask_int(fp, sendfileflags, flags, rem)); 674 } 675 676 bool 677 sysdecode_shmat_flags(FILE *fp, int flags, int *rem) 678 { 679 680 return (print_mask_int(fp, shmatflags, flags, rem)); 681 } 682 683 const char * 684 sysdecode_shutdown_how(int how) 685 { 686 687 return (lookup_value(shutdownhow, how)); 688 } 689 690 const char * 691 sysdecode_sigbus_code(int si_code) 692 { 693 694 return (lookup_value(sigbuscode, si_code)); 695 } 696 697 const char * 698 sysdecode_sigchld_code(int si_code) 699 { 700 701 return (lookup_value(sigchldcode, si_code)); 702 } 703 704 const char * 705 sysdecode_sigfpe_code(int si_code) 706 { 707 708 return (lookup_value(sigfpecode, si_code)); 709 } 710 711 const char * 712 sysdecode_sigill_code(int si_code) 713 { 714 715 return (lookup_value(sigillcode, si_code)); 716 } 717 718 const char * 719 sysdecode_sigsegv_code(int si_code) 720 { 721 722 return (lookup_value(sigsegvcode, si_code)); 723 } 724 725 const char * 726 sysdecode_sigtrap_code(int si_code) 727 { 728 729 return (lookup_value(sigtrapcode, si_code)); 730 } 731 732 const char * 733 sysdecode_sigprocmask_how(int how) 734 { 735 736 return (lookup_value(sigprocmaskhow, how)); 737 } 738 739 const char * 740 sysdecode_socketdomain(int domain) 741 { 742 743 return (lookup_value(sockdomain, domain)); 744 } 745 746 const char * 747 sysdecode_socket_protocol(int domain, int protocol) 748 { 749 750 switch (domain) { 751 case PF_INET: 752 case PF_INET6: 753 return (lookup_value(sockipproto, protocol)); 754 default: 755 return (NULL); 756 } 757 } 758 759 const char * 760 sysdecode_sockaddr_family(int sa_family) 761 { 762 763 return (lookup_value(sockfamily, sa_family)); 764 } 765 766 const char * 767 sysdecode_ipproto(int protocol) 768 { 769 770 return (lookup_value(sockipproto, protocol)); 771 } 772 773 const char * 774 sysdecode_sockopt_name(int level, int optname) 775 { 776 777 if (level == SOL_SOCKET) 778 return (lookup_value(sockopt, optname)); 779 if (level == IPPROTO_IP) 780 /* XXX: UNIX domain socket options use a level of 0 also. */ 781 return (lookup_value(sockoptip, optname)); 782 if (level == IPPROTO_IPV6) 783 return (lookup_value(sockoptipv6, optname)); 784 if (level == IPPROTO_SCTP) 785 return (lookup_value(sockoptsctp, optname)); 786 if (level == IPPROTO_TCP) 787 return (lookup_value(sockopttcp, optname)); 788 if (level == IPPROTO_UDP) 789 return (lookup_value(sockoptudp, optname)); 790 if (level == IPPROTO_UDPLITE) 791 return (lookup_value(sockoptudplite, optname)); 792 return (NULL); 793 } 794 795 bool 796 sysdecode_thr_create_flags(FILE *fp, int flags, int *rem) 797 { 798 799 return (print_mask_int(fp, thrcreateflags, flags, rem)); 800 } 801 802 const char * 803 sysdecode_umtx_op(int op) 804 { 805 806 return (lookup_value(umtxop, op)); 807 } 808 809 bool 810 sysdecode_umtx_op_flags(FILE *fp, int op, int *rem) 811 { 812 uintmax_t val; 813 bool printed; 814 815 printed = false; 816 val = (unsigned)op; 817 print_mask_part(fp, umtxopflags, &val, &printed); 818 if (rem != NULL) 819 *rem = val; 820 return (printed); 821 } 822 823 const char * 824 sysdecode_vmresult(int result) 825 { 826 827 return (lookup_value(vmresult, result)); 828 } 829 830 bool 831 sysdecode_wait4_options(FILE *fp, int options, int *rem) 832 { 833 bool printed; 834 int opt6; 835 836 /* A flags value of 0 is normal. */ 837 if (options == 0) { 838 fputs("0", fp); 839 if (rem != NULL) 840 *rem = 0; 841 return (true); 842 } 843 844 /* 845 * These flags are implicit and aren't valid flags for wait4() 846 * directly (though they don't fail with EINVAL). 847 */ 848 opt6 = options & (WEXITED | WTRAPPED); 849 options &= ~opt6; 850 printed = print_mask_int(fp, wait6opt, options, rem); 851 if (rem != NULL) 852 *rem |= opt6; 853 return (printed); 854 } 855 856 bool 857 sysdecode_wait6_options(FILE *fp, int options, int *rem) 858 { 859 860 return (print_mask_int(fp, wait6opt, options, rem)); 861 } 862 863 const char * 864 sysdecode_whence(int whence) 865 { 866 867 return (lookup_value(seekwhence, whence)); 868 } 869 870 const char * 871 sysdecode_fcntl_cmd(int cmd) 872 { 873 874 return (lookup_value(fcntlcmd, cmd)); 875 } 876 877 static struct name_table fcntl_fd_arg[] = { 878 X(FD_CLOEXEC) X(FD_CLOFORK) X(0) XEND 879 }; 880 881 bool 882 sysdecode_fcntl_arg_p(int cmd) 883 { 884 885 switch (cmd) { 886 case F_GETFD: 887 case F_GETFL: 888 case F_GETOWN: 889 return (false); 890 default: 891 return (true); 892 } 893 } 894 895 void 896 sysdecode_fcntl_arg(FILE *fp, int cmd, uintptr_t arg, int base) 897 { 898 int rem; 899 900 switch (cmd) { 901 case F_SETFD: 902 if (!print_value(fp, fcntl_fd_arg, arg)) 903 print_integer(fp, arg, base); 904 break; 905 case F_SETFL: 906 if (!sysdecode_fcntl_fileflags(fp, arg, &rem)) 907 fprintf(fp, "%#x", rem); 908 else if (rem != 0) 909 fprintf(fp, "|%#x", rem); 910 break; 911 case F_GETLK: 912 case F_SETLK: 913 case F_SETLKW: 914 fprintf(fp, "%p", (void *)arg); 915 break; 916 default: 917 print_integer(fp, arg, base); 918 break; 919 } 920 } 921 922 bool 923 sysdecode_mmap_flags(FILE *fp, int flags, int *rem) 924 { 925 uintmax_t val; 926 bool printed; 927 int align; 928 929 /* 930 * MAP_ALIGNED can't be handled directly by print_mask_int(). 931 */ 932 printed = false; 933 align = flags & MAP_ALIGNMENT_MASK; 934 val = (unsigned)flags & ~MAP_ALIGNMENT_MASK; 935 print_mask_part(fp, mmapflags, &val, &printed); 936 if (align != 0) { 937 if (printed) 938 fputc('|', fp); 939 if (align == MAP_ALIGNED_SUPER) 940 fputs("MAP_ALIGNED_SUPER", fp); 941 else 942 fprintf(fp, "MAP_ALIGNED(%d)", 943 align >> MAP_ALIGNMENT_SHIFT); 944 printed = true; 945 } 946 if (rem != NULL) 947 *rem = val; 948 return (printed); 949 } 950 951 const char * 952 sysdecode_pathconf_name(int name) 953 { 954 955 return (lookup_value(pathconfname, name)); 956 } 957 958 const char * 959 sysdecode_rtprio_function(int function) 960 { 961 962 return (lookup_value(rtpriofuncs, function)); 963 } 964 965 bool 966 sysdecode_msg_flags(FILE *fp, int flags, int *rem) 967 { 968 969 return (print_mask_0(fp, msgflags, flags, rem)); 970 } 971 972 const char * 973 sysdecode_sigcode(int sig, int si_code) 974 { 975 const char *str; 976 977 str = lookup_value(sigcode, si_code); 978 if (str != NULL) 979 return (str); 980 981 switch (sig) { 982 case SIGILL: 983 return (sysdecode_sigill_code(si_code)); 984 case SIGBUS: 985 return (sysdecode_sigbus_code(si_code)); 986 case SIGSEGV: 987 return (sysdecode_sigsegv_code(si_code)); 988 case SIGFPE: 989 return (sysdecode_sigfpe_code(si_code)); 990 case SIGTRAP: 991 return (sysdecode_sigtrap_code(si_code)); 992 case SIGCHLD: 993 return (sysdecode_sigchld_code(si_code)); 994 default: 995 return (NULL); 996 } 997 } 998 999 const char * 1000 sysdecode_sysarch_number(int number) 1001 { 1002 1003 return (lookup_value(sysarchnum, number)); 1004 } 1005 1006 bool 1007 sysdecode_umtx_cvwait_flags(FILE *fp, u_long flags, u_long *rem) 1008 { 1009 1010 return (print_mask_0ul(fp, umtxcvwaitflags, flags, rem)); 1011 } 1012 1013 bool 1014 sysdecode_umtx_rwlock_flags(FILE *fp, u_long flags, u_long *rem) 1015 { 1016 1017 return (print_mask_0ul(fp, umtxrwlockflags, flags, rem)); 1018 } 1019 1020 void 1021 sysdecode_cap_rights(FILE *fp, cap_rights_t *rightsp) 1022 { 1023 cap_rights_t diff, sum, zero; 1024 const struct name_table *t; 1025 int i; 1026 bool comma; 1027 1028 for (i = 0; i < CAPARSIZE(rightsp); i++) { 1029 if (CAPIDXBIT(rightsp->cr_rights[i]) != 1 << i) { 1030 fprintf(fp, "invalid cap_rights_t"); 1031 return; 1032 } 1033 } 1034 cap_rights_init(&sum); 1035 diff = *rightsp; 1036 for (t = caprights, comma = false; t->str != NULL; t++) { 1037 if (cap_rights_is_set(rightsp, t->val)) { 1038 cap_rights_clear(&diff, t->val); 1039 if (cap_rights_is_set(&sum, t->val)) { 1040 /* Don't print redundant rights. */ 1041 continue; 1042 } 1043 cap_rights_set(&sum, t->val); 1044 1045 fprintf(fp, "%s%s", comma ? "," : "", t->str); 1046 comma = true; 1047 } 1048 } 1049 if (!comma) 1050 fprintf(fp, "CAP_NONE"); 1051 1052 /* 1053 * Provide a breadcrumb if some of the provided rights are not included 1054 * in the table, likely due to a bug in the mktables script. 1055 */ 1056 CAP_NONE(&zero); 1057 if (!cap_rights_contains(&zero, &diff)) 1058 fprintf(fp, ",unknown rights"); 1059 } 1060 1061 /* 1062 * Pre-sort the set of rights, which has a partial ordering defined by the 1063 * subset relation. This lets sysdecode_cap_rights() print a list of minimal 1064 * length with a single pass over the "caprights" table. 1065 */ 1066 static void __attribute__((constructor)) 1067 sysdecode_cap_rights_init(void) 1068 { 1069 cap_rights_t tr, qr; 1070 struct name_table *t, *q, tmp; 1071 bool swapped; 1072 1073 do { 1074 for (t = caprights, swapped = false; t->str != NULL; t++) { 1075 cap_rights_init(&tr, t->val); 1076 for (q = t + 1; q->str != NULL; q++) { 1077 cap_rights_init(&qr, q->val); 1078 if (cap_rights_contains(&qr, &tr)) { 1079 tmp = *t; 1080 *t = *q; 1081 *q = tmp; 1082 swapped = true; 1083 } 1084 } 1085 } 1086 } while (swapped); 1087 } 1088 1089 static struct name_table cmsgtypeip[] = { 1090 X(IP_RECVDSTADDR) X(IP_RECVTTL) X(IP_RECVOPTS) X(IP_RECVRETOPTS) 1091 X(IP_RECVIF) X(IP_RECVTOS) X(IP_FLOWID) X(IP_FLOWTYPE) 1092 X(IP_RSSBUCKETID) XEND 1093 }; 1094 1095 static struct name_table cmsgtypeipv6[] = { 1096 #if 0 1097 /* The RFC 2292 defines are kernel space only. */ 1098 X(IPV6_2292PKTINFO) X(IPV6_2292HOPLIMIT) X(IPV6_2292HOPOPTS) 1099 X(IPV6_2292DSTOPTS) X(IPV6_2292RTHDR) X(IPV6_2292NEXTHOP) 1100 #endif 1101 X(IPV6_PKTINFO) X(IPV6_HOPLIMIT) X(IPV6_HOPOPTS) 1102 X(IPV6_DSTOPTS) X(IPV6_RTHDR) X(IPV6_NEXTHOP) 1103 X(IPV6_TCLASS) X(IPV6_FLOWID) X(IPV6_FLOWTYPE) X(IPV6_RSSBUCKETID) 1104 X(IPV6_PATHMTU) X(IPV6_RTHDRDSTOPTS) X(IPV6_USE_MIN_MTU) 1105 X(IPV6_DONTFRAG) X(IPV6_PREFER_TEMPADDR) XEND 1106 }; 1107 1108 static struct name_table cmsgtypesctp[] = { 1109 X(SCTP_INIT) X(SCTP_SNDRCV) X(SCTP_EXTRCV) X(SCTP_SNDINFO) 1110 X(SCTP_RCVINFO) X(SCTP_NXTINFO) X(SCTP_PRINFO) X(SCTP_AUTHINFO) 1111 X(SCTP_DSTADDRV4) X(SCTP_DSTADDRV6) XEND 1112 }; 1113 1114 const char * 1115 sysdecode_cmsg_type(int cmsg_level, int cmsg_type) 1116 { 1117 1118 if (cmsg_level == SOL_SOCKET) 1119 return (lookup_value(cmsgtypesocket, cmsg_type)); 1120 if (cmsg_level == IPPROTO_IP) 1121 return (lookup_value(cmsgtypeip, cmsg_type)); 1122 if (cmsg_level == IPPROTO_IPV6) 1123 return (lookup_value(cmsgtypeipv6, cmsg_type)); 1124 if (cmsg_level == IPPROTO_SCTP) 1125 return (lookup_value(cmsgtypesctp, cmsg_type)); 1126 return (NULL); 1127 } 1128 1129 const char * 1130 sysdecode_sctp_pr_policy(int policy) 1131 { 1132 1133 return (lookup_value(sctpprpolicy, policy)); 1134 } 1135 1136 static struct name_table sctpsndflags[] = { 1137 X(SCTP_EOF) X(SCTP_ABORT) X(SCTP_UNORDERED) X(SCTP_ADDR_OVER) 1138 X(SCTP_SENDALL) X(SCTP_EOR) X(SCTP_SACK_IMMEDIATELY) XEND 1139 }; 1140 1141 bool 1142 sysdecode_sctp_snd_flags(FILE *fp, int flags, int *rem) 1143 { 1144 1145 return (print_mask_int(fp, sctpsndflags, flags, rem)); 1146 } 1147 1148 static struct name_table sctprcvflags[] = { 1149 X(SCTP_UNORDERED) XEND 1150 }; 1151 1152 bool 1153 sysdecode_sctp_rcv_flags(FILE *fp, int flags, int *rem) 1154 { 1155 1156 return (print_mask_int(fp, sctprcvflags, flags, rem)); 1157 } 1158 1159 static struct name_table sctpnxtflags[] = { 1160 X(SCTP_UNORDERED) X(SCTP_COMPLETE) X(SCTP_NOTIFICATION) XEND 1161 }; 1162 1163 bool 1164 sysdecode_sctp_nxt_flags(FILE *fp, int flags, int *rem) 1165 { 1166 1167 return (print_mask_int(fp, sctpnxtflags, flags, rem)); 1168 } 1169 1170 static struct name_table sctpsinfoflags[] = { 1171 X(SCTP_EOF) X(SCTP_ABORT) X(SCTP_UNORDERED) X(SCTP_ADDR_OVER) 1172 X(SCTP_SENDALL) X(SCTP_EOR) X(SCTP_SACK_IMMEDIATELY) XEND 1173 }; 1174 1175 void 1176 sysdecode_sctp_sinfo_flags(FILE *fp, int sinfo_flags) 1177 { 1178 const char *temp; 1179 int rem; 1180 bool printed; 1181 1182 printed = print_mask_0(fp, sctpsinfoflags, sinfo_flags, &rem); 1183 if (rem & ~SCTP_PR_SCTP_ALL) { 1184 fprintf(fp, "%s%#x", printed ? "|" : "", rem & ~SCTP_PR_SCTP_ALL); 1185 printed = true; 1186 rem &= ~SCTP_PR_SCTP_ALL; 1187 } 1188 if (rem != 0) { 1189 temp = sysdecode_sctp_pr_policy(rem); 1190 if (temp != NULL) { 1191 fprintf(fp, "%s%s", printed ? "|" : "", temp); 1192 } else { 1193 fprintf(fp, "%s%#x", printed ? "|" : "", rem); 1194 } 1195 } 1196 } 1197 1198 bool 1199 sysdecode_shmflags(FILE *fp, int flags, int *rem) 1200 { 1201 1202 return (print_mask_0(fp, shmflags, flags, rem)); 1203 } 1204 1205 const char * 1206 sysdecode_itimer(int which) 1207 { 1208 1209 return (lookup_value(itimerwhich, which)); 1210 } 1211 1212 const char * 1213 sysdecode_pfnl_cmd(int cmd) 1214 { 1215 1216 return (lookup_value(pfnl_cmd, cmd)); 1217 } 1218