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)

_______________________________________________
NetworkManager-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/networkmanager-list

Reply via email to