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