[wpa-supplicant] Wireless-extension v19
Jean Tourrilhes
jt
Fri Sep 9 10:04:52 PDT 2005
On Fri, Sep 09, 2005 at 02:20:01PM +0200, Benoit Boissinot wrote:
> Version 19 of Wireless Extension is now in Linus git tree. It broke
> wpa_supplicant for me (because of changes in iw_handler.h).
>
> I needed the following patch, can someone comment if this is the
> appropriate fix ?
I believe the most appropriate fix would be to make this
function use iw_extract_event_stream() available in iwlib.c, which
does all this magic behind the scenes since WT-27-pre25 (available in
all good distro).
If you really want to roll your own, I believe the fix is
first incomplete and second could be simplified.
First, you would need to fix wpa_driver_wext_event_wireless()
as well, as events have the exact same issue.
Second, you could still copy unconditionally the event before
the switch and only fixup the pointer events with memmove().
Something like :
--------------------------------------------------------------
/* Event data may be unaligned, so make a local, aligned copy
* before processing. */
memcpy(&iwe_buf, pos, sizeof(struct iw_event));
if (iwe->len <= IW_EV_LCP_LEN)
break;
switch (iwe->cmd) {
case SIOCGIWAP:
if (!first)
ap_num++;
first = 0;
if (ap_num < max_size) {
memcpy(results[ap_num].bssid,
iwe->u.ap_addr.sa_data, ETH_ALEN);
}
break;
case SIOCGIWESSID:
+ if(drv->we_version_compiled > 18)
+ memmove((char *)iwe + IW_EV_LCP_LEN + IW_EV_POINT_OFF, (char *)iwe + IW_EV_LCP_LEN, sizeof(struct iw_point) - IW_EV_POINT_OFF);
ssid_len = iwe->u.essid.length;
custom = pos + IW_EV_POINT_LEN;
if (custom + ssid_len > end)
break;
if (iwe->u.essid.flags &&
ssid_len > 0 &&
ssid_len <= IW_ESSID_MAX_SIZE) {
if (ap_num < max_size) {
memcpy(results[ap_num].ssid, custom,
ssid_len);
results[ap_num].ssid_len = ssid_len;
}
}
break;
--------------------------------------------------------------
I think you get the idea...
> thanks,
>
> Benoit Boissinot
Good luck...
Jean
>
>
> diff -Naurp wpa_supplicant-0.4.4/driver_wext.c wpa_supplicant-0.4.4.new/driver_wext.c
> --- wpa_supplicant-0.4.4/driver_wext.c 2005-09-08 16:18:26.000000000 +0200
> +++ wpa_supplicant-0.4.4.new/driver_wext.c 2005-09-09 12:35:58.000000000 +0200
> @@ -42,6 +42,7 @@ struct wpa_driver_wext_data {
> size_t assoc_resp_ies_len;
> struct wpa_driver_capa capa;
> int has_capability;
> + int we_version_compiled;
> };
>
>
> @@ -846,16 +847,22 @@ int wpa_driver_wext_get_scan_results(voi
>
> pos = (char *) res_buf;
> end = (char *) res_buf + len;
> + char * tmp = pos;
>
> while (pos + IW_EV_LCP_LEN <= end) {
> int ssid_len;
> /* Event data may be unaligned, so make a local, aligned copy
> * before processing. */
> - memcpy(&iwe_buf, pos, sizeof(struct iw_event));
> + if(drv->we_version_compiled > 18)
> + memcpy(iwe, pos, IW_EV_LCP_LEN);
> + else
> + memcpy(iwe, pos, sizeof(struct iw_event));
What about :
+ if(drv->we_version_compiled > 18) {
+ memcpy(iwe, pos, IW_EV_LCP_LEN);
+ } else
+ memcpy(iwe, pos, sizeof(struct iw_event));
> if (iwe->len <= IW_EV_LCP_LEN)
> break;
> switch (iwe->cmd) {
> case SIOCGIWAP:
> + if(drv->we_version_compiled > 18)
> + memcpy((char *)iwe + IW_EV_LCP_LEN, pos + IW_EV_LCP_LEN, sizeof(union iwreq_data));
> if (!first)
> ap_num++;
> first = 0;
> @@ -865,6 +872,8 @@ int wpa_driver_wext_get_scan_results(voi
> }
> break;
> case SIOCGIWMODE:
> + if(drv->we_version_compiled > 18)
> + memcpy((char *)iwe + IW_EV_LCP_LEN, pos + IW_EV_LCP_LEN, sizeof(union iwreq_data));
> if (ap_num >= max_size)
> break;
> if (iwe->u.mode == IW_MODE_ADHOC)
> @@ -874,6 +883,8 @@ int wpa_driver_wext_get_scan_results(voi
> results[ap_num].caps |= IEEE80211_CAP_ESS;
> break;
> case SIOCGIWESSID:
> + if(drv->we_version_compiled > 18)
> + memcpy((char *)iwe + IW_EV_LCP_LEN + IW_EV_POINT_OFF, pos + IW_EV_LCP_LEN, sizeof(union iwreq_data));
> ssid_len = iwe->u.essid.length;
> custom = pos + IW_EV_POINT_LEN;
> if (custom + ssid_len > end)
> @@ -889,6 +900,8 @@ int wpa_driver_wext_get_scan_results(voi
> }
> break;
> case SIOCGIWFREQ:
> + if(drv->we_version_compiled > 18)
> + memcpy((char *)iwe + IW_EV_LCP_LEN, pos + IW_EV_LCP_LEN, sizeof(union iwreq_data));
> if (ap_num < max_size) {
> int div = 1000001, i;
> if (iwe->u.freq.e > 6) {
> @@ -906,6 +919,8 @@ int wpa_driver_wext_get_scan_results(voi
> }
> break;
> case IWEVQUAL:
> + if(drv->we_version_compiled > 18)
> + memcpy((char *)iwe + IW_EV_LCP_LEN, pos + IW_EV_LCP_LEN, sizeof(union iwreq_data));
> if (ap_num < max_size) {
> results[ap_num].qual = iwe->u.qual.qual;
> results[ap_num].noise = iwe->u.qual.noise;
> @@ -913,11 +928,15 @@ int wpa_driver_wext_get_scan_results(voi
> }
> break;
> case SIOCGIWENCODE:
> + if(drv->we_version_compiled > 18)
> + memcpy((char *)iwe + IW_EV_LCP_LEN, pos + IW_EV_LCP_LEN, sizeof(union iwreq_data));
> if (ap_num < max_size &&
> !(iwe->u.data.flags & IW_ENCODE_DISABLED))
> results[ap_num].caps |= IEEE80211_CAP_PRIVACY;
> break;
> case SIOCGIWRATE:
> + if(drv->we_version_compiled > 18)
> + memcpy((char *)iwe + IW_EV_LCP_LEN, pos + IW_EV_LCP_LEN, sizeof(union iwreq_data));
> custom = pos + IW_EV_LCP_LEN;
> clen = iwe->len;
> if (custom + clen > end)
> @@ -936,6 +955,8 @@ int wpa_driver_wext_get_scan_results(voi
> results[ap_num].maxrate = maxrate;
> break;
> case IWEVGENIE:
> + if(drv->we_version_compiled > 18)
> + memcpy((char *)iwe + IW_EV_LCP_LEN + IW_EV_POINT_OFF, pos + IW_EV_LCP_LEN, sizeof(union iwreq_data));
> if (ap_num >= max_size)
> break;
> gpos = genie = pos + IW_EV_POINT_LEN;
> @@ -971,6 +992,8 @@ int wpa_driver_wext_get_scan_results(voi
> }
> break;
> case IWEVCUSTOM:
> + if(drv->we_version_compiled > 18)
> + memcpy((char *)iwe + IW_EV_LCP_LEN + IW_EV_POINT_OFF, pos + IW_EV_LCP_LEN, sizeof(union iwreq_data));
> custom = pos + IW_EV_POINT_LEN;
> clen = iwe->u.data.length;
> if (custom + clen > end)
> @@ -1055,6 +1078,7 @@ static int wpa_driver_wext_get_range(voi
> if (ioctl(drv->ioctl_sock, SIOCGIWRANGE, &iwr) < 0) {
> perror("ioctl[SIOCGIWRANGE]");
> return -1;
> + drv->we_version_compiled = range.we_version_compiled;
> } else if (iwr.u.data.length >= minlen &&
> range.we_version_compiled >= 18) {
> wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: WE(compiled)=%d "
> diff -Naurp wpa_supplicant-0.4.4/wireless_copy.h wpa_supplicant-0.4.4.new/wireless_copy.h
> --- wpa_supplicant-0.4.4/wireless_copy.h 2005-08-21 21:24:43.000000000 +0200
> +++ wpa_supplicant-0.4.4.new/wireless_copy.h 2005-09-08 23:13:59.000000000 +0200
> @@ -8,7 +8,7 @@
> /*
> * This file define a set of standard wireless extensions
> *
> - * Version : 18 12.3.05
> + * Version : 19 18.3.05
> *
> * Authors : Jean Tourrilhes - HPL - <jt at hpl.hp.com>
> * Copyright (c) 1997-2005 Jean Tourrilhes, All Rights Reserved.
> @@ -103,7 +103,7 @@ typedef __uint8_t __u8;
> * (there is some stuff that will be added in the future...)
> * I just plan to increment with each new version.
> */
> -#define WIRELESS_EXT 18
> +#define WIRELESS_EXT 19
>
> /*
> * Changes :
> @@ -218,6 +218,15 @@ typedef __uint8_t __u8;
> * related parameters (extensible up to 4096 parameter values)
> * - Add wireless events: IWEVGENIE, IWEVMICHAELMICFAILURE,
> * IWEVASSOCREQIE, IWEVASSOCRESPIE, IWEVPMKIDCAND
> + *
> + * V18 to V19
> + * ----------
> + * - Remove (struct iw_point *)->pointer from events and streams
> + * - Remove header includes to help user space
> + * - Increase IW_ENCODING_TOKEN_MAX from 32 to 64
> + * - Add IW_QUAL_ALL_UPDATED and IW_QUAL_ALL_INVALID macros
> + * - Add explicit flag to tell stats are in dBm : IW_QUAL_DBM
> + * - Add IW_IOCTL_IDX() and IW_EVENT_IDX() macros
> */
>
> /**************************** CONSTANTS ****************************/
> @@ -343,6 +352,7 @@ typedef __uint8_t __u8;
> /* The first and the last (range) */
> #define SIOCIWFIRST 0x8B00
> #define SIOCIWLAST SIOCIWLASTPRIV /* 0x8BFF */
> +#define IW_IOCTL_IDX(cmd) ((cmd) - SIOCIWFIRST)
>
> /* Even : get (world access), odd : set (root access) */
> #define IW_IS_SET(cmd) (!((cmd) & 0x1))
> @@ -387,6 +397,7 @@ typedef __uint8_t __u8;
> * (struct iw_pmkid_cand) */
>
> #define IWEVFIRST 0x8C00
> +#define IW_EVENT_IDX(cmd) ((cmd) - IWEVFIRST)
>
> /* ------------------------- PRIVATE INFO ------------------------- */
> /*
> @@ -448,12 +459,15 @@ typedef __uint8_t __u8;
> #define IW_MODE_MONITOR 6 /* Passive monitor (listen only) */
>
> /* Statistics flags (bitmask in updated) */
> -#define IW_QUAL_QUAL_UPDATED 0x1 /* Value was updated since last read */
> -#define IW_QUAL_LEVEL_UPDATED 0x2
> -#define IW_QUAL_NOISE_UPDATED 0x4
> +#define IW_QUAL_QUAL_UPDATED 0x01 /* Value was updated since last read */
> +#define IW_QUAL_LEVEL_UPDATED 0x02
> +#define IW_QUAL_NOISE_UPDATED 0x04
> +#define IW_QUAL_ALL_UPDATED 0x07
> +#define IW_QUAL_DBM 0x08 /* Level + Noise are dBm */
> #define IW_QUAL_QUAL_INVALID 0x10 /* Driver doesn't provide value */
> #define IW_QUAL_LEVEL_INVALID 0x20
> #define IW_QUAL_NOISE_INVALID 0x40
> +#define IW_QUAL_ALL_INVALID 0x70
>
> /* Frequency flags */
> #define IW_FREQ_AUTO 0x00 /* Let the driver decides */
> @@ -464,7 +478,7 @@ typedef __uint8_t __u8;
> #define IW_MAX_ENCODING_SIZES 8
>
> /* Maximum size of the encoding token in bytes */
> -#define IW_ENCODING_TOKEN_MAX 32 /* 256 bits (for now) */
> +#define IW_ENCODING_TOKEN_MAX 64 /* 512 bits (for now) */
>
> /* Flags for encoding (along with the token) */
> #define IW_ENCODE_INDEX 0x00FF /* Token index (if needed) */
> @@ -1060,12 +1074,16 @@ struct iw_event
> #define IW_EV_CHAR_LEN (IW_EV_LCP_LEN + IFNAMSIZ)
> #define IW_EV_UINT_LEN (IW_EV_LCP_LEN + sizeof(__u32))
> #define IW_EV_FREQ_LEN (IW_EV_LCP_LEN + sizeof(struct iw_freq))
> -#define IW_EV_POINT_LEN (IW_EV_LCP_LEN + sizeof(struct iw_point))
> #define IW_EV_PARAM_LEN (IW_EV_LCP_LEN + sizeof(struct iw_param))
> #define IW_EV_ADDR_LEN (IW_EV_LCP_LEN + sizeof(struct sockaddr))
> #define IW_EV_QUAL_LEN (IW_EV_LCP_LEN + sizeof(struct iw_quality))
>
> -/* Note : in the case of iw_point, the extra data will come at the
> - * end of the event */
> +/* iw_point events are special. First, the payload (extra data) come at
> + * the end of the event, so they are bigger than IW_EV_POINT_LEN. Second,
> + * we omit the pointer, so start at an offset. */
> +#define IW_EV_POINT_OFF (((char *) &(((struct iw_point *) NULL)->length)) - \
> + (char *) NULL)
> +#define IW_EV_POINT_LEN (IW_EV_LCP_LEN + sizeof(struct iw_point) - \
> + IW_EV_POINT_OFF)
>
> #endif /* _LINUX_WIRELESS_H */
More information about the Hostap
mailing list