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