Re: [PATCH NM 0.6.4] use iwlib scan parsing, fix 32<->64 bit issues



On Thu, 2007-03-22 at 17:21 -0700, Jean Tourrilhes wrote:
> 	Hi,
> 
> 	Johannes Berg has discovered some issues with scanning when
> using 32 bit userspace on 64 bit kernels. I've implemented a fix for
> this in iwlib, and I've just have report that this fix is working.

Committed to the stable branch, thanks.  trunk asks wpa_supplicant to
perform all scanning and gets results via the D-Bus interface.

Dan

> 	The same issue is also present in NetworkManager. Rather than
> bloat further the code of NetworkManager, I've made a patch to make it
> use the iwlib scanning routines. This should both fix this issue, and
> simplify the code and the maintainance of NetworkManager.
> 	Unfortunately, due to some distro compatibility issues, I had
> to work with version 0.6.4. The patch was tested with iwlib v29,
> however iwlib v28 has exactly the same API (but without the fix).
> 
> 	Have fun...
> 
> 	Jean
> 
> -----------------------------------------------------------
> 
> diff -u -p NetworkManager-0.6.4/src/nm-device-802-11-wireless.j1.c NetworkManager-0.6.4/src/nm-device-802-11-wireless.c
> --- NetworkManager-0.6.4/src/nm-device-802-11-wireless.j1.c	2007-03-22 15:28:11.000000000 -0700
> +++ NetworkManager-0.6.4/src/nm-device-802-11-wireless.c	2007-03-22 16:04:54.000000000 -0700
> @@ -3229,48 +3229,32 @@ process_scan_results (NMDevice80211Wirel
>                        const guint8 *res_buf,
>                        guint32 res_buf_len)
>  {
> -	char *pos, *end, *custom, *genie, *gpos, *gend;
> +	char *genie, *gpos, *gend, *custom;
>  	NMAccessPoint *ap = NULL;
>  	size_t clen;
> -	struct iw_param iwp;
>  	int maxrate;
>  	struct iw_event iwe_buf, *iwe = &iwe_buf;
> +	struct stream_descr	stream;
> +	struct wireless_scan *	wscan = NULL;
> +	int			ret;
>  
>  	g_return_val_if_fail (dev != NULL, FALSE);
>  	g_return_val_if_fail (res_buf != NULL, FALSE);
>  	g_return_val_if_fail (res_buf_len > 0, FALSE);
>  
> -	pos = (char *) res_buf;
> -	end = (char *) res_buf + res_buf_len;
> +	/* Init stream descriptor */
> +	iw_init_event_stream(&stream, (char *) res_buf, res_buf_len);
>  
> -	while (pos + IW_EV_LCP_LEN <= end)
> +	while (1)
>  	{
>  		int ssid_len;
>  
> -		/* Event data may be unaligned, so make a local, aligned copy
> -		 * before processing. */
> -		memcpy (&iwe_buf, pos, IW_EV_LCP_LEN);
> -		if (iwe->len <= IW_EV_LCP_LEN)
> +		/* Extract an event */
> +		ret = iw_extract_event_stream(&stream, &iwe_buf, dev->priv->we_version);
> +		if(ret <= 0)
>  			break;
>  
> -		custom = pos + IW_EV_POINT_LEN;
> -		if (dev->priv->we_version > 18 &&
> -		    (iwe->cmd == SIOCGIWESSID ||
> -		     iwe->cmd == SIOCGIWENCODE ||
> -		     iwe->cmd == IWEVGENIE ||
> -		     iwe->cmd == IWEVCUSTOM))
> -		{
> -			/* WE-19 removed the pointer from struct iw_point */
> -			char *dpos = (char *) &iwe_buf.u.data.length;
> -			int dlen = dpos - (char *) &iwe_buf;
> -			memcpy (dpos, pos + IW_EV_LCP_LEN, sizeof (struct iw_event) - dlen);
> -		}
> -		else
> -		{
> -			memcpy (&iwe_buf, pos, sizeof (struct iw_event));
> -			custom += IW_EV_POINT_OFF;
> -		}
> -
> +		iwe = &iwe_buf;		/* Prevent gcc unstrict-aliasing */
>  		switch (iwe->cmd)
>  		{
>  			case SIOCGIWAP:
> @@ -3287,6 +3271,7 @@ process_scan_results (NMDevice80211Wirel
>  				/* New AP with some defaults */
>  				ap = nm_ap_new ();
>  				nm_ap_set_address (ap, (const struct ether_addr *)(iwe->u.ap_addr.sa_data));
> +				maxrate = 0;
>  				break;
>  			case SIOCGIWMODE:
>  				switch (iwe->u.mode)
> @@ -3304,13 +3289,13 @@ process_scan_results (NMDevice80211Wirel
>  				break;
>  			case SIOCGIWESSID:
>  				ssid_len = iwe->u.essid.length;
> -				if (custom + ssid_len > end)
> +				if (!iwe->u.essid.pointer)
>  					break;
>  				if (iwe->u.essid.flags && (ssid_len > 0) && (ssid_len <= IW_ESSID_MAX_SIZE))
>  				{
>  					gboolean set = TRUE;
>  					char *essid = g_malloc (IW_ESSID_MAX_SIZE + 1);
> -					memcpy (essid, custom, ssid_len);
> +					memcpy (essid, iwe->u.essid.pointer, ssid_len);
>  					essid[ssid_len] = '\0';
>  					if (!strlen(essid))
>  						set = FALSE;
> @@ -3340,25 +3325,17 @@ process_scan_results (NMDevice80211Wirel
>  				}
>  				break;
>  			case SIOCGIWRATE:
> -				clen = iwe->len;
> -				if (custom + clen > end)
> -					break;
> -				maxrate = 0;
> -				while (((ssize_t) clen) >= sizeof(struct iw_param))
> +				if(iwe->u.bitrate.value > maxrate)
>  				{
> -					/* the payload may be unaligned, so we align it */
> -					memcpy(&iwp, custom, sizeof (struct iw_param));
> -					if (iwp.value > maxrate)
> -						maxrate = iwp.value;
> -					clen -= sizeof (struct iw_param);
> -					custom += sizeof (struct iw_param);
> +					maxrate = iwe->u.bitrate.value;
> +					nm_ap_set_rate (ap, maxrate);
> +					nm_warning ("get_scan_results(): SIOCGIWRATE new max %d.", maxrate);
>  				}
> -				nm_ap_set_rate (ap, maxrate);
>  				break;
>  			case IWEVGENIE:
> -				gpos = genie = custom;
> +				gpos = genie = iwe->u.data.pointer;
>  				gend = genie + iwe->u.data.length;
> -				if (gend > end)
> +				if (!iwe->u.data.pointer)
>  				{
>  					nm_warning ("get_scan_results(): IWEVGENIE overflow.");
>  					break;
> @@ -3386,8 +3363,9 @@ process_scan_results (NMDevice80211Wirel
>  				}
>  				break;
>  			case IWEVCUSTOM:
> +				custom = iwe->u.data.pointer;
>  				clen = iwe->u.data.length;
> -				if (custom + clen > end)
> +				if (!iwe->u.data.pointer)
>  					break;
>  				if (clen > 7 && ((strncmp (custom, "wpa_ie=", 7) == 0) || (strncmp (custom, "rsn_ie=", 7) == 0)))
>  				{
> @@ -3418,7 +3396,6 @@ process_scan_results (NMDevice80211Wirel
>  				break;
>  		}
>  
> -		pos += iwe->len;
>  	}
>  
>  	if (ap)




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]