Dan Williams wrote: > <hidden> this is something that ieee80211 does that's completely wrong.
Because it is not a part of the 802.11 specification, AP vendors have each implemented their own method for disguising the SSID. Some set the length to the actual SSID length but put fill the SSID with '\0', some set the length and SSID to a single space, some set the length to 0. Since the scan results are supposed to report networks found; the first agreement we need to make between user space and the kernel is how we define a 'network', and how do we determine when a network has been updated? Take the following flow where you have an AP that supports two networks on the same channel using the same MAC, but does not beacon a hidden network if a non-hidden network also exists: Indirect scan finds via probe request: ssid_len=3, ssid=Foo, channel 1, BSSID: 00:0e:de:ad:be:ef and via beacons: ssid_len=3, ssid=Foo, channel 1, BSSID: 00:0e:de:ad:be:ef The user configures the SSID to look for to be Bar. A direct scan for 'Bar' is sent, and the following is found via probe request: ssid_len=3, ssid=Bar, channel 1, BSSID: 00:0e:de:ad:be:ef and via beacons: ssid_len=3, ssid=Foo, channel 1, BSSID: 00:0e:de:ad:be:ef The network Bar is associated with, and time passes with no data or probe requests being sent (idle network). Beacons are received for Foo, but nothing for Bar (since the AP isn't beaconing hidden networks). Now you look for scan results with an indirect scan, and you will only see: ssid_len=3, ssid=Foo, channel 1, BSSID: 00:0e:de:ad:be:ef Aside from the probe response for Bar, there are never any beacons that indicate that the network Bar still exists. Scan results *should* display Foo and Bar, but the current ieee80211 subsystem will filter out Bar once 15s has passed without receiving a probe response. Currently ieee80211 does not differentiate between probe responses and beacons for collecting network data. To "fix" the problem we have now, ieee80211 needs to be changed to be able to distinguish between probe respones and beacons, and update all networks that match channel and MAC when a beacon is received (regardless of SSID) and update a specific network if the frame is a probe response. If the above change is made, we can perhaps remove all knowledge of a hidden vs. broadcast network from the drivers and ieee80211 subsystem. > Drivers need to report the _exact_ ESSID from the air in their scan > results. It's up to the user space app to deal with ESSID length of 0. Agree the kernel should pass the SSID as received. Ideally user space should just register to receive all beacons and probe responses from the network device and do all the parsing and network management, with a timing interval specified for frequency to receive beacons/probe responses that have not changed (although one packet every 100ms isn't likely to cause too much thrash) Exporting the entire frame allows user space to provide information on 802.11h, 802.11e, 802.11i and other network capabilities that currently aren't exposed via the wireless extension interface. Doing this also has the advantage of being able to remove all scan and network collection logistics out of the kernel and into user space. In light of the above, I started playing with a raw packet interface on the ipw2200 and ipw3945 projects that export all frames to user space in radiotap format through a 2nd network device. I am working on changing the way the raw packet interface is configured to be via netlink (vs. a sysfs entry) but you can apply it to ipw2200-1.1.1 via http://ipw2200.sf.net/ipw2200-1.1.1-rtap_iface.patch if interested. > Signed-off-by: Dan Williams <[EMAIL PROTECTED]> > > --- net/ieee80211/ieee80211_wx.c 2006-03-24 10:43:04.000000000 -0500 > +++ net/ieee80211/ieee80211_wx.c 2006-03-24 10:53:27.000000000 -0500 > @@ -64,8 +64,8 @@ > iwe.cmd = SIOCGIWESSID; > iwe.u.data.flags = 1; > if (network->flags & NETWORK_EMPTY_ESSID) { > - iwe.u.data.length = sizeof("<hidden>"); > - start = iwe_stream_add_point(start, stop, &iwe, "<hidden>"); > + iwe.u.data.length = 0; > + start = iwe_stream_add_point(start, stop, &iwe, ""); > } else { > iwe.u.data.length = min(network->ssid_len, (u8) 32); > start = iwe_stream_add_point(start, stop, &iwe, network->ssid); See (untested) attached to change ieee80211 to expose the SSID as received. James
ieee80211: Change _rx and _wx to export full SSIDs as received over air This patch modifies the frame parsing code to copy the contents of a "hidden" network's SSID information element as well as modify the wireless extension handler for providing that information to user space. With this patch applied, no "<hidden>" network string will be returned to user space -- it is up to user space to determine if a network is hidden or not. Signed-off-by: James Ketrenos <[EMAIL PROTECTED]> --- ieee80211/ieee80211_rx.c | 4 +--- ieee80211/ieee80211_wx.c | 11 +++-------- 2 files changed, 4 insertions(+), 11 deletions(-) --- a/net/ieee80211/ieee80211_rx.c 2006-03-24 10:50:00.000000000 -0600 +++ b/net/ieee80211/ieee80211_rx.c 2006-03-24 10:50:23.000000000 -0600 @@ -1000,10 +1000,8 @@ static int ieee80211_parse_info_param(st switch (info_element->id) { case MFIE_TYPE_SSID: if (ieee80211_is_empty_essid(info_element->data, - info_element->len)) { + info_element->len)) network->flags |= NETWORK_EMPTY_ESSID; - break; - } network->ssid_len = min(info_element->len, (u8) IW_ESSID_MAX_SIZE); --- a/net/ieee80211/ieee80211_wx.c 2006-03-24 10:50:06.000000000 -0600 +++ a/net/ieee80211/ieee80211_wx.c 2006-03-24 10:50:54.000000000 -0600 @@ -63,14 +63,9 @@ static char *ipw2100_translate_scan(stru /* Add the ESSID */ iwe.cmd = SIOCGIWESSID; iwe.u.data.flags = 1; - if (network->flags & NETWORK_EMPTY_ESSID) { - iwe.u.data.length = sizeof("<hidden>"); - start = iwe_stream_add_point(start, stop, &iwe, "<hidden>"); - } else { - iwe.u.data.length = min(network->ssid_len, (u8) 32); - start = iwe_stream_add_point(start, stop, &iwe, network->ssid); - } - + iwe.u.data.length = min(network->ssid_len, (u8) 32); + start = iwe_stream_add_point(start, stop, &iwe, network->ssid); + /* Add the protocol name */ iwe.cmd = SIOCGIWNAME; snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s",