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