--- net/mac80211/ieee80211.c | 5 + net/mac80211/ieee80211_ioctl.c | 121 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+) --- everything.orig/net/mac80211/ieee80211_ioctl.c 2007-11-07 13:06:34.902124618 +0100 +++ everything/net/mac80211/ieee80211_ioctl.c 2007-11-07 13:19:24.311521482 +0100 @@ -21,6 +21,7 @@ #include #include "ieee80211_i.h" +#include "hostapd_ioctl.h" #include "ieee80211_rate.h" #include "wpa.h" #include "aes_ccm.h" @@ -124,6 +125,47 @@ static int ieee80211_ioctl_siwgenie(stru return -EOPNOTSUPP; } + +static int ieee80211_ioctl_priv_hostapd(struct net_device *dev, + struct iw_point *p) +{ + struct prism2_hostapd_param *param; + int ret = 0; + + if (p->length < sizeof(struct prism2_hostapd_param) || + p->length > PRISM2_HOSTAPD_MAX_BUF_SIZE || !p->pointer) { + printk(KERN_DEBUG "%s: hostapd ioctl: ptr=%p len=%d min=%d " + "max=%d\n", dev->name, p->pointer, p->length, + (int)sizeof(struct prism2_hostapd_param), + PRISM2_HOSTAPD_MAX_BUF_SIZE); + return -EINVAL; + } + + param = kmalloc(p->length, GFP_KERNEL); + if (!param) + return -ENOMEM; + + if (copy_from_user(param, p->pointer, p->length)) { + ret = -EFAULT; + goto out; + } + + switch (param->cmd) { + default: + ret = -EOPNOTSUPP; + break; + } + + if (copy_to_user(p->pointer, param, p->length)) + ret = -EFAULT; + + out: + kfree(param); + + return ret; +} + + static int ieee80211_ioctl_giwname(struct net_device *dev, struct iw_request_info *info, char *name, char *extra) @@ -819,6 +861,49 @@ static int ieee80211_ioctl_giwretry(stru return 0; } +static int ieee80211_ioctl_prism2_param(struct net_device *dev, + struct iw_request_info *info, + void *wrqu, char *extra) +{ + struct ieee80211_sub_if_data *sdata; + int *i = (int *) extra; + int param = *i; + int ret = 0; + + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + sdata = IEEE80211_DEV_TO_SUB_IF(dev); + + switch (param) { + default: + ret = -EOPNOTSUPP; + break; + } + + return ret; +} + + +static int ieee80211_ioctl_get_prism2_param(struct net_device *dev, + struct iw_request_info *info, + void *wrqu, char *extra) +{ + struct ieee80211_sub_if_data *sdata; + int *param = (int *) extra; + int ret = 0; + + sdata = IEEE80211_DEV_TO_SUB_IF(dev); + + switch (*param) { + default: + ret = -EOPNOTSUPP; + break; + } + + return ret; +} + static int ieee80211_ioctl_siwmlme(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *extra) @@ -1073,6 +1158,32 @@ static int ieee80211_ioctl_siwencodeext( } +static const struct iw_priv_args ieee80211_ioctl_priv[] = { + { PRISM2_IOCTL_PRISM2_PARAM, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "param" }, + { PRISM2_IOCTL_GET_PRISM2_PARAM, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_param" }, +}; + + +int ieee80211_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + struct iwreq *wrq = (struct iwreq *) rq; + + switch (cmd) { + /* Private ioctls (iwpriv) that have not yet been converted + * into new wireless extensions API */ + case PRISM2_IOCTL_HOSTAPD: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + return ieee80211_ioctl_priv_hostapd(dev, &wrq->u.data); + default: + return -EOPNOTSUPP; + } +} + + /* Structures to export the Wireless Handlers */ static const iw_handler ieee80211_handler[] = @@ -1135,9 +1246,19 @@ static const iw_handler ieee80211_handle (iw_handler) NULL, /* -- hole -- */ }; +static const iw_handler ieee80211_private_handler[] = +{ /* SIOCIWFIRSTPRIV + */ + (iw_handler) ieee80211_ioctl_prism2_param, /* 0 */ + (iw_handler) ieee80211_ioctl_get_prism2_param, /* 1 */ +}; + const struct iw_handler_def ieee80211_iw_handler_def = { .num_standard = ARRAY_SIZE(ieee80211_handler), + .num_private = ARRAY_SIZE(ieee80211_private_handler), + .num_private_args = ARRAY_SIZE(ieee80211_ioctl_priv), .standard = (iw_handler *) ieee80211_handler, + .private = (iw_handler *) ieee80211_private_handler, + .private_args = (struct iw_priv_args *) ieee80211_ioctl_priv, .get_wireless_stats = ieee80211_get_wireless_stats, }; --- everything.orig/net/mac80211/ieee80211.c 2007-11-07 13:18:36.001511500 +0100 +++ everything/net/mac80211/ieee80211.c 2007-11-07 13:19:24.311521482 +0100 @@ -413,6 +413,9 @@ static const struct header_ops ieee80211 .cache_update = eth_header_cache_update, }; +/* HACK */ +extern int ieee80211_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); + /* Must not be called for mdev */ void ieee80211_if_setup(struct net_device *dev) { @@ -425,6 +428,8 @@ void ieee80211_if_setup(struct net_devic dev->open = ieee80211_open; dev->stop = ieee80211_stop; dev->destructor = ieee80211_if_free; + + dev->do_ioctl = ieee80211_ioctl; } /* WDS specialties */