Functions | |
| int | net80211_prepare_probe (struct net80211_device *dev, int band, int active) |
| Prepare 802.11 device channel and rate set for scanning. | |
| struct net80211_probe_ctx * | net80211_probe_start (struct net80211_device *dev, const char *essid, int active) |
| Begin probe of 802.11 networks. | |
| int | net80211_probe_step (struct net80211_probe_ctx *ctx) |
| Continue probe of 802.11 networks. | |
| struct net80211_wlan * | net80211_probe_finish_best (struct net80211_probe_ctx *ctx) |
| Finish probe of 802.11 networks, returning best-signal network found. | |
| struct list_head * | net80211_probe_finish_all (struct net80211_probe_ctx *ctx) |
| Finish probe of 802.11 networks, returning all networks found. | |
| void | net80211_free_wlan (struct net80211_wlan *wlan) |
| Free WLAN structure. | |
| void | net80211_free_wlanlist (struct list_head *list) |
| Free list of WLAN structures. | |
| int net80211_prepare_probe | ( | struct net80211_device * | dev, | |
| int | band, | |||
| int | active | |||
| ) |
Prepare 802.11 device channel and rate set for scanning.
| dev | 802.11 device | |
| band | RF band(s) on which to prepare for scanning | |
| active | Whether the scanning will be active |
| rc | Return status code |
Definition at line 2064 of file net80211.c.
References assert, net80211_channel::band, net80211_device::channel, net80211_device::channels, net80211_device_operations::config, DBGC, EINVAL_ACTIVE_SCAN, net80211_device::hw, net80211_add_channels(), NET80211_BAND_BIT_2GHZ, NET80211_BAND_BIT_5GHZ, NET80211_CFG_CHANNEL, NET80211_CFG_RATE, net80211_filter_hw_channels(), NET80211_REG_TXPOWER, net80211_device::netdev, netdev_is_open(), net80211_device::nr_channels, net80211_device::nr_rates, net80211_device::op, net80211_device::rate, net80211_hw_info::rates, and net80211_device::rates.
Referenced by iwlist(), and net80211_step_associate().
02066 { 02067 assert ( netdev_is_open ( dev->netdev ) ); 02068 02069 if ( active && ( band & NET80211_BAND_BIT_5GHZ ) ) { 02070 DBGC ( dev, "802.11 %p cannot perform active scanning on " 02071 "5GHz band\n", dev ); 02072 return -EINVAL_ACTIVE_SCAN; 02073 } 02074 02075 if ( band == 0 ) { 02076 /* This can happen for a 5GHz-only card with 5GHz 02077 scanning masked out by an active request. */ 02078 DBGC ( dev, "802.11 %p asked to prepare for scanning nothing\n", 02079 dev ); 02080 return -EINVAL_ACTIVE_SCAN; 02081 } 02082 02083 dev->nr_channels = 0; 02084 02085 if ( active ) 02086 net80211_add_channels ( dev, 1, 11, NET80211_REG_TXPOWER ); 02087 else { 02088 if ( band & NET80211_BAND_BIT_2GHZ ) 02089 net80211_add_channels ( dev, 1, 14, 02090 NET80211_REG_TXPOWER ); 02091 if ( band & NET80211_BAND_BIT_5GHZ ) 02092 net80211_add_channels ( dev, 36, 8, 02093 NET80211_REG_TXPOWER ); 02094 } 02095 02096 net80211_filter_hw_channels ( dev ); 02097 02098 /* Use channel 1 for now */ 02099 dev->channel = 0; 02100 dev->op->config ( dev, NET80211_CFG_CHANNEL ); 02101 02102 /* Always do active probes at lowest (presumably first) speed */ 02103 dev->rate = 0; 02104 dev->nr_rates = 1; 02105 dev->rates[0] = dev->hw->rates[dev->channels[0].band][0]; 02106 dev->op->config ( dev, NET80211_CFG_RATE ); 02107 02108 return 0; 02109 }
| struct net80211_probe_ctx* net80211_probe_start | ( | struct net80211_device * | dev, | |
| const char * | essid, | |||
| int | active | |||
| ) | [read] |
Begin probe of 802.11 networks.
| dev | 802.11 device | |
| essid | SSID to probe for, or "" to accept any (may not be NULL) | |
| active | Whether to use active scanning |
| ctx | Probe context |
A NULL return indicates an out-of-memory condition.
The returned context must be periodically passed to net80211_probe_step() until that function returns zero.
Definition at line 1298 of file net80211.c.
References alloc_iob(), assert, net80211_probe_ctx::beacons, net80211_device::channel, net80211_device_operations::config, currticks(), io_buffer::data, net80211_probe_ctx::dev, net80211_device::essid, net80211_probe_ctx::essid, net80211_probe_ctx::hop_step, net80211_probe_ctx::hop_time, IEEE80211_TYP_FRAME_HEADER_LEN, ieee80211_probe_req::info_element, INIT_LIST_HEAD, iob_put, iob_reserve, malloc(), NET80211_CFG_CHANNEL, net80211_keep_mgmt(), net80211_marshal_request_info(), net80211_device::netdev, netdev_is_open(), net80211_device::nr_channels, NULL, net80211_probe_ctx::old_keep_mgmt, net80211_device::op, net80211_probe_ctx::probe, strcpy(), net80211_probe_ctx::ticks_beacon, net80211_probe_ctx::ticks_channel, ticks_per_sec(), net80211_probe_ctx::ticks_start, and zalloc().
Referenced by iwlist(), and net80211_step_associate().
01301 { 01302 struct net80211_probe_ctx *ctx = zalloc ( sizeof ( *ctx ) ); 01303 01304 if ( ! ctx ) 01305 return NULL; 01306 01307 assert ( netdev_is_open ( dev->netdev ) ); 01308 01309 ctx->dev = dev; 01310 ctx->old_keep_mgmt = net80211_keep_mgmt ( dev, 1 ); 01311 ctx->essid = essid; 01312 if ( dev->essid != ctx->essid ) 01313 strcpy ( dev->essid, ctx->essid ); 01314 01315 if ( active ) { 01316 struct ieee80211_probe_req *probe_req; 01317 union ieee80211_ie *ie; 01318 01319 ctx->probe = alloc_iob ( 128 ); 01320 iob_reserve ( ctx->probe, IEEE80211_TYP_FRAME_HEADER_LEN ); 01321 probe_req = ctx->probe->data; 01322 01323 ie = net80211_marshal_request_info ( dev, 01324 probe_req->info_element ); 01325 01326 iob_put ( ctx->probe, ( void * ) ie - ctx->probe->data ); 01327 } 01328 01329 ctx->ticks_start = currticks(); 01330 ctx->ticks_beacon = 0; 01331 ctx->ticks_channel = currticks(); 01332 ctx->hop_time = ticks_per_sec() / ( active ? 2 : 6 ); 01333 01334 /* 01335 * Channels on 2.4GHz overlap, and the most commonly used 01336 * are 1, 6, and 11. We'll get a result faster if we check 01337 * every 5 channels, but in order to hit all of them the 01338 * number of channels must be relatively prime to 5. If it's 01339 * not, tweak the hop. 01340 */ 01341 ctx->hop_step = 5; 01342 while ( dev->nr_channels % ctx->hop_step == 0 && ctx->hop_step > 1 ) 01343 ctx->hop_step--; 01344 01345 ctx->beacons = malloc ( sizeof ( *ctx->beacons ) ); 01346 INIT_LIST_HEAD ( ctx->beacons ); 01347 01348 dev->channel = 0; 01349 dev->op->config ( dev, NET80211_CFG_CHANNEL ); 01350 01351 return ctx; 01352 }
| int net80211_probe_step | ( | struct net80211_probe_ctx * | ctx | ) |
Continue probe of 802.11 networks.
| ctx | Probe context returned by net80211_probe_start() |
| rc | Probe status |
Whether the probe succeeded or failed, you must call net80211_probe_finish_all() or net80211_probe_finish_best() (depending on whether you want information on all networks or just the best-signal one) in order to release the probe context. A failed probe may still have acquired some valid data.
Definition at line 1371 of file net80211.c.
References ieee80211_frame::addr3, alloc_iob(), net80211_wlan::beacon, net80211_probe_ctx::beacons, net80211_wlan::bssid, net80211_wlan::channel, net80211_device::channel, net80211_hw_info::channel_change_time, net80211_channel::channel_nr, net80211_device::channels, net80211_device_operations::config, net80211_wlan::crypto, currticks(), ieee80211_frame::data, io_buffer::data, DBG, DBGC, DBGC2, net80211_probe_ctx::dev, ENOTSUP, net80211_wlan::essid, net80211_probe_ctx::essid, ETH_ALEN, eth_ntoa(), ETIMEDOUT, ieee80211_frame::fc, free_iob(), net80211_wlan::handshaking, io_buffer::head, net80211_probe_ctx::hop_step, net80211_probe_ctx::hop_time, net80211_device::hw, ieee80211_ie::id, ieee80211_beacon, IEEE80211_CAPAB_PRIVACY, IEEE80211_FC_SUBTYPE, ieee80211_ie_bound(), IEEE80211_IE_SSID, IEEE80211_MAX_SSID_LEN, ieee80211_next_ie(), IEEE80211_STYPE_BEACON, IEEE80211_STYPE_PROBE_REQ, IEEE80211_STYPE_PROBE_RESP, iob_disown, iob_headroom(), iob_len(), iob_put, iob_reserve, ieee80211_ie::len, net80211_wlan::list, list_add_tail, list_empty(), list_for_each_entry, memcpy, NET80211_CFG_CHANNEL, NET80211_CRYPT_NONE, NET80211_CRYPT_UNKNOWN, net80211_ll_broadcast, net80211_mgmt_dequeue(), NET80211_PROBE_GATHER, NET80211_PROBE_GATHER_ALL, NET80211_PROBE_TIMEOUT, NET80211_SECPROT_NONE, NET80211_SECPROT_UNKNOWN, net80211_tx_mgmt(), net80211_device::nr_channels, NULL, net80211_device::op, net80211_probe_ctx::probe, sec80211_detect(), net80211_wlan::signal, ieee80211_ie::ssid, strcmp(), strcpy(), strerror(), io_buffer::tail, net80211_probe_ctx::ticks_beacon, net80211_probe_ctx::ticks_channel, ticks_per_sec(), net80211_probe_ctx::ticks_start, u16, u32, udelay(), and zalloc().
Referenced by iwlist(), and net80211_step_associate().
01372 { 01373 struct net80211_device *dev = ctx->dev; 01374 u32 start_timeout = NET80211_PROBE_TIMEOUT * ticks_per_sec(); 01375 u32 gather_timeout = ticks_per_sec(); 01376 u32 now = currticks(); 01377 struct io_buffer *iob; 01378 int signal; 01379 int rc; 01380 char ssid[IEEE80211_MAX_SSID_LEN + 1]; 01381 01382 gather_timeout *= ( ctx->essid[0] ? NET80211_PROBE_GATHER : 01383 NET80211_PROBE_GATHER_ALL ); 01384 01385 /* Time out if necessary */ 01386 if ( now >= ctx->ticks_start + start_timeout ) 01387 return list_empty ( ctx->beacons ) ? -ETIMEDOUT : +1; 01388 01389 if ( ctx->ticks_beacon > 0 && now >= ctx->ticks_start + gather_timeout ) 01390 return +1; 01391 01392 /* Change channels if necessary */ 01393 if ( now >= ctx->ticks_channel + ctx->hop_time ) { 01394 dev->channel = ( dev->channel + ctx->hop_step ) 01395 % dev->nr_channels; 01396 dev->op->config ( dev, NET80211_CFG_CHANNEL ); 01397 udelay ( dev->hw->channel_change_time ); 01398 01399 ctx->ticks_channel = now; 01400 01401 if ( ctx->probe ) { 01402 struct io_buffer *siob = ctx->probe; /* to send */ 01403 01404 /* make a copy for future use */ 01405 iob = alloc_iob ( siob->tail - siob->head ); 01406 iob_reserve ( iob, iob_headroom ( siob ) ); 01407 memcpy ( iob_put ( iob, iob_len ( siob ) ), 01408 siob->data, iob_len ( siob ) ); 01409 01410 ctx->probe = iob; 01411 rc = net80211_tx_mgmt ( dev, IEEE80211_STYPE_PROBE_REQ, 01412 net80211_ll_broadcast, 01413 iob_disown ( siob ) ); 01414 if ( rc ) { 01415 DBGC ( dev, "802.11 %p send probe failed: " 01416 "%s\n", dev, strerror ( rc ) ); 01417 return rc; 01418 } 01419 } 01420 } 01421 01422 /* Check for new management packets */ 01423 while ( ( iob = net80211_mgmt_dequeue ( dev, &signal ) ) != NULL ) { 01424 struct ieee80211_frame *hdr; 01425 struct ieee80211_beacon *beacon; 01426 union ieee80211_ie *ie; 01427 struct net80211_wlan *wlan; 01428 u16 type; 01429 01430 hdr = iob->data; 01431 type = hdr->fc & IEEE80211_FC_SUBTYPE; 01432 beacon = ( struct ieee80211_beacon * ) hdr->data; 01433 01434 if ( type != IEEE80211_STYPE_BEACON && 01435 type != IEEE80211_STYPE_PROBE_RESP ) { 01436 DBGC2 ( dev, "802.11 %p probe: non-beacon\n", dev ); 01437 goto drop; 01438 } 01439 01440 if ( ( void * ) beacon->info_element >= iob->tail ) { 01441 DBGC ( dev, "802.11 %p probe: beacon with no IEs\n", 01442 dev ); 01443 goto drop; 01444 } 01445 01446 ie = beacon->info_element; 01447 01448 if ( ! ieee80211_ie_bound ( ie, iob->tail ) ) 01449 ie = NULL; 01450 01451 while ( ie && ie->id != IEEE80211_IE_SSID ) 01452 ie = ieee80211_next_ie ( ie, iob->tail ); 01453 01454 if ( ! ie ) { 01455 DBGC ( dev, "802.11 %p probe: beacon with no SSID\n", 01456 dev ); 01457 goto drop; 01458 } 01459 01460 memcpy ( ssid, ie->ssid, ie->len ); 01461 ssid[ie->len] = 0; 01462 01463 if ( ctx->essid[0] && strcmp ( ctx->essid, ssid ) != 0 ) { 01464 DBGC2 ( dev, "802.11 %p probe: beacon with wrong SSID " 01465 "(%s)\n", dev, ssid ); 01466 goto drop; 01467 } 01468 01469 /* See if we've got an entry for this network */ 01470 list_for_each_entry ( wlan, ctx->beacons, list ) { 01471 if ( strcmp ( wlan->essid, ssid ) != 0 ) 01472 continue; 01473 01474 if ( signal < wlan->signal ) { 01475 DBGC2 ( dev, "802.11 %p probe: beacon for %s " 01476 "(%s) with weaker signal %d\n", dev, 01477 ssid, eth_ntoa ( hdr->addr3 ), signal ); 01478 goto drop; 01479 } 01480 01481 goto fill; 01482 } 01483 01484 /* No entry yet - make one */ 01485 wlan = zalloc ( sizeof ( *wlan ) ); 01486 strcpy ( wlan->essid, ssid ); 01487 list_add_tail ( &wlan->list, ctx->beacons ); 01488 01489 /* Whether we're using an old entry or a new one, fill 01490 it with new data. */ 01491 fill: 01492 memcpy ( wlan->bssid, hdr->addr3, ETH_ALEN ); 01493 wlan->signal = signal; 01494 wlan->channel = dev->channels[dev->channel].channel_nr; 01495 01496 /* Copy this I/O buffer into a new wlan->beacon; the 01497 * iob we've got probably came from the device driver 01498 * and may have the full 2.4k allocation, which we 01499 * don't want to keep around wasting memory. 01500 */ 01501 free_iob ( wlan->beacon ); 01502 wlan->beacon = alloc_iob ( iob_len ( iob ) ); 01503 memcpy ( iob_put ( wlan->beacon, iob_len ( iob ) ), 01504 iob->data, iob_len ( iob ) ); 01505 01506 if ( ( rc = sec80211_detect ( wlan->beacon, &wlan->handshaking, 01507 &wlan->crypto ) ) == -ENOTSUP ) { 01508 struct ieee80211_beacon *beacon = 01509 ( struct ieee80211_beacon * ) hdr->data; 01510 01511 if ( beacon->capability & IEEE80211_CAPAB_PRIVACY ) { 01512 DBG ( "802.11 %p probe: secured network %s but " 01513 "encryption support not compiled in\n", 01514 dev, wlan->essid ); 01515 wlan->handshaking = NET80211_SECPROT_UNKNOWN; 01516 wlan->crypto = NET80211_CRYPT_UNKNOWN; 01517 } else { 01518 wlan->handshaking = NET80211_SECPROT_NONE; 01519 wlan->crypto = NET80211_CRYPT_NONE; 01520 } 01521 } else if ( rc != 0 ) { 01522 DBGC ( dev, "802.11 %p probe warning: network " 01523 "%s with unidentifiable security " 01524 "settings: %s\n", dev, wlan->essid, 01525 strerror ( rc ) ); 01526 } 01527 01528 ctx->ticks_beacon = now; 01529 01530 DBGC2 ( dev, "802.11 %p probe: good beacon for %s (%s)\n", 01531 dev, wlan->essid, eth_ntoa ( wlan->bssid ) ); 01532 01533 drop: 01534 free_iob ( iob ); 01535 } 01536 01537 return 0; 01538 }
| struct net80211_wlan* net80211_probe_finish_best | ( | struct net80211_probe_ctx * | ctx | ) | [read] |
Finish probe of 802.11 networks, returning best-signal network found.
| ctx | Probe context |
| wlan | Best-signal network found, or NULL if none were found |
Definition at line 1552 of file net80211.c.
References net80211_probe_ctx::beacons, DBGC, net80211_probe_ctx::dev, net80211_probe_ctx::essid, free(), free_iob(), net80211_wlan::list, list_del, list_for_each_entry, net80211_free_wlanlist(), net80211_keep_mgmt(), NULL, net80211_probe_ctx::old_keep_mgmt, net80211_probe_ctx::probe, and net80211_wlan::signal.
Referenced by net80211_autoassociate(), and net80211_step_associate().
01553 { 01554 struct net80211_wlan *best = NULL, *wlan; 01555 01556 if ( ! ctx ) 01557 return NULL; 01558 01559 list_for_each_entry ( wlan, ctx->beacons, list ) { 01560 if ( ! best || best->signal < wlan->signal ) 01561 best = wlan; 01562 } 01563 01564 if ( best ) 01565 list_del ( &best->list ); 01566 else 01567 DBGC ( ctx->dev, "802.11 %p probe: found nothing for '%s'\n", 01568 ctx->dev, ctx->essid ); 01569 01570 net80211_free_wlanlist ( ctx->beacons ); 01571 01572 net80211_keep_mgmt ( ctx->dev, ctx->old_keep_mgmt ); 01573 01574 if ( ctx->probe ) 01575 free_iob ( ctx->probe ); 01576 01577 free ( ctx ); 01578 01579 return best; 01580 }
| struct list_head* net80211_probe_finish_all | ( | struct net80211_probe_ctx * | ctx | ) | [read] |
Finish probe of 802.11 networks, returning all networks found.
| ctx | Probe context |
| list | List of net80211_wlan detailing networks found |
Definition at line 1593 of file net80211.c.
References net80211_probe_ctx::beacons, net80211_probe_ctx::dev, free(), free_iob(), net80211_keep_mgmt(), NULL, net80211_probe_ctx::old_keep_mgmt, and net80211_probe_ctx::probe.
Referenced by iwlist().
01594 { 01595 struct list_head *beacons = ctx->beacons; 01596 01597 if ( ! ctx ) 01598 return NULL; 01599 01600 net80211_keep_mgmt ( ctx->dev, ctx->old_keep_mgmt ); 01601 01602 if ( ctx->probe ) 01603 free_iob ( ctx->probe ); 01604 01605 free ( ctx ); 01606 01607 return beacons; 01608 }
| void net80211_free_wlan | ( | struct net80211_wlan * | wlan | ) |
Free WLAN structure.
| wlan | WLAN structure to free |
Definition at line 1616 of file net80211.c.
References net80211_wlan::beacon, free(), and free_iob().
Referenced by net80211_autoassociate(), net80211_free_wlanlist(), and net80211_step_associate().
| void net80211_free_wlanlist | ( | struct list_head * | list | ) |
Free list of WLAN structures.
| list | List of WLAN structures to free |
Definition at line 1630 of file net80211.c.
References free(), net80211_wlan::list, list_del, list_for_each_entry_safe, and net80211_free_wlan().
Referenced by iwlist(), and net80211_probe_finish_best().
01631 { 01632 struct net80211_wlan *wlan, *tmp; 01633 01634 if ( ! list ) 01635 return; 01636 01637 list_for_each_entry_safe ( wlan, tmp, list, list ) { 01638 list_del ( &wlan->list ); 01639 net80211_free_wlan ( wlan ); 01640 } 01641 01642 free ( list ); 01643 }
1.5.7.1