[wpa-supplicant] Wireless-extension v19

Jean Tourrilhes jt at hpl.hp.com
Fri Sep 9 13:04:52 EDT 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