xref: /haiku/src/bin/debug/strace/ioctl.cpp (revision 445d4fd926c569e7b9ae28017da86280aaecbae2)
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 #define TCWAITEVENT				(TCGETA + 4)
116 #define TCQUERYCONNECTED		(TCGETA + 8)
117 #define TCVTIME					(TCGETA + 14)
118 	IOCTL_INFO_ENTRY(TCGETA),
119 	IOCTL_INFO_ENTRY(TCSETA),
120 	IOCTL_INFO_ENTRY(TCSETAF),
121 	IOCTL_INFO_ENTRY(TCSETAW),
122 	IOCTL_INFO_ENTRY(TCWAITEVENT),
123 	IOCTL_INFO_ENTRY(TCSBRK),
124 	IOCTL_INFO_ENTRY(TCFLSH),
125 	IOCTL_INFO_ENTRY(TCXONC),
126 	IOCTL_INFO_ENTRY(TCQUERYCONNECTED),
127 	IOCTL_INFO_ENTRY(TCGETBITS),
128 	IOCTL_INFO_ENTRY(TCSETDTR),
129 	IOCTL_INFO_ENTRY(TCSETRTS),
130 	IOCTL_INFO_ENTRY(TIOCGWINSZ),
131 	IOCTL_INFO_ENTRY(TIOCSWINSZ),
132 	IOCTL_INFO_ENTRY(TCVTIME),
133 	IOCTL_INFO_ENTRY(TIOCGPGRP),
134 	IOCTL_INFO_ENTRY(TIOCSPGRP),
135 	IOCTL_INFO_ENTRY(TIOCSCTTY),
136 	IOCTL_INFO_ENTRY(TIOCMGET),
137 	IOCTL_INFO_ENTRY(TIOCMSET),
138 	IOCTL_INFO_ENTRY(TIOCSBRK),
139 	IOCTL_INFO_ENTRY(TIOCCBRK),
140 	IOCTL_INFO_ENTRY(TIOCMBIS),
141 	IOCTL_INFO_ENTRY(TIOCMBIC),
142 	IOCTL_INFO_ENTRY(TIOCOUTQ),
143 	IOCTL_INFO_ENTRY(TIOCEXCL),
144 	IOCTL_INFO_ENTRY(TIOCNXCL),
145 
146 	// private termios
147 	IOCTL_INFO_ENTRY(B_IOCTL_GET_TTY_INDEX),
148 	IOCTL_INFO_ENTRY(B_IOCTL_GRANT_TTY),
149 
150 	// scsi ioctls
151 	IOCTL_INFO_ENTRY(B_SCSI_SCAN_FOR_DEVICES),
152 	IOCTL_INFO_ENTRY(B_SCSI_ENABLE_PROFILING),
153 	IOCTL_INFO_ENTRY(B_SCSI_INQUIRY),
154 	IOCTL_INFO_ENTRY(B_SCSI_EJECT),
155 	IOCTL_INFO_ENTRY(B_SCSI_PREVENT_ALLOW),
156 	IOCTL_INFO_ENTRY(B_RAW_DEVICE_COMMAND),
157 	IOCTL_INFO_ENTRY(B_SCSI_GET_TOC),
158 	IOCTL_INFO_ENTRY(B_SCSI_PLAY_TRACK),
159 	IOCTL_INFO_ENTRY(B_SCSI_PLAY_POSITION),
160 	IOCTL_INFO_ENTRY(B_SCSI_STOP_AUDIO),
161 	IOCTL_INFO_ENTRY(B_SCSI_PAUSE_AUDIO),
162 	IOCTL_INFO_ENTRY(B_SCSI_RESUME_AUDIO),
163 	IOCTL_INFO_ENTRY(B_SCSI_GET_POSITION),
164 	IOCTL_INFO_ENTRY(B_SCSI_SET_VOLUME),
165 	IOCTL_INFO_ENTRY(B_SCSI_GET_VOLUME),
166 	IOCTL_INFO_ENTRY(B_SCSI_READ_CD),
167 	IOCTL_INFO_ENTRY(B_SCSI_SCAN),
168 	IOCTL_INFO_ENTRY(B_SCSI_DATA_MODE),
169 
170 	// socket ioctls
171 	IOCTL_INFO_ENTRY_TYPE(FIONBIO, int*),
172 	IOCTL_INFO_ENTRY_TYPE(FIONREAD, int*),
173 	IOCTL_INFO_ENTRY_TYPE(FIOSEEKDATA, off_t*),
174 	IOCTL_INFO_ENTRY_TYPE(FIOSEEKHOLE, off_t*),
175 
176 	{ 0, NULL, NULL }
177 };
178 
179 static EnumTypeHandler::EnumMap kIoctlNames;
180 static TypeHandlerSelector::SelectMap kIoctlTypeHandlers;
181 
182 void
183 patch_ioctl()
184 {
185 	for (int i = 0; kIOCtls[i].name != NULL; i++) {
186 		kIoctlNames[kIOCtls[i].index] = kIOCtls[i].name;
187 		if (kIOCtls[i].handler != NULL)
188 			kIoctlTypeHandlers[kIOCtls[i].index] = kIOCtls[i].handler;
189 	}
190 
191 	Syscall *ioctl = get_syscall("_kern_ioctl");
192 
193 	ioctl->GetParameter("cmd")->SetHandler(
194 			new EnumTypeHandler(kIoctlNames));
195 	ioctl->GetParameter("data")->SetHandler(
196 			new TypeHandlerSelector(kIoctlTypeHandlers,
197 					1, TypeHandlerFactory<void *>::Create()));
198 }
199 
200