aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/wext.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/wext.c')
-rw-r--r--net/wireless/wext.c104
1 files changed, 104 insertions, 0 deletions
diff --git a/net/wireless/wext.c b/net/wireless/wext.c
index 09022cbb58ba..1a4636a9fcde 100644
--- a/net/wireless/wext.c
+++ b/net/wireless/wext.c
@@ -1112,6 +1112,110 @@ int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd,
1112 return ret; 1112 return ret;
1113} 1113}
1114 1114
1115#ifdef CONFIG_COMPAT
1116static int compat_standard_call(struct net_device *dev,
1117 struct iwreq *iwr,
1118 unsigned int cmd,
1119 iw_handler handler)
1120{
1121 const struct iw_ioctl_description *descr;
1122 struct compat_iw_point *iwp_compat;
1123 struct iw_request_info info;
1124 struct iw_point iwp;
1125 int err;
1126
1127 descr = standard_ioctl + (cmd - SIOCIWFIRST);
1128
1129 if (descr->header_type != IW_HEADER_TYPE_POINT)
1130 return ioctl_standard_call(dev, iwr, cmd, handler);
1131
1132 iwp_compat = (struct compat_iw_point *) &iwr->u.data;
1133 iwp.pointer = compat_ptr(iwp_compat->pointer);
1134 iwp.length = iwp_compat->length;
1135 iwp.flags = iwp_compat->flags;
1136
1137 info.cmd = cmd;
1138 info.flags = 0;
1139
1140 err = ioctl_standard_iw_point(&iwp, cmd, descr, handler, dev, &info);
1141
1142 iwp_compat->pointer = ptr_to_compat(iwp.pointer);
1143 iwp_compat->length = iwp.length;
1144 iwp_compat->flags = iwp.flags;
1145
1146 return err;
1147}
1148
1149static int compat_private_call(struct net_device *dev, struct iwreq *iwr,
1150 unsigned int cmd, iw_handler handler)
1151{
1152 const struct iw_priv_args *descr;
1153 struct iw_request_info info;
1154 int ret, extra_size;
1155
1156 extra_size = get_priv_descr_and_size(dev, cmd, &descr);
1157
1158 /* Prepare the call */
1159 info.cmd = cmd;
1160 info.flags = 0;
1161
1162 /* Check if we have a pointer to user space data or not. */
1163 if (extra_size == 0) {
1164 /* No extra arguments. Trivial to handle */
1165 ret = handler(dev, &info, &(iwr->u), (char *) &(iwr->u));
1166 } else {
1167 struct compat_iw_point *iwp_compat;
1168 struct iw_point iwp;
1169
1170 iwp_compat = (struct compat_iw_point *) &iwr->u.data;
1171 iwp.pointer = compat_ptr(iwp_compat->pointer);
1172 iwp.length = iwp_compat->length;
1173 iwp.flags = iwp_compat->flags;
1174
1175 ret = ioctl_private_iw_point(&iwp, cmd, descr,
1176 handler, dev, &info, extra_size);
1177
1178 iwp_compat->pointer = ptr_to_compat(iwp.pointer);
1179 iwp_compat->length = iwp.length;
1180 iwp_compat->flags = iwp.flags;
1181 }
1182
1183 /* Call commit handler if needed and defined */
1184 if (ret == -EIWCOMMIT)
1185 ret = call_commit_handler(dev);
1186
1187 return ret;
1188}
1189
1190int compat_wext_handle_ioctl(struct net *net, unsigned int cmd,
1191 unsigned long arg)
1192{
1193 void __user *argp = (void __user *)arg;
1194 struct iwreq iwr;
1195 char *colon;
1196 int ret;
1197
1198 if (copy_from_user(&iwr, argp, sizeof(struct iwreq)))
1199 return -EFAULT;
1200
1201 iwr.ifr_name[IFNAMSIZ-1] = 0;
1202 colon = strchr(iwr.ifr_name, ':');
1203 if (colon)
1204 *colon = 0;
1205
1206 ret = wext_ioctl_dispatch(net, (struct ifreq *) &iwr, cmd,
1207 compat_standard_call,
1208 compat_private_call);
1209
1210 if (ret >= 0 &&
1211 IW_IS_GET(cmd) &&
1212 copy_to_user(argp, &iwr, sizeof(struct iwreq)))
1213 return -EFAULT;
1214
1215 return ret;
1216}
1217#endif
1218
1115/************************* EVENT PROCESSING *************************/ 1219/************************* EVENT PROCESSING *************************/
1116/* 1220/*
1117 * Process events generated by the wireless layer or the driver. 1221 * Process events generated by the wireless layer or the driver.