xref: /haiku/src/bin/debug/strace/ioctl.cpp (revision 4c8e85b316c35a9161f5a1c50ad70bc91c83a76f)
1 /*
2  * Copyright 2007-2010, Haiku Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Hugo Santos <hugosantos@gmail.com>
7  */
8 
9 
10 #include <sys/ioctl.h>
11 #include <sys/sockio.h>
12 #include <termios.h>
13 
14 #include <Drivers.h>
15 #include <tty.h>
16 #include <scsi.h>
17 
18 #include "strace.h"
19 #include "Syscall.h"
20 #include "TypeHandler.h"
21 
22 
23 struct ioctl_info {
24 	unsigned int index;
25 	const char *name;
26 	TypeHandler *handler;
27 };
28 
29 #define IOCTL_INFO_ENTRY(name) \
30 	{ name, #name, NULL }
31 
32 #define IOCTL_INFO_ENTRY_TYPE(name, type) \
33 	{ name, #name, TypeHandlerFactory<type>::Create() }
34 
35 static const ioctl_info kIOCtls[] = {
36 	// <Drivers.h>
37 	IOCTL_INFO_ENTRY_TYPE(B_GET_DEVICE_SIZE, size_t *),
38 	IOCTL_INFO_ENTRY_TYPE(B_SET_DEVICE_SIZE, size_t *),
39 	IOCTL_INFO_ENTRY(B_SET_NONBLOCKING_IO),
40 	IOCTL_INFO_ENTRY(B_SET_BLOCKING_IO),
41 	IOCTL_INFO_ENTRY(B_GET_READ_STATUS),
42 	IOCTL_INFO_ENTRY(B_GET_WRITE_STATUS),
43 	IOCTL_INFO_ENTRY(B_GET_GEOMETRY),
44 	IOCTL_INFO_ENTRY(B_GET_DRIVER_FOR_DEVICE),
45 	IOCTL_INFO_ENTRY(B_GET_PARTITION_INFO),
46 	IOCTL_INFO_ENTRY(B_SET_PARTITION),
47 	IOCTL_INFO_ENTRY(B_FORMAT_DEVICE),
48 	IOCTL_INFO_ENTRY(B_EJECT_DEVICE),
49 	IOCTL_INFO_ENTRY(B_GET_ICON),
50 	IOCTL_INFO_ENTRY(B_GET_BIOS_GEOMETRY),
51 	IOCTL_INFO_ENTRY(B_GET_MEDIA_STATUS),
52 	IOCTL_INFO_ENTRY(B_LOAD_MEDIA),
53 	IOCTL_INFO_ENTRY(B_GET_BIOS_DRIVE_ID),
54 	IOCTL_INFO_ENTRY(B_SET_UNINTERRUPTABLE_IO),
55 	IOCTL_INFO_ENTRY(B_SET_INTERRUPTABLE_IO),
56 	IOCTL_INFO_ENTRY(B_FLUSH_DRIVE_CACHE),
57 	IOCTL_INFO_ENTRY(B_GET_PATH_FOR_DEVICE),
58 	IOCTL_INFO_ENTRY(B_GET_NEXT_OPEN_DEVICE),
59 	IOCTL_INFO_ENTRY(B_ADD_FIXED_DRIVER),
60 	IOCTL_INFO_ENTRY(B_REMOVE_FIXED_DRIVER),
61 
62 	/*
63 	IOCTL_INFO_ENTRY(B_AUDIO_DRIVER_BASE), // conflicts
64 	IOCTL_INFO_ENTRY(B_MIDI_DRIVER_BASE),
65 	IOCTL_INFO_ENTRY(B_JOYSTICK_DRIVER_BASE),
66 	IOCTL_INFO_ENTRY(B_GRAPHIC_DRIVER_BASE),
67 	IOCTL_INFO_ENTRY(B_DEVICE_OP_CODES_END),
68 	*/
69 
70 	// <sys/sockio.h>
71 	IOCTL_INFO_ENTRY(SIOCADDRT),
72 	IOCTL_INFO_ENTRY(SIOCDELRT),
73 	IOCTL_INFO_ENTRY_TYPE(SIOCSIFADDR, struct ifreq *),
74 	IOCTL_INFO_ENTRY_TYPE(SIOCGIFADDR, struct ifreq *),
75 	IOCTL_INFO_ENTRY_TYPE(SIOCSIFDSTADDR, struct ifreq *),
76 	IOCTL_INFO_ENTRY_TYPE(SIOCGIFDSTADDR, struct ifreq *),
77 	IOCTL_INFO_ENTRY_TYPE(SIOCSIFFLAGS, struct ifreq *),
78 	IOCTL_INFO_ENTRY_TYPE(SIOCGIFFLAGS, struct ifreq *),
79 	IOCTL_INFO_ENTRY_TYPE(SIOCGIFBRDADDR, struct ifreq *),
80 	IOCTL_INFO_ENTRY_TYPE(SIOCSIFBRDADDR, struct ifreq *),
81 	IOCTL_INFO_ENTRY_TYPE(SIOCGIFCOUNT, struct ifconf *),
82 	IOCTL_INFO_ENTRY_TYPE(SIOCGIFCONF, struct ifconf *),
83 	IOCTL_INFO_ENTRY_TYPE(SIOCGIFINDEX, struct ifreq *),
84 	IOCTL_INFO_ENTRY(SIOCGIFNAME),
85 	IOCTL_INFO_ENTRY_TYPE(SIOCGIFNETMASK, struct ifreq *),
86 	IOCTL_INFO_ENTRY_TYPE(SIOCSIFNETMASK, struct ifreq *),
87 	IOCTL_INFO_ENTRY_TYPE(SIOCGIFMETRIC, struct ifreq *),
88 	IOCTL_INFO_ENTRY_TYPE(SIOCSIFMETRIC, struct ifreq *),
89 	IOCTL_INFO_ENTRY_TYPE(SIOCDIFADDR, struct ifreq *),
90 	IOCTL_INFO_ENTRY_TYPE(SIOCAIFADDR, struct ifaliasreq *),
91 	IOCTL_INFO_ENTRY(SIOCADDMULTI),
92 	IOCTL_INFO_ENTRY(SIOCDELMULTI),
93 	IOCTL_INFO_ENTRY_TYPE(SIOCGIFMTU, struct ifreq *),
94 	IOCTL_INFO_ENTRY_TYPE(SIOCSIFMTU, struct ifreq *),
95 	IOCTL_INFO_ENTRY(SIOCSIFMEDIA),
96 	IOCTL_INFO_ENTRY(SIOCGIFMEDIA),
97 	IOCTL_INFO_ENTRY(SIOCGRTSIZE),
98 	IOCTL_INFO_ENTRY(SIOCGRTTABLE),
99 	IOCTL_INFO_ENTRY_TYPE(SIOCGIFSTATS, struct ifreq *),
100 	IOCTL_INFO_ENTRY_TYPE(SIOCGIFTYPE, struct ifreq *),
101 	IOCTL_INFO_ENTRY(SIOCSPACKETCAP),
102 	IOCTL_INFO_ENTRY(SIOCCPACKETCAP),
103 	IOCTL_INFO_ENTRY(SIOCSHIWAT),
104 	IOCTL_INFO_ENTRY(SIOCGHIWAT),
105 	IOCTL_INFO_ENTRY(SIOCSLOWAT),
106 	IOCTL_INFO_ENTRY(SIOCGLOWAT),
107 	IOCTL_INFO_ENTRY(SIOCATMARK),
108 	IOCTL_INFO_ENTRY(SIOCSPGRP),
109 
110 	IOCTL_INFO_ENTRY_TYPE(B_SOCKET_SET_ALIAS, struct ifaliasreq *),
111 	IOCTL_INFO_ENTRY_TYPE(B_SOCKET_GET_ALIAS, struct ifaliasreq *),
112 	IOCTL_INFO_ENTRY_TYPE(B_SOCKET_COUNT_ALIASES, struct ifreq *),
113 
114 	// termios ioctls
115 	IOCTL_INFO_ENTRY(TCGETA),
116 	IOCTL_INFO_ENTRY(TCSETA),
117 	IOCTL_INFO_ENTRY(TCSETAF),
118 	IOCTL_INFO_ENTRY(TCSETAW),
119 	IOCTL_INFO_ENTRY(TCWAITEVENT),
120 	IOCTL_INFO_ENTRY(TCSBRK),
121 	IOCTL_INFO_ENTRY(TCFLSH),
122 	IOCTL_INFO_ENTRY(TCXONC),
123 	IOCTL_INFO_ENTRY(TCQUERYCONNECTED),
124 	IOCTL_INFO_ENTRY(TCGETBITS),
125 	IOCTL_INFO_ENTRY(TCSETDTR),
126 	IOCTL_INFO_ENTRY(TCSETRTS),
127 	IOCTL_INFO_ENTRY(TIOCGWINSZ),
128 	IOCTL_INFO_ENTRY(TIOCSWINSZ),
129 	IOCTL_INFO_ENTRY(TCVTIME),
130 	IOCTL_INFO_ENTRY(TIOCGPGRP),
131 	IOCTL_INFO_ENTRY(TIOCSPGRP),
132 	IOCTL_INFO_ENTRY(TIOCSCTTY),
133 	IOCTL_INFO_ENTRY(TIOCMGET),
134 	IOCTL_INFO_ENTRY(TIOCMSET),
135 	IOCTL_INFO_ENTRY(TIOCSBRK),
136 	IOCTL_INFO_ENTRY(TIOCCBRK),
137 	IOCTL_INFO_ENTRY(TIOCMBIS),
138 	IOCTL_INFO_ENTRY(TIOCMBIC),
139 	// private termios
140 	IOCTL_INFO_ENTRY(B_IOCTL_GET_TTY_INDEX),
141 	IOCTL_INFO_ENTRY(B_IOCTL_GRANT_TTY),
142 
143 	// scsi ioctls
144 	IOCTL_INFO_ENTRY(B_SCSI_SCAN_FOR_DEVICES),
145 	IOCTL_INFO_ENTRY(B_SCSI_ENABLE_PROFILING),
146 	IOCTL_INFO_ENTRY(B_SCSI_INQUIRY),
147 	IOCTL_INFO_ENTRY(B_SCSI_EJECT),
148 	IOCTL_INFO_ENTRY(B_SCSI_PREVENT_ALLOW),
149 	IOCTL_INFO_ENTRY(B_RAW_DEVICE_COMMAND),
150 	IOCTL_INFO_ENTRY(B_SCSI_GET_TOC),
151 	IOCTL_INFO_ENTRY(B_SCSI_PLAY_TRACK),
152 	IOCTL_INFO_ENTRY(B_SCSI_PLAY_POSITION),
153 	IOCTL_INFO_ENTRY(B_SCSI_STOP_AUDIO),
154 	IOCTL_INFO_ENTRY(B_SCSI_PAUSE_AUDIO),
155 	IOCTL_INFO_ENTRY(B_SCSI_RESUME_AUDIO),
156 	IOCTL_INFO_ENTRY(B_SCSI_GET_POSITION),
157 	IOCTL_INFO_ENTRY(B_SCSI_SET_VOLUME),
158 	IOCTL_INFO_ENTRY(B_SCSI_GET_VOLUME),
159 	IOCTL_INFO_ENTRY(B_SCSI_READ_CD),
160 	IOCTL_INFO_ENTRY(B_SCSI_SCAN),
161 	IOCTL_INFO_ENTRY(B_SCSI_DATA_MODE),
162 
163 	// socket ioctls
164 	IOCTL_INFO_ENTRY_TYPE(FIONBIO, int*),
165 	IOCTL_INFO_ENTRY_TYPE(FIONREAD, int*),
166 	IOCTL_INFO_ENTRY_TYPE(FIOSEEKDATA, off_t*),
167 	IOCTL_INFO_ENTRY_TYPE(FIOSEEKHOLE, off_t*),
168 
169 	{ 0, NULL, NULL }
170 };
171 
172 static EnumTypeHandler::EnumMap kIoctlNames;
173 static TypeHandlerSelector::SelectMap kIoctlTypeHandlers;
174 
175 void
176 patch_ioctl()
177 {
178 	for (int i = 0; kIOCtls[i].name != NULL; i++) {
179 		kIoctlNames[kIOCtls[i].index] = kIOCtls[i].name;
180 		if (kIOCtls[i].handler != NULL)
181 			kIoctlTypeHandlers[kIOCtls[i].index] = kIOCtls[i].handler;
182 	}
183 
184 	Syscall *ioctl = get_syscall("_kern_ioctl");
185 
186 	ioctl->GetParameter("cmd")->SetHandler(
187 			new EnumTypeHandler(kIoctlNames));
188 	ioctl->GetParameter("data")->SetHandler(
189 			new TypeHandlerSelector(kIoctlTypeHandlers,
190 					1, TypeHandlerFactory<void *>::Create()));
191 }
192 
193