Esempio n. 1
0
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;
}
Esempio n. 2
0
File: net.c Progetto: cuviper/strace
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);
}
Esempio n. 3
0
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);
	}
}
Esempio n. 4
0
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;
	}
}
Esempio n. 5
0
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;
}
Esempio n. 6
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;
}
Esempio n. 7
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);
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
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;
}
Esempio n. 10
0
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;
}
Esempio n. 11
0
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;
}
Esempio n. 12
0
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;
}
Esempio n. 13
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;
}
Esempio n. 14
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;
}
Esempio n. 15
0
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;
}
Esempio n. 16
0
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;
}
Esempio n. 17
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;
	}
}