xref: /haiku/src/bin/debug/strace/ioctl.cpp (revision 68ea01249e1e2088933cb12f9c28d4e5c5d1c9ef)
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 	// private termios
132 	IOCTL_INFO_ENTRY(B_IOCTL_GET_TTY_INDEX),
133 	IOCTL_INFO_ENTRY(B_IOCTL_GRANT_TTY),
134 
135 	// scsi ioctls
136 	IOCTL_INFO_ENTRY(B_SCSI_SCAN_FOR_DEVICES),
137 	IOCTL_INFO_ENTRY(B_SCSI_ENABLE_PROFILING),
138 	IOCTL_INFO_ENTRY(B_SCSI_INQUIRY),
139 	IOCTL_INFO_ENTRY(B_SCSI_EJECT),
140 	IOCTL_INFO_ENTRY(B_SCSI_PREVENT_ALLOW),
141 	IOCTL_INFO_ENTRY(B_RAW_DEVICE_COMMAND),
142 	IOCTL_INFO_ENTRY(B_SCSI_GET_TOC),
143 	IOCTL_INFO_ENTRY(B_SCSI_PLAY_TRACK),
144 	IOCTL_INFO_ENTRY(B_SCSI_PLAY_POSITION),
145 	IOCTL_INFO_ENTRY(B_SCSI_STOP_AUDIO),
146 	IOCTL_INFO_ENTRY(B_SCSI_PAUSE_AUDIO),
147 	IOCTL_INFO_ENTRY(B_SCSI_RESUME_AUDIO),
148 	IOCTL_INFO_ENTRY(B_SCSI_GET_POSITION),
149 	IOCTL_INFO_ENTRY(B_SCSI_SET_VOLUME),
150 	IOCTL_INFO_ENTRY(B_SCSI_GET_VOLUME),
151 	IOCTL_INFO_ENTRY(B_SCSI_READ_CD),
152 	IOCTL_INFO_ENTRY(B_SCSI_SCAN),
153 	IOCTL_INFO_ENTRY(B_SCSI_DATA_MODE),
154 
155 	{ -1, NULL, NULL }
156 };
157 
158 static EnumTypeHandler::EnumMap kIoctlNames;
159 static TypeHandlerSelector::SelectMap kIoctlTypeHandlers;
160 
161 void
162 patch_ioctl()
163 {
164 	for (int i = 0; kIOCtls[i].name != NULL; i++) {
165 		kIoctlNames[kIOCtls[i].index] = kIOCtls[i].name;
166 		if (kIOCtls[i].handler != NULL)
167 			kIoctlTypeHandlers[kIOCtls[i].index] = kIOCtls[i].handler;
168 	}
169 
170 	Syscall *ioctl = get_syscall("_kern_ioctl");
171 
172 	ioctl->GetParameter("cmd")->SetHandler(
173 			new EnumTypeHandler(kIoctlNames));
174 	ioctl->GetParameter("data")->SetHandler(
175 			new TypeHandlerSelector(kIoctlTypeHandlers,
176 					1, TypeHandlerFactory<void *>::Create()));
177 }
178 
179