static int do_accept(struct tcb *tcp, int flags_arg) { if (entering(tcp)) { printfd(tcp, tcp->u_arg[0]); tprints(", "); return 0; } if (!tcp->u_arg[2]) tprintf("%#lx, NULL", tcp->u_arg[1]); else { int len; if (tcp->u_arg[1] == 0 || syserror(tcp) || umove(tcp, tcp->u_arg[2], &len) < 0) { tprintf("%#lx", tcp->u_arg[1]); } else { printsock(tcp, tcp->u_arg[1], len); } tprints(", "); printnum_int(tcp, tcp->u_arg[2], "%u"); } if (flags_arg >= 0) { tprints(", "); printflags(sock_type_flags, tcp->u_arg[flags_arg], "SOCK_???"); } return 0; }
static void print_getsockopt(struct tcb *tcp, unsigned int level, unsigned int name, long addr, int len) { if (addr && verbose(tcp)) switch (level) { case SOL_SOCKET: switch (name) { #ifdef SO_LINGER case SO_LINGER: print_linger(tcp, addr, len); goto done; #endif #ifdef SO_PEERCRED case SO_PEERCRED: print_ucred(tcp, addr, len); goto done; #endif } break; case SOL_PACKET: switch (name) { #ifdef PACKET_STATISTICS case PACKET_STATISTICS: print_tpacket_stats(tcp, addr, len); goto done; #endif } break; case SOL_RAW: switch (name) { #ifdef ICMP_FILTER case ICMP_FILTER: print_icmp_filter(tcp, addr, len); goto done; #endif } break; } /* default arg printing */ if (verbose(tcp)) { if (len == sizeof(int)) { printnum_int(tcp, addr, "%d"); } else { printstr(tcp, addr, len); } } else { printaddr(addr); } done: tprintf(", [%d]", len); }
bool printnum_long_int(struct tcb *const tcp, const kernel_ulong_t addr, const char *const fmt_long, const char *const fmt_int) { if (current_wordsize > sizeof(int)) { return printnum_int64(tcp, addr, fmt_long); } else { return printnum_int(tcp, addr, fmt_int); } }
static int bit_ioctl(struct tcb *const tcp, const unsigned int ev_nr, const kernel_ulong_t arg) { switch (ev_nr) { case EV_SYN: return decode_bitset(tcp, arg, evdev_sync, SYN_MAX, "SYN_???"); case EV_KEY: return decode_bitset(tcp, arg, evdev_keycode, KEY_MAX, "KEY_???"); case EV_REL: return decode_bitset(tcp, arg, evdev_relative_axes, REL_MAX, "REL_???"); case EV_ABS: return decode_bitset(tcp, arg, evdev_abs, ABS_MAX, "ABS_???"); case EV_MSC: return decode_bitset(tcp, arg, evdev_misc, MSC_MAX, "MSC_???"); # ifdef EV_SW case EV_SW: return decode_bitset(tcp, arg, evdev_switch, SW_MAX, "SW_???"); # endif case EV_LED: return decode_bitset(tcp, arg, evdev_leds, LED_MAX, "LED_???"); case EV_SND: return decode_bitset(tcp, arg, evdev_snd, SND_MAX, "SND_???"); case EV_REP: return decode_bitset(tcp, arg, evdev_autorepeat, REP_MAX, "REP_???"); case EV_FF: return decode_bitset(tcp, arg, evdev_ff_types, FF_MAX, "FF_???"); case EV_PWR: tprints(", "); printnum_int(tcp, arg, "%d"); return 1; case EV_FF_STATUS: return decode_bitset(tcp, arg, evdev_ff_status, FF_STATUS_MAX, "FF_STATUS_???"); default: tprints(", "); printaddr(arg); return 1; } }
static int evdev_write_ioctl(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t arg) { /* fixed-number fixed-length commands */ switch (code) { # ifdef EVIOCSREP case EVIOCSREP: return repeat_ioctl(tcp, arg); # endif case EVIOCSKEYCODE: return keycode_ioctl(tcp, arg); # ifdef EVIOCSKEYCODE_V2 case EVIOCSKEYCODE_V2: return keycode_V2_ioctl(tcp, arg); # endif case EVIOCSFF: return ff_effect_ioctl(tcp, arg); case EVIOCRMFF: tprintf(", %d", (int) arg); return 1; case EVIOCGRAB: # ifdef EVIOCREVOKE case EVIOCREVOKE: # endif tprintf(", %" PRI_klu, arg); return 1; # ifdef EVIOCSCLOCKID case EVIOCSCLOCKID: tprints(", "); printnum_int(tcp, arg, "%u"); return 1; # endif } /* multi-number fixed-length commands */ if ((_IOC_NR(code) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) return abs_ioctl(tcp, arg); return 0; }
static int printsockopt(struct tcb *tcp, int level, int name, long addr, int len) { printxval(socketlayers, level, "SOL_??"); tprints(", "); switch (level) { case SOL_SOCKET: printxval(sockoptions, name, "SO_???"); switch (name) { #if defined(SO_LINGER) case SO_LINGER: if (len == sizeof(struct linger)) { struct linger linger; if (umove(tcp, addr, &linger) < 0) break; tprintf(", {onoff=%d, linger=%d}", linger.l_onoff, linger.l_linger); return 0; } break; #endif } break; #ifdef SOL_IP case SOL_IP: printxval(sockipoptions, name, "IP_???"); break; #endif #ifdef SOL_IPV6 case SOL_IPV6: printxval(sockipv6options, name, "IPV6_???"); break; #endif #ifdef SOL_IPX case SOL_IPX: printxval(sockipxoptions, name, "IPX_???"); break; #endif #ifdef SOL_PACKET case SOL_PACKET: printxval(sockpacketoptions, name, "PACKET_???"); /* TODO: decode packate_mreq for PACKET_*_MEMBERSHIP */ switch (name) { #ifdef PACKET_RX_RING case PACKET_RX_RING: #endif #ifdef PACKET_TX_RING case PACKET_TX_RING: #endif #if defined(PACKET_RX_RING) || defined(PACKET_TX_RING) if (len == sizeof(struct tpacket_req)) { struct tpacket_req req; if (umove(tcp, addr, &req) < 0) break; tprintf(", {block_size=%u, block_nr=%u, frame_size=%u, frame_nr=%u}", req.tp_block_size, req.tp_block_nr, req.tp_frame_size, req.tp_frame_nr); return 0; } break; #endif /* PACKET_RX_RING || PACKET_TX_RING */ } break; #endif #ifdef SOL_TCP case SOL_TCP: printxval(socktcpoptions, name, "TCP_???"); break; #endif #ifdef SOL_SCTP case SOL_SCTP: printxval(socksctpoptions, name, "SCTP_???"); break; #endif #ifdef SOL_RAW case SOL_RAW: printxval(sockrawoptions, name, "RAW_???"); switch (name) { #if defined(ICMP_FILTER) case ICMP_FILTER: tprints(", "); printicmpfilter(tcp, addr); return 0; #endif } break; #endif /* SOL_AX25 SOL_ATALK SOL_NETROM SOL_UDP SOL_DECNET SOL_X25 * etc. still need work */ default: tprintf("%u", name); } /* default arg printing */ tprints(", "); if (len == sizeof(int)) { printnum_int(tcp, addr, "%d"); } else { printstr(tcp, addr, len); } return 0; }
static void print_setsockopt(struct tcb *tcp, int level, int name, long addr, int len) { if (addr && verbose(tcp)) switch (level) { case SOL_SOCKET: switch (name) { #ifdef SO_LINGER case SO_LINGER: print_linger(tcp, addr, len); goto done; #endif } break; case SOL_IP: switch (name) { #ifdef IP_ADD_MEMBERSHIP case IP_ADD_MEMBERSHIP: case IP_DROP_MEMBERSHIP: print_mreq(tcp, addr, len); goto done; #endif /* IP_ADD_MEMBERSHIP */ #ifdef MCAST_JOIN_GROUP case MCAST_JOIN_GROUP: case MCAST_LEAVE_GROUP: print_group_req(tcp, addr, len); goto done; #endif /* MCAST_JOIN_GROUP */ } break; case SOL_IPV6: switch (name) { #ifdef IPV6_ADD_MEMBERSHIP case IPV6_ADD_MEMBERSHIP: case IPV6_DROP_MEMBERSHIP: # ifdef IPV6_JOIN_ANYCAST case IPV6_JOIN_ANYCAST: # endif # ifdef IPV6_LEAVE_ANYCAST case IPV6_LEAVE_ANYCAST: # endif print_mreq6(tcp, addr, len); goto done; #endif /* IPV6_ADD_MEMBERSHIP */ } break; case SOL_PACKET: switch (name) { #ifdef PACKET_RX_RING case PACKET_RX_RING: # ifdef PACKET_TX_RING case PACKET_TX_RING: # endif print_tpacket_req(tcp, addr, len); goto done; #endif /* PACKET_RX_RING */ #ifdef PACKET_ADD_MEMBERSHIP case PACKET_ADD_MEMBERSHIP: case PACKET_DROP_MEMBERSHIP: print_packet_mreq(tcp, addr, len); goto done; #endif /* PACKET_ADD_MEMBERSHIP */ } break; case SOL_RAW: switch (name) { #ifdef ICMP_FILTER case ICMP_FILTER: print_icmp_filter(tcp, addr, len); goto done; #endif } break; } /* default arg printing */ if (verbose(tcp)) { if (len == sizeof(int)) { printnum_int(tcp, addr, "%d"); } else { printstr(tcp, addr, len); } } else { printaddr(addr); } done: tprintf(", %d", len); }
int mtd_ioctl(struct tcb *tcp, const unsigned int code, const long arg) { if (!verbose(tcp)) return RVAL_DECODED; switch (code) { case MEMERASE: case MEMLOCK: case MEMUNLOCK: case MEMISLOCKED: { struct erase_info_user einfo; tprints(", "); if (umove_or_printaddr(tcp, arg, &einfo)) break; tprintf("{start=%#" PRIx32 ", length=%#" PRIx32 "}", einfo.start, einfo.length); break; } case MEMERASE64: { struct erase_info_user64 einfo64; tprints(", "); if (umove_or_printaddr(tcp, arg, &einfo64)) break; tprintf("{start=%#" PRIx64 ", length=%#" PRIx64 "}", (uint64_t) einfo64.start, (uint64_t) einfo64.length); break; } case MEMWRITEOOB: case MEMREADOOB: { struct mtd_oob_buf mbuf; tprints(", "); if (umove_or_printaddr(tcp, arg, &mbuf)) break; tprintf("{start=%#" PRIx32 ", length=%#" PRIx32 ", ptr=...}", mbuf.start, mbuf.length); break; } case MEMWRITEOOB64: case MEMREADOOB64: { struct mtd_oob_buf64 mbuf64; tprints(", "); if (umove_or_printaddr(tcp, arg, &mbuf64)) break; tprintf("{start=%#" PRIx64 ", length=%#" PRIx64 ", ptr=...}", (uint64_t) mbuf64.start, (uint64_t) mbuf64.length); break; } case MEMGETREGIONINFO: { struct region_info_user rinfo; if (entering(tcp)) { tprints(", "); if (umove_or_printaddr(tcp, arg, &rinfo)) break; tprintf("{regionindex=%#x", rinfo.regionindex); return 1; } else { if (syserror(tcp)) { tprints("}"); break; } if (umove(tcp, arg, &rinfo) < 0) { tprints(", ???}"); break; } tprintf(", offset=%#x, erasesize=%#x, numblocks=%#x}", rinfo.offset, rinfo.erasesize, rinfo.numblocks); break; } } case OTPLOCK: { struct otp_info oinfo; tprints(", "); if (umove_or_printaddr(tcp, arg, &oinfo)) break; tprintf("{start=%#" PRIx32 ", length=%#" PRIx32 ", locked=%" PRIu32 "}", oinfo.start, oinfo.length, oinfo.locked); break; } case MEMWRITE: { struct mtd_write_req mreq; tprints(", "); if (umove_or_printaddr(tcp, arg, &mreq)) break; tprintf("{start=%#" PRIx64 ", len=%#" PRIx64, (uint64_t) mreq.start, (uint64_t) mreq.len); tprintf(", ooblen=%#" PRIx64 ", usr_data=%#" PRIx64, (uint64_t) mreq.ooblen, (uint64_t) mreq.usr_data); tprintf(", usr_oob=%#" PRIx64 ", mode=", (uint64_t) mreq.usr_oob); printxval(mtd_mode_options, mreq.mode, "MTD_OPS_???"); tprints(", padding=...}"); break; } case OTPSELECT: { unsigned int i; tprints(", "); if (umove_or_printaddr(tcp, arg, &i)) break; tprints("["); printxval(mtd_otp_options, i, "MTD_OTP_???"); tprints("]"); break; } case MTDFILEMODE: tprints(", "); printxval(mtd_file_mode_options, arg, "MTD_FILE_MODE_???"); break; case MEMGETBADBLOCK: case MEMSETBADBLOCK: tprints(", "); print_loff_t(tcp, arg); break; case MEMGETINFO: { struct mtd_info_user minfo; if (entering(tcp)) return 0; tprints(", "); if (umove_or_printaddr(tcp, arg, &minfo)) break; tprints("{type="); printxval(mtd_type_options, minfo.type, "MTD_???"); tprints(", flags="); printflags(mtd_flags_options, minfo.flags, "MTD_???"); tprintf(", size=%#" PRIx32 ", erasesize=%#" PRIx32, minfo.size, minfo.erasesize); tprintf(", writesize=%#" PRIx32 ", oobsize=%#" PRIx32, minfo.writesize, minfo.oobsize); tprintf(", padding=%#" PRIx64 "}", (uint64_t) minfo.padding); break; } case MEMGETOOBSEL: { struct nand_oobinfo ninfo; unsigned int i; if (entering(tcp)) return 0; tprints(", "); if (umove_or_printaddr(tcp, arg, &ninfo)) break; tprints("{useecc="); printxval(mtd_nandecc_options, ninfo.useecc, "MTD_NANDECC_???"); tprintf(", eccbytes=%#" PRIx32, ninfo.eccbytes); tprints(", oobfree={"); for (i = 0; i < ARRAY_SIZE(ninfo.oobfree); ++i) { unsigned int j; if (i) tprints("}, "); tprints("{"); for (j = 0; j < ARRAY_SIZE(ninfo.oobfree[0]); ++j) { if (j) tprints(", "); tprintf("%#" PRIx32, ninfo.oobfree[i][j]); } } tprints("}}, eccpos={"); for (i = 0; i < ARRAY_SIZE(ninfo.eccpos); ++i) { if (i) tprints(", "); tprintf("%#" PRIx32, ninfo.eccpos[i]); } tprints("}"); break; } case OTPGETREGIONINFO: { struct otp_info oinfo; if (entering(tcp)) return 0; tprints(", "); if (umove_or_printaddr(tcp, arg, &oinfo)) break; tprintf("{start=%#" PRIx32 ", length=%#" PRIx32 ", locked=%" PRIu32 "}", oinfo.start, oinfo.length, oinfo.locked); break; } case ECCGETLAYOUT: { struct nand_ecclayout_user nlay; unsigned int i; if (entering(tcp)) return 0; tprints(", "); if (umove_or_printaddr(tcp, arg, &nlay)) break; tprintf("{eccbytes=%#" PRIx32 ", eccpos={", nlay.eccbytes); for (i = 0; i < ARRAY_SIZE(nlay.eccpos); ++i) { if (i) tprints(", "); tprintf("%#" PRIx32, nlay.eccpos[i]); } tprintf("}, oobavail=%#" PRIx32 ", oobfree={", nlay.oobavail); for (i = 0; i < ARRAY_SIZE(nlay.oobfree); ++i) { if (i) tprints(", "); tprintf("{offset=%#" PRIx32 ", length=%#" PRIx32 "}", nlay.oobfree[i].offset, nlay.oobfree[i].length); } tprints("}"); break; } case ECCGETSTATS: { struct mtd_ecc_stats estat; if (entering(tcp)) return 0; tprints(", "); if (umove_or_printaddr(tcp, arg, &estat)) break; tprintf("{corrected=%#" PRIx32 ", failed=%#" PRIx32, estat.corrected, estat.failed); tprintf(", badblocks=%#" PRIx32 ", bbtblocks=%#" PRIx32 "}", estat.badblocks, estat.bbtblocks); break; } case OTPGETREGIONCOUNT: if (entering(tcp)) return 0; tprints(", "); printnum_int(tcp, arg, "%u"); break; case MEMGETREGIONCOUNT: if (entering(tcp)) return 0; tprints(", "); printnum_int(tcp, arg, "%d"); break; default: return RVAL_DECODED; } return RVAL_DECODED | 1; }
int ubi_ioctl(struct tcb *tcp, const unsigned int code, const long arg) { if (!verbose(tcp)) return RVAL_DECODED; switch (code) { case UBI_IOCMKVOL: if (entering(tcp)) { struct ubi_mkvol_req mkvol; tprints(", "); if (umove_or_printaddr(tcp, arg, &mkvol)) break; tprintf("{vol_id=%" PRIi32 ", alignment=%" PRIi32 ", bytes=%" PRIi64 ", vol_type=", mkvol.vol_id, mkvol.alignment, (int64_t)mkvol.bytes); printxval(ubi_volume_types, mkvol.vol_type, "UBI_???_VOLUME"); tprintf(", name_len=%" PRIi16 ", name=", mkvol.name_len); if (print_quoted_string(mkvol.name, CLAMP(mkvol.name_len, 0, UBI_MAX_VOLUME_NAME), QUOTE_0_TERMINATED) > 0) { tprints("..."); } tprints("}"); return 1; } if (!syserror(tcp)) { tprints(" => "); printnum_int(tcp, arg, "%d"); } break; case UBI_IOCRSVOL: { struct ubi_rsvol_req rsvol; tprints(", "); if (umove_or_printaddr(tcp, arg, &rsvol)) break; tprintf("{vol_id=%" PRIi32 ", bytes=%" PRIi64 "}", rsvol.vol_id, (int64_t)rsvol.bytes); break; } case UBI_IOCRNVOL: { struct ubi_rnvol_req rnvol; int c; tprints(", "); if (umove_or_printaddr(tcp, arg, &rnvol)) break; tprintf("{count=%" PRIi32 ", ents=[", rnvol.count); for (c = 0; c < CLAMP(rnvol.count, 0, UBI_MAX_RNVOL); ++c) { if (c) tprints(", "); tprintf("{vol_id=%" PRIi32 ", name_len=%" PRIi16 ", name=", rnvol.ents[c].vol_id, rnvol.ents[c].name_len); if (print_quoted_string(rnvol.ents[c].name, CLAMP(rnvol.ents[c].name_len, 0, UBI_MAX_VOLUME_NAME), QUOTE_0_TERMINATED) > 0) { tprints("..."); } tprints("}"); } tprints("]}"); break; } case UBI_IOCEBCH: { struct ubi_leb_change_req leb; tprints(", "); if (umove_or_printaddr(tcp, arg, &leb)) break; tprintf("{lnum=%d, bytes=%d}", leb.lnum, leb.bytes); break; } case UBI_IOCATT: if (entering(tcp)) { struct ubi_attach_req attach; tprints(", "); if (umove_or_printaddr(tcp, arg, &attach)) break; tprintf("{ubi_num=%" PRIi32 ", mtd_num=%" PRIi32 ", vid_hdr_offset=%" PRIi32 ", max_beb_per1024=%" PRIi16 "}", attach.ubi_num, attach.mtd_num, attach.vid_hdr_offset, attach.max_beb_per1024); return 1; } if (!syserror(tcp)) { tprints(" => "); printnum_int(tcp, arg, "%d"); } break; case UBI_IOCEBMAP: { struct ubi_map_req map; tprints(", "); if (umove_or_printaddr(tcp, arg, &map)) break; tprintf("{lnum=%" PRIi32 ", dtype=%" PRIi8 "}", map.lnum, map.dtype); break; } case UBI_IOCSETVOLPROP: { struct ubi_set_vol_prop_req prop; tprints(", "); if (umove_or_printaddr(tcp, arg, &prop)) break; tprints("{property="); printxval(ubi_volume_props, prop.property, "UBI_VOL_PROP_???"); tprintf(", value=%#" PRIx64 "}", (uint64_t)prop.value); break; } case UBI_IOCVOLUP: tprints(", "); printnum_int64(tcp, arg, "%" PRIi64); break; case UBI_IOCDET: case UBI_IOCEBER: case UBI_IOCEBISMAP: case UBI_IOCEBUNMAP: case UBI_IOCRMVOL: tprints(", "); printnum_int(tcp, arg, "%d"); break; case UBI_IOCVOLCRBLK: case UBI_IOCVOLRMBLK: /* no arguments */ break; default: return RVAL_DECODED; } return RVAL_DECODED | 1; }
MPERS_PRINTER_DECL(int, sock_ioctl, struct tcb *tcp, const unsigned int code, const kernel_ulong_t arg) { struct_ifreq ifr; switch (code) { case SIOCGIFCONF: return decode_ifconf(tcp, arg); #ifdef SIOCBRADDBR case SIOCBRADDBR: case SIOCBRDELBR: tprints(", "); printstr(tcp, arg); break; #endif #ifdef FIOSETOWN case FIOSETOWN: #endif #ifdef SIOCSPGRP case SIOCSPGRP: #endif tprints(", "); printnum_int(tcp, arg, "%d"); break; #ifdef FIOGETOWN case FIOGETOWN: #endif #ifdef SIOCGPGRP case SIOCGPGRP: #endif #ifdef SIOCATMARK case SIOCATMARK: #endif if (entering(tcp)) return 0; tprints(", "); printnum_int(tcp, arg, "%d"); break; #ifdef SIOCBRADDIF case SIOCBRADDIF: #endif #ifdef SIOCBRDELIF case SIOCBRDELIF: #endif /* no arguments */ break; case SIOCSIFNAME: case SIOCSIFADDR: case SIOCSIFDSTADDR: case SIOCSIFBRDADDR: case SIOCSIFNETMASK: case SIOCSIFFLAGS: case SIOCSIFMETRIC: case SIOCSIFMTU: case SIOCSIFSLAVE: case SIOCSIFHWADDR: case SIOCSIFTXQLEN: case SIOCSIFMAP: tprints(", "); if (umove_or_printaddr(tcp, arg, &ifr)) break; tprints("{ifr_name="); print_ifname(ifr.ifr_name); tprints(", "); if (code == SIOCSIFNAME) { tprints("ifr_newname="); print_ifname(ifr.ifr_newname); } else { print_ifreq(tcp, code, arg, &ifr); } tprints("}"); break; case SIOCGIFNAME: case SIOCGIFINDEX: case SIOCGIFADDR: case SIOCGIFDSTADDR: case SIOCGIFBRDADDR: case SIOCGIFNETMASK: case SIOCGIFFLAGS: case SIOCGIFMETRIC: case SIOCGIFMTU: case SIOCGIFSLAVE: case SIOCGIFHWADDR: case SIOCGIFTXQLEN: case SIOCGIFMAP: if (entering(tcp)) { tprints(", "); if (umove_or_printaddr(tcp, arg, &ifr)) break; if (SIOCGIFNAME == code) { tprintf("{ifr_index=%d", ifr.ifr_ifindex); } else { tprints("{ifr_name="); print_ifname(ifr.ifr_name); } return 1; } else { if (syserror(tcp)) { tprints("}"); break; } tprints(", "); if (umove(tcp, arg, &ifr) < 0) { tprints("???}"); break; } if (SIOCGIFNAME == code) { tprints("ifr_name="); print_ifname(ifr.ifr_name); } else { print_ifreq(tcp, code, arg, &ifr); } tprints("}"); break; } default: return RVAL_DECODED; } return RVAL_DECODED | 1; }
MPERS_PRINTER_DECL(int, rtc_ioctl, struct tcb *tcp, const unsigned int code, const long arg) { switch (code) { case RTC_ALM_READ: case RTC_RD_TIME: if (entering(tcp)) return 0; /* fall through */ case RTC_ALM_SET: case RTC_SET_TIME: tprints(", "); decode_rtc_time(tcp, arg); break; case RTC_IRQP_SET: case RTC_EPOCH_SET: tprintf(", %lu", arg); break; case RTC_IRQP_READ: case RTC_EPOCH_READ: if (entering(tcp)) return 0; tprints(", "); printnum_ulong(tcp, arg); break; case RTC_WKALM_RD: if (entering(tcp)) return 0; /* fall through */ case RTC_WKALM_SET: tprints(", "); decode_rtc_wkalrm(tcp, arg); break; case RTC_PLL_GET: if (entering(tcp)) return 0; /* fall through */ case RTC_PLL_SET: tprints(", "); decode_rtc_pll_info(tcp, arg); break; #ifdef RTC_VL_READ case RTC_VL_READ: if (entering(tcp)) return 0; tprints(", "); printnum_int(tcp, arg, "%d"); break; #endif case RTC_AIE_ON: case RTC_AIE_OFF: case RTC_UIE_ON: case RTC_UIE_OFF: case RTC_PIE_ON: case RTC_PIE_OFF: case RTC_WIE_ON: case RTC_WIE_OFF: #ifdef RTC_VL_CLR case RTC_VL_CLR: #endif /* no args */ break; default: return RVAL_DECODED; } return RVAL_DECODED | 1; }
int sys_getsockopt(struct tcb *tcp) { if (entering(tcp)) { printfd(tcp, tcp->u_arg[0]); tprints(", "); printxval(socketlayers, tcp->u_arg[1], "SOL_???"); tprints(", "); switch (tcp->u_arg[1]) { case SOL_SOCKET: printxval(sockoptions, tcp->u_arg[2], "SO_???"); break; #ifdef SOL_IP case SOL_IP: printxval(sockipoptions, tcp->u_arg[2], "IP_???"); break; #endif #ifdef SOL_IPV6 case SOL_IPV6: printxval(sockipv6options, tcp->u_arg[2], "IPV6_???"); break; #endif #ifdef SOL_IPX case SOL_IPX: printxval(sockipxoptions, tcp->u_arg[2], "IPX_???"); break; #endif #ifdef SOL_PACKET case SOL_PACKET: printxval(sockpacketoptions, tcp->u_arg[2], "PACKET_???"); break; #endif #ifdef SOL_TCP case SOL_TCP: printxval(socktcpoptions, tcp->u_arg[2], "TCP_???"); break; #endif #ifdef SOL_SCTP case SOL_SCTP: printxval(socksctpoptions, tcp->u_arg[2], "SCTP_???"); break; #endif /* SOL_AX25 SOL_ROSE SOL_ATALK SOL_NETROM SOL_UDP SOL_DECNET SOL_X25 * etc. still need work */ default: tprintf("%lu", tcp->u_arg[2]); break; } tprints(", "); } else { int len; if (syserror(tcp) || umove(tcp, tcp->u_arg[4], &len) < 0) { tprintf("%#lx, %#lx", tcp->u_arg[3], tcp->u_arg[4]); return 0; } switch (tcp->u_arg[1]) { case SOL_SOCKET: switch (tcp->u_arg[2]) { #ifdef SO_LINGER case SO_LINGER: if (len == sizeof(struct linger)) { struct linger linger; if (umove(tcp, tcp->u_arg[3], &linger) < 0) break; tprintf("{onoff=%d, linger=%d}, " "[%d]", linger.l_onoff, linger.l_linger, len); return 0; } break; #endif #ifdef SO_PEERCRED case SO_PEERCRED: if (len == sizeof(struct ucred)) { struct ucred uc; if (umove(tcp, tcp->u_arg[3], &uc) < 0) break; tprintf("{pid=%ld, uid=%ld, gid=%ld}, " "[%d]", (long)uc.pid, (long)uc.uid, (long)uc.gid, len); return 0; } break; #endif } break; case SOL_PACKET: switch (tcp->u_arg[2]) { #ifdef PACKET_STATISTICS case PACKET_STATISTICS: if (len == sizeof(struct tpacket_stats)) { struct tpacket_stats stats; if (umove(tcp, tcp->u_arg[3], &stats) < 0) break; tprintf("{packets=%u, drops=%u}, " "[%d]", stats.tp_packets, stats.tp_drops, len); return 0; } break; #endif } break; } if (len == sizeof(int)) { printnum_int(tcp, tcp->u_arg[3], "%d"); } else { printstr(tcp, tcp->u_arg[3], len); } tprintf(", [%d]", len); } return 0; }
static int evdev_read_ioctl(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t arg) { /* fixed-number fixed-length commands */ switch (code) { case EVIOCGVERSION: tprints(", "); printnum_int(tcp, arg, "%#x"); return 1; case EVIOCGEFFECTS: tprints(", "); printnum_int(tcp, arg, "%u"); return 1; case EVIOCGID: return getid_ioctl(tcp, arg); # ifdef EVIOCGREP case EVIOCGREP: return repeat_ioctl(tcp, arg); # endif case EVIOCGKEYCODE: return keycode_ioctl(tcp, arg); # ifdef EVIOCGKEYCODE_V2 case EVIOCGKEYCODE_V2: return keycode_V2_ioctl(tcp, arg); # endif } /* fixed-number variable-length commands */ switch (_IOC_NR(code)) { # ifdef EVIOCGMTSLOTS case _IOC_NR(EVIOCGMTSLOTS(0)): return mtslots_ioctl(tcp, code, arg); # endif case _IOC_NR(EVIOCGNAME(0)): case _IOC_NR(EVIOCGPHYS(0)): case _IOC_NR(EVIOCGUNIQ(0)): tprints(", "); if (syserror(tcp)) printaddr(arg); else printstrn(tcp, arg, tcp->u_rval); return 1; # ifdef EVIOCGPROP case _IOC_NR(EVIOCGPROP(0)): return decode_bitset(tcp, arg, evdev_prop, INPUT_PROP_MAX, "PROP_???"); # endif case _IOC_NR(EVIOCGSND(0)): return decode_bitset(tcp, arg, evdev_snd, SND_MAX, "SND_???"); # ifdef EVIOCGSW case _IOC_NR(EVIOCGSW(0)): return decode_bitset(tcp, arg, evdev_switch, SW_MAX, "SW_???"); # endif case _IOC_NR(EVIOCGKEY(0)): return decode_bitset(tcp, arg, evdev_keycode, KEY_MAX, "KEY_???"); case _IOC_NR(EVIOCGLED(0)): return decode_bitset(tcp, arg, evdev_leds, LED_MAX, "LED_???"); } /* multi-number fixed-length commands */ if ((_IOC_NR(code) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) return abs_ioctl(tcp, arg); /* multi-number variable-length commands */ if ((_IOC_NR(code) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0))) return bit_ioctl(tcp, _IOC_NR(code) & EV_MAX, arg); return 0; }
int term_ioctl(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t arg) { switch (code) { /* struct termios */ case TCGETS: #ifdef TCGETS2 case TCGETS2: #endif case TIOCGLCKTRMIOS: if (entering(tcp)) return 0; case TCSETS: #ifdef TCSETS2 case TCSETS2: #endif case TCSETSW: #ifdef TCSETSW2 case TCSETSW2: #endif case TCSETSF: #ifdef TCSETSF2 case TCSETSF2: #endif case TIOCSLCKTRMIOS: decode_termios(tcp, arg); break; /* struct termio */ case TCGETA: if (entering(tcp)) return 0; case TCSETA: case TCSETAW: case TCSETAF: decode_termio(tcp, arg); break; /* struct winsize */ case TIOCGWINSZ: if (entering(tcp)) return 0; case TIOCSWINSZ: decode_winsize(tcp, arg); break; /* struct ttysize */ #ifdef TIOCGSIZE case TIOCGSIZE: if (entering(tcp)) return 0; case TIOCSSIZE: decode_ttysize(tcp, arg); break; #endif /* ioctls with a direct decodable arg */ case TCXONC: tprints(", "); printxval64(tcxonc_options, arg, "TC???"); break; case TCFLSH: tprints(", "); printxval64(tcflsh_options, arg, "TC???"); break; case TCSBRK: case TCSBRKP: case TIOCSCTTY: tprintf(", %d", (int) arg); break; /* ioctls with an indirect parameter displayed as modem flags */ case TIOCMGET: if (entering(tcp)) return 0; case TIOCMBIS: case TIOCMBIC: case TIOCMSET: decode_modem_flags(tcp, arg); break; /* ioctls with an indirect parameter displayed in decimal */ case TIOCGPGRP: case TIOCGSID: case TIOCGETD: case TIOCGSOFTCAR: case TIOCGPTN: case FIONREAD: case TIOCOUTQ: #ifdef TIOCGEXCL case TIOCGEXCL: #endif #ifdef TIOCGDEV case TIOCGDEV: #endif if (entering(tcp)) return 0; case TIOCSPGRP: case TIOCSETD: case FIONBIO: case FIOASYNC: case TIOCPKT: case TIOCSSOFTCAR: case TIOCSPTLCK: tprints(", "); printnum_int(tcp, arg, "%d"); break; /* ioctls with an indirect parameter displayed as a char */ case TIOCSTI: tprints(", "); printstrn(tcp, arg, 1); break; /* ioctls with no parameters */ case TIOCSBRK: case TIOCCBRK: case TIOCCONS: case TIOCNOTTY: case TIOCEXCL: case TIOCNXCL: case FIOCLEX: case FIONCLEX: #ifdef TIOCVHANGUP case TIOCVHANGUP: #endif #ifdef TIOCSSERIAL case TIOCSSERIAL: #endif break; /* ioctls which are unknown */ default: return RVAL_DECODED; } return RVAL_IOCTL_DECODED; }
MPERS_PRINTER_DECL(int, mtd_ioctl, struct tcb *const tcp, const unsigned int code, const kernel_ulong_t arg) { switch (code) { case MEMERASE: case MEMLOCK: case MEMUNLOCK: case MEMISLOCKED: decode_erase_info_user(tcp, arg); break; case MEMERASE64: decode_erase_info_user64(tcp, arg); break; case MEMWRITEOOB: case MEMREADOOB: decode_mtd_oob_buf(tcp, arg); break; case MEMWRITEOOB64: case MEMREADOOB64: decode_mtd_oob_buf64(tcp, arg); break; case MEMWRITE: decode_mtd_write_req(tcp, arg); break; case OTPGETREGIONINFO: if (entering(tcp)) return 0; /* fall through */ case OTPLOCK: decode_otp_info(tcp, arg); break; case OTPSELECT: decode_otp_select(tcp, arg); break; case MTDFILEMODE: tprints(", "); printxval64(mtd_file_mode_options, arg, "MTD_FILE_MODE_???"); break; case MEMGETBADBLOCK: case MEMSETBADBLOCK: tprints(", "); printnum_int64(tcp, arg, "%" PRIu64); break; case MEMGETINFO: if (entering(tcp)) return 0; decode_mtd_info_user(tcp, arg); break; case MEMGETOOBSEL: if (entering(tcp)) return 0; decode_nand_oobinfo(tcp, arg); break; case ECCGETLAYOUT: if (entering(tcp)) return 0; decode_nand_ecclayout_user(tcp, arg); break; case ECCGETSTATS: if (entering(tcp)) return 0; decode_mtd_ecc_stats(tcp, arg); break; case OTPGETREGIONCOUNT: if (entering(tcp)) return 0; tprints(", "); printnum_int(tcp, arg, "%u"); break; case MEMGETREGIONCOUNT: if (entering(tcp)) return 0; tprints(", "); printnum_int(tcp, arg, "%d"); break; case MEMGETREGIONINFO: if (entering(tcp)) { struct region_info_user rinfo; tprints(", "); if (umove_or_printaddr(tcp, arg, &rinfo)) break; tprintf("{regionindex=%#x", rinfo.regionindex); return 0; } else { struct region_info_user rinfo; if (!syserror(tcp) && !umove(tcp, arg, &rinfo)) tprintf(", offset=%#x" ", erasesize=%#x" ", numblocks=%#x}", rinfo.offset, rinfo.erasesize, rinfo.numblocks); tprints("}"); break; } default: return RVAL_DECODED; } return RVAL_IOCTL_DECODED; }
static void print_group_req(struct tcb *tcp, long addr, int len) { struct group_req greq; if (len != sizeof(greq) || umove(tcp, addr, &greq) < 0) { tprintf("%#lx", addr); return; } union { struct sockaddr *sa; struct sockaddr_in *sin; #ifdef HAVE_INET_NTOP struct sockaddr_in6 *sin6; #endif } a = { .sa = (struct sockaddr *) &greq.gr_group }; #ifdef HAVE_INET_NTOP char str[INET6_ADDRSTRLEN]; #endif tprintf("{gr_interface=%u, gr_group={sa_family=", greq.gr_interface); printxval(addrfams, a.sa->sa_family, "AF_???"); switch (a.sa->sa_family) { case AF_INET: tprintf(", sin_port=htons(%u), sin_addr=inet_addr(\"%s\")}}", ntohs(a.sin->sin_port), inet_ntoa(a.sin->sin_addr)); return; #ifdef HAVE_INET_NTOP case AF_INET6: if (!inet_ntop(AF_INET6, &a.sin6->sin6_addr, str, sizeof(str))) break; tprintf(", sin6_port=htons(%u)" ", inet_pton(AF_INET6, \"%s\", &sin6_addr)}}", ntohs(a.sin6->sin6_port), str); return; #endif /* HAVE_INET_NTOP */ } tprints(", sa_data="); print_quoted_string(a.sa->sa_data, sizeof(a.sa->sa_data), 0); tprintf("}}"); } #endif /* MCAST_JOIN_GROUP */ #ifdef PACKET_RX_RING static void print_tpacket_req(struct tcb *tcp, long addr, int len) { struct tpacket_req req; if (len != sizeof(req) || umove(tcp, addr, &req) < 0) { tprintf("%#lx", addr); } else { tprintf("{block_size=%u, block_nr=%u, " "frame_size=%u, frame_nr=%u}", req.tp_block_size, req.tp_block_nr, req.tp_frame_size, req.tp_frame_nr); } } #endif /* PACKET_RX_RING */ #ifdef PACKET_ADD_MEMBERSHIP # include "xlat/packet_mreq_type.h" static void print_packet_mreq(struct tcb *tcp, long addr, int len) { struct packet_mreq mreq; if (len != sizeof(mreq) || umove(tcp, addr, &mreq) < 0) { tprintf("%#lx", addr); } else { unsigned int i; tprintf("{mr_ifindex=%u, mr_type=", mreq.mr_ifindex); printxval(packet_mreq_type, mreq.mr_type, "PACKET_MR_???"); tprintf(", mr_alen=%u, mr_address=", mreq.mr_alen); if (mreq.mr_alen > ARRAY_SIZE(mreq.mr_address)) mreq.mr_alen = ARRAY_SIZE(mreq.mr_address); for (i = 0; i < mreq.mr_alen; ++i) tprintf("%02x", mreq.mr_address[i]); tprints("}"); } } #endif /* PACKET_ADD_MEMBERSHIP */ static void print_setsockopt(struct tcb *tcp, int level, int name, long addr, int len) { if (addr && verbose(tcp)) switch (level) { case SOL_SOCKET: switch (name) { #ifdef SO_LINGER case SO_LINGER: print_linger(tcp, addr, len); goto done; #endif } break; case SOL_IP: switch (name) { #ifdef IP_ADD_MEMBERSHIP case IP_ADD_MEMBERSHIP: case IP_DROP_MEMBERSHIP: print_mreq(tcp, addr, len); goto done; #endif /* IP_ADD_MEMBERSHIP */ #ifdef MCAST_JOIN_GROUP case MCAST_JOIN_GROUP: case MCAST_LEAVE_GROUP: print_group_req(tcp, addr, len); goto done; #endif /* MCAST_JOIN_GROUP */ } break; case SOL_IPV6: switch (name) { #ifdef IPV6_ADD_MEMBERSHIP case IPV6_ADD_MEMBERSHIP: case IPV6_DROP_MEMBERSHIP: # ifdef IPV6_JOIN_ANYCAST case IPV6_JOIN_ANYCAST: # endif # ifdef IPV6_LEAVE_ANYCAST case IPV6_LEAVE_ANYCAST: # endif print_mreq6(tcp, addr, len); goto done; #endif /* IPV6_ADD_MEMBERSHIP */ } break; case SOL_PACKET: switch (name) { #ifdef PACKET_RX_RING case PACKET_RX_RING: # ifdef PACKET_TX_RING case PACKET_TX_RING: # endif print_tpacket_req(tcp, addr, len); goto done; #endif /* PACKET_RX_RING */ #ifdef PACKET_ADD_MEMBERSHIP case PACKET_ADD_MEMBERSHIP: case PACKET_DROP_MEMBERSHIP: print_packet_mreq(tcp, addr, len); goto done; #endif /* PACKET_ADD_MEMBERSHIP */ } break; case SOL_RAW: switch (name) { #ifdef ICMP_FILTER case ICMP_FILTER: print_icmp_filter(tcp, addr, len); goto done; #endif } break; } /* default arg printing */ if (verbose(tcp)) { if (len == sizeof(int)) { printnum_int(tcp, addr, "%d"); } else { printstr(tcp, addr, len); } } else { tprintf("%#lx", addr); } done: tprintf(", %d", len); } SYS_FUNC(setsockopt) { if (entering(tcp)) { print_sockopt_fd_level_name(tcp, tcp->u_arg[0], tcp->u_arg[1], tcp->u_arg[2]); print_setsockopt(tcp, tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3], tcp->u_arg[4]); } return 0; }
int term_ioctl(struct tcb *tcp, long code, long arg) { struct termios tios; #ifndef FREEBSD struct termio tio; #else #define TCGETS TIOCGETA #define TCSETS TIOCSETA #define TCSETSW TIOCSETAW #define TCSETSF TIOCSETAF #endif struct winsize ws; #ifdef TIOCGSIZE struct ttysize ts; #endif int i; if (entering(tcp)) return 0; switch (code) { /* ioctls with termios or termio args */ #ifdef TCGETS case TCGETS: if (syserror(tcp)) return 0; case TCSETS: case TCSETSW: case TCSETSF: if (!verbose(tcp) || umove(tcp, arg, &tios) < 0) return 0; if (abbrev(tcp)) { tprintf(", {"); #ifndef FREEBSD printxval(baud_options, tios.c_cflag & CBAUD, "B???"); #else printxval(baud_options, tios.c_ispeed, "B???"); if (tios.c_ispeed != tios.c_ospeed) { tprintf(" (in)"); printxval(baud_options, tios.c_ospeed, "B???"); tprintf(" (out)"); } #endif tprintf(" %sopost %sisig %sicanon %secho ...}", (tios.c_oflag & OPOST) ? "" : "-", (tios.c_lflag & ISIG) ? "" : "-", (tios.c_lflag & ICANON) ? "" : "-", (tios.c_lflag & ECHO) ? "" : "-"); return 1; } tprintf(", {c_iflags=%#lx, c_oflags=%#lx, ", (long) tios.c_iflag, (long) tios.c_oflag); tprintf("c_cflags=%#lx, c_lflags=%#lx, ", (long) tios.c_cflag, (long) tios.c_lflag); #if !defined(SVR4) && !defined(FREEBSD) tprintf("c_line=%u, ", tios.c_line); #endif if (!(tios.c_lflag & ICANON)) tprintf("c_cc[VMIN]=%d, c_cc[VTIME]=%d, ", tios.c_cc[VMIN], tios.c_cc[VTIME]); tprintf("c_cc=\""); for (i = 0; i < NCCS; i++) tprintf("\\x%02x", tios.c_cc[i]); tprintf("\"}"); return 1; #endif /* TCGETS */ #ifdef TCGETA case TCGETA: if (syserror(tcp)) return 0; case TCSETA: case TCSETAW: case TCSETAF: if (!verbose(tcp) || umove(tcp, arg, &tio) < 0) return 0; if (abbrev(tcp)) { tprintf(", {"); printxval(baud_options, tio.c_cflag & CBAUD, "B???"); tprintf(" %sopost %sisig %sicanon %secho ...}", (tio.c_oflag & OPOST) ? "" : "-", (tio.c_lflag & ISIG) ? "" : "-", (tio.c_lflag & ICANON) ? "" : "-", (tio.c_lflag & ECHO) ? "" : "-"); return 1; } tprintf(", {c_iflags=%#lx, c_oflags=%#lx, ", (long) tio.c_iflag, (long) tio.c_oflag); tprintf("c_cflags=%#lx, c_lflags=%#lx, ", (long) tio.c_cflag, (long) tio.c_lflag); tprintf("c_line=%u, ", tio.c_line); #ifdef _VMIN if (!(tio.c_lflag & ICANON)) tprintf("c_cc[_VMIN]=%d, c_cc[_VTIME]=%d, ", tio.c_cc[_VMIN], tio.c_cc[_VTIME]); #else /* !_VMIN */ if (!(tio.c_lflag & ICANON)) tprintf("c_cc[VMIN]=%d, c_cc[VTIME]=%d, ", tio.c_cc[VMIN], tio.c_cc[VTIME]); #endif /* !_VMIN */ tprintf("c_cc=\""); for (i = 0; i < NCC; i++) tprintf("\\x%02x", tio.c_cc[i]); tprintf("\"}"); return 1; #endif /* TCGETA */ /* ioctls with winsize or ttysize args */ #ifdef TIOCGWINSZ case TIOCGWINSZ: if (syserror(tcp)) return 0; case TIOCSWINSZ: if (!verbose(tcp) || umove(tcp, arg, &ws) < 0) return 0; tprintf(", {ws_row=%d, ws_col=%d, ws_xpixel=%d, ws_ypixel=%d}", ws.ws_row, ws.ws_col, ws.ws_xpixel, ws.ws_ypixel); return 1; #endif /* TIOCGWINSZ */ #ifdef TIOCGSIZE case TIOCGSIZE: if (syserror(tcp)) return 0; case TIOCSSIZE: if (!verbose(tcp) || umove(tcp, arg, &ts) < 0) return 0; tprintf(", {ts_lines=%d, ts_cols=%d}", ts.ts_lines, ts.ts_cols); return 1; #endif /* ioctls with a direct decodable arg */ #ifdef TCXONC case TCXONC: tprintf(", "); printxval(tcxonc_options, arg, "TC???"); return 1; #endif #ifdef TCLFLSH case TCFLSH: tprintf(", "); printxval(tcflsh_options, arg, "TC???"); return 1; #endif /* ioctls with an indirect parameter displayed as modem flags */ #ifdef TIOCMGET case TIOCMGET: case TIOCMBIS: case TIOCMBIC: case TIOCMSET: if (umove(tcp, arg, &i) < 0) return 0; tprintf(", ["); printflags(modem_flags, i, "TIOCM_???"); tprintf("]"); return 1; #endif /* TIOCMGET */ /* ioctls with an indirect parameter displayed in decimal */ case TIOCSPGRP: case TIOCGPGRP: #ifdef TIOCGETPGRP case TIOCGETPGRP: #endif #ifdef TIOCSETPGRP case TIOCSETPGRP: #endif #ifdef FIONREAD case FIONREAD: #endif case TIOCOUTQ: #ifdef FIONBIO case FIONBIO: #endif #ifdef FIOASYNC case FIOASYNC: #endif #ifdef FIOGETOWN case FIOGETOWN: #endif #ifdef FIOSETOWN case FIOSETOWN: #endif #ifdef TIOCGETD case TIOCGETD: #endif #ifdef TIOCSETD case TIOCSETD: #endif #ifdef TIOCPKT case TIOCPKT: #endif #ifdef TIOCREMOTE case TIOCREMOTE: #endif #ifdef TIOCUCNTL case TIOCUCNTL: #endif #ifdef TIOCTCNTL case TIOCTCNTL: #endif #ifdef TIOCSIGNAL case TIOCSIGNAL: #endif #ifdef TIOCSSOFTCAR case TIOCSSOFTCAR: #endif #ifdef TIOCGSOFTCAR case TIOCGSOFTCAR: #endif #ifdef TIOCISPACE case TIOCISPACE: #endif #ifdef TIOCISIZE case TIOCISIZE: #endif #ifdef TIOCSINTR case TIOCSINTR: #endif #ifdef TIOCSPTLCK case TIOCSPTLCK: #endif #ifdef TIOCGPTN case TIOCGPTN: #endif tprintf(", "); printnum_int(tcp, arg, "%d"); return 1; /* ioctls with an indirect parameter displayed as a char */ #ifdef TIOCSTI case TIOCSTI: #endif tprintf(", "); printstr(tcp, arg, 1); return 1; /* ioctls with no parameters */ #ifdef TIOCSCTTY case TIOCSCTTY: #endif #ifdef TIOCNOTTY case TIOCNOTTY: #endif #ifdef FIOCLEX case FIOCLEX: #endif #ifdef FIONCLEX case FIONCLEX: #endif #ifdef TIOCCONS case TIOCCONS: #endif return 1; /* ioctls which are unknown */ default: return 0; } }