00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 FILE_LICENCE ( GPL2_OR_LATER );
00022
00023 #include <string.h>
00024 #include <byteswap.h>
00025 #include <stdlib.h>
00026 #include <gpxe/settings.h>
00027 #include <gpxe/if_arp.h>
00028 #include <gpxe/ethernet.h>
00029 #include <gpxe/ieee80211.h>
00030 #include <gpxe/netdevice.h>
00031 #include <gpxe/net80211.h>
00032 #include <gpxe/sec80211.h>
00033 #include <gpxe/timer.h>
00034 #include <gpxe/nap.h>
00035 #include <unistd.h>
00036 #include <errno.h>
00037
00038
00039
00040
00041
00042
00043
00044 #define EINVAL_PKT_TOO_SHORT ( EINVAL | EUNIQ_01 )
00045 #define EINVAL_PKT_VERSION ( EINVAL | EUNIQ_02 )
00046 #define EINVAL_PKT_NOT_DATA ( EINVAL | EUNIQ_03 )
00047 #define EINVAL_PKT_NOT_FROMDS ( EINVAL | EUNIQ_04 )
00048 #define EINVAL_PKT_LLC_HEADER ( EINVAL | EUNIQ_05 )
00049 #define EINVAL_CRYPTO_REQUEST ( EINVAL | EUNIQ_06 )
00050 #define EINVAL_ACTIVE_SCAN ( EINVAL | EUNIQ_07 )
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 #define E80211_STATUS( stat ) ( ((stat & 0x20)? EHOSTUNREACH : ECONNREFUSED) \
00074 | ((stat & 0x1f) << 8) )
00075
00076
00077 #define E80211_REASON( reas ) ( ((reas & 0x20)? ENETRESET : ECONNRESET) \
00078 | ((reas & 0x1f) << 8) )
00079
00080
00081
00082 static struct list_head net80211_devices = LIST_HEAD_INIT ( net80211_devices );
00083
00084
00085 static struct net80211_device_operations net80211_null_ops;
00086
00087
00088
00089
00090
00091
00092 struct net80211_rx_info {
00093 int signal;
00094 struct list_head list;
00095 };
00096
00097
00098 struct net80211_probe_ctx {
00099
00100 struct net80211_device *dev;
00101
00102
00103 int old_keep_mgmt;
00104
00105
00106 struct io_buffer *probe;
00107
00108
00109 const char *essid;
00110
00111
00112 u32 ticks_start;
00113
00114
00115 u32 ticks_beacon;
00116
00117
00118 u32 ticks_channel;
00119
00120
00121 u32 hop_time;
00122
00123
00124 int hop_step;
00125
00126
00127 struct list_head *beacons;
00128 };
00129
00130
00131 struct net80211_assoc_ctx {
00132
00133 int method;
00134
00135
00136 int last_packet;
00137
00138
00139 int times_tried;
00140 };
00141
00142
00143
00144
00145
00146 static int net80211_netdev_open ( struct net_device *netdev );
00147 static void net80211_netdev_close ( struct net_device *netdev );
00148 static int net80211_netdev_transmit ( struct net_device *netdev,
00149 struct io_buffer *iobuf );
00150 static void net80211_netdev_poll ( struct net_device *netdev );
00151 static void net80211_netdev_irq ( struct net_device *netdev, int enable );
00152
00153
00154
00155
00156
00157
00158 static int net80211_ll_push ( struct net_device *netdev,
00159 struct io_buffer *iobuf, const void *ll_dest,
00160 const void *ll_source, uint16_t net_proto );
00161 static int net80211_ll_pull ( struct net_device *netdev,
00162 struct io_buffer *iobuf, const void **ll_dest,
00163 const void **ll_source, uint16_t * net_proto );
00164
00165
00166
00167
00168
00169
00170 static void net80211_add_channels ( struct net80211_device *dev, int start,
00171 int len, int txpower );
00172 static void net80211_filter_hw_channels ( struct net80211_device *dev );
00173 static void net80211_set_rtscts_rate ( struct net80211_device *dev );
00174 static int net80211_process_capab ( struct net80211_device *dev,
00175 u16 capab );
00176 static int net80211_process_ie ( struct net80211_device *dev,
00177 union ieee80211_ie *ie, void *ie_end );
00178 static union ieee80211_ie *
00179 net80211_marshal_request_info ( struct net80211_device *dev,
00180 union ieee80211_ie *ie );
00181
00182
00183
00184
00185
00186
00187 static void net80211_step_associate ( struct process *proc );
00188 static void net80211_handle_auth ( struct net80211_device *dev,
00189 struct io_buffer *iob );
00190 static void net80211_handle_assoc_reply ( struct net80211_device *dev,
00191 struct io_buffer *iob );
00192 static int net80211_send_disassoc ( struct net80211_device *dev, int reason,
00193 int deauth );
00194 static void net80211_handle_mgmt ( struct net80211_device *dev,
00195 struct io_buffer *iob, int signal );
00196
00197
00198
00199
00200
00201
00202 static void net80211_free_frags ( struct net80211_device *dev, int fcid );
00203 static struct io_buffer *net80211_accum_frags ( struct net80211_device *dev,
00204 int fcid, int nfrags, int size );
00205 static void net80211_rx_frag ( struct net80211_device *dev,
00206 struct io_buffer *iob, int signal );
00207
00208
00209
00210
00211
00212
00213 static int net80211_check_settings_update ( void );
00214
00215
00216
00217
00218
00219
00220
00221 struct settings_applicator net80211_applicator __settings_applicator = {
00222 .apply = net80211_check_settings_update,
00223 };
00224
00225
00226
00227
00228
00229
00230 struct setting net80211_ssid_setting __setting = {
00231 .name = "ssid",
00232 .description = "802.11 SSID (network name)",
00233 .type = &setting_type_string,
00234 };
00235
00236
00237
00238
00239
00240
00241
00242 struct setting net80211_active_setting __setting = {
00243 .name = "active-scan",
00244 .description = "Use an active scan during 802.11 association",
00245 .type = &setting_type_int8,
00246 };
00247
00248
00249
00250
00251
00252
00253
00254 struct setting net80211_key_setting __setting = {
00255 .name = "key",
00256 .description = "Encryption key for protected 802.11 networks",
00257 .type = &setting_type_string,
00258 };
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 static int net80211_netdev_open ( struct net_device *netdev )
00277 {
00278 struct net80211_device *dev = netdev->priv;
00279 int rc = 0;
00280
00281 if ( dev->op == &net80211_null_ops )
00282 return -EFAULT;
00283
00284 if ( dev->op->open )
00285 rc = dev->op->open ( dev );
00286
00287 if ( rc < 0 )
00288 return rc;
00289
00290 if ( ! ( dev->state & NET80211_NO_ASSOC ) )
00291 net80211_autoassociate ( dev );
00292
00293 return 0;
00294 }
00295
00296
00297
00298
00299
00300
00301
00302
00303 static void net80211_netdev_close ( struct net_device *netdev )
00304 {
00305 struct net80211_device *dev = netdev->priv;
00306
00307 if ( dev->state & NET80211_WORKING )
00308 process_del ( &dev->proc_assoc );
00309
00310
00311 if ( dev->state & NET80211_ASSOCIATED )
00312 net80211_send_disassoc ( dev, IEEE80211_REASON_LEAVING, 0 );
00313
00314 if ( dev->handshaker && dev->handshaker->stop &&
00315 dev->handshaker->started )
00316 dev->handshaker->stop ( dev );
00317
00318 free ( dev->crypto );
00319 free ( dev->handshaker );
00320 dev->crypto = NULL;
00321 dev->handshaker = NULL;
00322
00323 netdev_link_down ( netdev );
00324 dev->state = 0;
00325
00326 if ( dev->op->close )
00327 dev->op->close ( dev );
00328 }
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340 static int net80211_netdev_transmit ( struct net_device *netdev,
00341 struct io_buffer *iobuf )
00342 {
00343 struct net80211_device *dev = netdev->priv;
00344 struct ieee80211_frame *hdr = iobuf->data;
00345 int rc = -ENOSYS;
00346
00347 if ( dev->crypto && ! ( hdr->fc & IEEE80211_FC_PROTECTED ) &&
00348 ( ( hdr->fc & IEEE80211_FC_TYPE ) == IEEE80211_TYPE_DATA ) ) {
00349 struct io_buffer *niob = dev->crypto->encrypt ( dev->crypto,
00350 iobuf );
00351 if ( ! niob )
00352 return -ENOMEM;
00353
00354
00355 netdev_tx_complete ( netdev, iobuf );
00356
00357
00358
00359 netdev_tx ( netdev, niob );
00360
00361
00362 return 0;
00363 }
00364
00365 if ( dev->op->transmit )
00366 rc = dev->op->transmit ( dev, iobuf );
00367
00368 return rc;
00369 }
00370
00371
00372
00373
00374
00375
00376 static void net80211_netdev_poll ( struct net_device *netdev )
00377 {
00378 struct net80211_device *dev = netdev->priv;
00379
00380 if ( dev->op->poll )
00381 dev->op->poll ( dev );
00382 }
00383
00384
00385
00386
00387
00388
00389
00390 static void net80211_netdev_irq ( struct net_device *netdev, int enable )
00391 {
00392 struct net80211_device *dev = netdev->priv;
00393
00394 if ( dev->op->irq )
00395 dev->op->irq ( dev, enable );
00396 }
00397
00398
00399 static struct net_device_operations net80211_netdev_ops = {
00400 .open = net80211_netdev_open,
00401 .close = net80211_netdev_close,
00402 .transmit = net80211_netdev_transmit,
00403 .poll = net80211_netdev_poll,
00404 .irq = net80211_netdev_irq,
00405 };
00406
00407
00408
00409
00410
00411 static u8 net80211_ll_broadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422 static inline int net80211_rate_is_erp ( u16 rate )
00423 {
00424 if ( rate == 10 || rate == 20 || rate == 55 || rate == 110 )
00425 return 0;
00426 return 1;
00427 }
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464 u16 net80211_duration ( struct net80211_device *dev, int bytes, u16 rate )
00465 {
00466 struct net80211_channel *chan = &dev->channels[dev->channel];
00467 u32 kbps = rate * 100;
00468
00469 if ( chan->band == NET80211_BAND_5GHZ || net80211_rate_is_erp ( rate ) ) {
00470
00471 int bits_per_symbol = ( kbps * 4 ) / 1000;
00472 int bits = 22 + ( bytes << 3 );
00473 int symbols = ( bits + bits_per_symbol - 1 ) / bits_per_symbol;
00474
00475 return 16 + 20 + ( symbols * 4 );
00476 } else {
00477
00478 int phy_time = 144 + 48;
00479 int bits = bytes << 3;
00480 int data_time = ( bits * 1000 + kbps - 1 ) / kbps;
00481
00482 if ( dev->phy_flags & NET80211_PHY_USE_SHORT_PREAMBLE )
00483 phy_time >>= 1;
00484
00485 return 10 + phy_time + data_time;
00486 }
00487 }
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506 static int net80211_ll_push ( struct net_device *netdev,
00507 struct io_buffer *iobuf, const void *ll_dest,
00508 const void *ll_source, uint16_t net_proto )
00509 {
00510 struct net80211_device *dev = netdev->priv;
00511 struct ieee80211_frame *hdr = iob_push ( iobuf,
00512 IEEE80211_LLC_HEADER_LEN +
00513 IEEE80211_TYP_FRAME_HEADER_LEN );
00514 struct ieee80211_llc_snap_header *lhdr =
00515 ( void * ) hdr + IEEE80211_TYP_FRAME_HEADER_LEN;
00516
00517
00518 if ( ! ( dev->state & NET80211_ASSOCIATED ) ) {
00519 if ( dev->assoc_rc )
00520 return dev->assoc_rc;
00521 return -ENETUNREACH;
00522 }
00523
00524 hdr->fc = IEEE80211_THIS_VERSION | IEEE80211_TYPE_DATA |
00525 IEEE80211_STYPE_DATA | IEEE80211_FC_TODS;
00526
00527
00528
00529 hdr->duration = net80211_duration ( dev, 10, dev->rates[dev->rate] );
00530
00531 memcpy ( hdr->addr1, dev->bssid, ETH_ALEN );
00532 memcpy ( hdr->addr2, ll_source, ETH_ALEN );
00533 memcpy ( hdr->addr3, ll_dest, ETH_ALEN );
00534
00535 hdr->seq = IEEE80211_MAKESEQ ( ++dev->last_tx_seqnr, 0 );
00536
00537 lhdr->dsap = IEEE80211_LLC_DSAP;
00538 lhdr->ssap = IEEE80211_LLC_SSAP;
00539 lhdr->ctrl = IEEE80211_LLC_CTRL;
00540 memset ( lhdr->oui, 0x00, 3 );
00541 lhdr->ethertype = net_proto;
00542
00543 return 0;
00544 }
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559 static int net80211_ll_pull ( struct net_device *netdev __unused,
00560 struct io_buffer *iobuf,
00561 const void **ll_dest, const void **ll_source,
00562 uint16_t * net_proto )
00563 {
00564 struct ieee80211_frame *hdr = iobuf->data;
00565 struct ieee80211_llc_snap_header *lhdr =
00566 ( void * ) hdr + IEEE80211_TYP_FRAME_HEADER_LEN;
00567
00568
00569 if ( iob_len ( iobuf ) < IEEE80211_TYP_FRAME_HEADER_LEN +
00570 IEEE80211_LLC_HEADER_LEN ) {
00571 DBGC ( netdev->priv, "802.11 %p packet too short (%zd bytes)\n",
00572 netdev->priv, iob_len ( iobuf ) );
00573 return -EINVAL_PKT_TOO_SHORT;
00574 }
00575
00576 if ( ( hdr->fc & IEEE80211_FC_VERSION ) != IEEE80211_THIS_VERSION ) {
00577 DBGC ( netdev->priv, "802.11 %p packet invalid version %04x\n",
00578 netdev->priv, hdr->fc & IEEE80211_FC_VERSION );
00579 return -EINVAL_PKT_VERSION;
00580 }
00581
00582 if ( ( hdr->fc & IEEE80211_FC_TYPE ) != IEEE80211_TYPE_DATA ||
00583 ( hdr->fc & IEEE80211_FC_SUBTYPE ) != IEEE80211_STYPE_DATA ) {
00584 DBGC ( netdev->priv, "802.11 %p packet not data/data (fc=%04x)\n",
00585 netdev->priv, hdr->fc );
00586 return -EINVAL_PKT_NOT_DATA;
00587 }
00588
00589 if ( ( hdr->fc & ( IEEE80211_FC_TODS | IEEE80211_FC_FROMDS ) ) !=
00590 IEEE80211_FC_FROMDS ) {
00591 DBGC ( netdev->priv, "802.11 %p packet not from DS (fc=%04x)\n",
00592 netdev->priv, hdr->fc );
00593 return -EINVAL_PKT_NOT_FROMDS;
00594 }
00595
00596 if ( lhdr->dsap != IEEE80211_LLC_DSAP || lhdr->ssap != IEEE80211_LLC_SSAP ||
00597 lhdr->ctrl != IEEE80211_LLC_CTRL || lhdr->oui[0] || lhdr->oui[1] ||
00598 lhdr->oui[2] ) {
00599 DBGC ( netdev->priv, "802.11 %p LLC header is not plain EtherType "
00600 "encapsulator: %02x->%02x [%02x] %02x:%02x:%02x %04x\n",
00601 netdev->priv, lhdr->dsap, lhdr->ssap, lhdr->ctrl,
00602 lhdr->oui[0], lhdr->oui[1], lhdr->oui[2], lhdr->ethertype );
00603 return -EINVAL_PKT_LLC_HEADER;
00604 }
00605
00606 iob_pull ( iobuf, sizeof ( *hdr ) + sizeof ( *lhdr ) );
00607
00608 *ll_dest = hdr->addr1;
00609 *ll_source = hdr->addr3;
00610 *net_proto = lhdr->ethertype;
00611 return 0;
00612 }
00613
00614
00615 static struct ll_protocol net80211_ll_protocol __ll_protocol = {
00616 .name = "802.11",
00617 .push = net80211_ll_push,
00618 .pull = net80211_ll_pull,
00619 .init_addr = eth_init_addr,
00620 .ntoa = eth_ntoa,
00621 .mc_hash = eth_mc_hash,
00622 .eth_addr = eth_eth_addr,
00623 .ll_proto = htons ( ARPHRD_ETHER ),
00624 .hw_addr_len = ETH_ALEN,
00625 .ll_addr_len = ETH_ALEN,
00626 .ll_header_len = IEEE80211_TYP_FRAME_HEADER_LEN +
00627 IEEE80211_LLC_HEADER_LEN,
00628 };
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641 struct net80211_device * net80211_get ( struct net_device *netdev )
00642 {
00643 struct net80211_device *dev;
00644
00645 list_for_each_entry ( dev, &net80211_devices, list ) {
00646 if ( netdev->priv == dev )
00647 return netdev->priv;
00648 }
00649
00650 return NULL;
00651 }
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663 int net80211_keep_mgmt ( struct net80211_device *dev, int enable )
00664 {
00665 int oldenab = dev->keep_mgmt;
00666
00667 dev->keep_mgmt = enable;
00668 return oldenab;
00669 }
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684 struct io_buffer * net80211_mgmt_dequeue ( struct net80211_device *dev,
00685 int *signal )
00686 {
00687 struct io_buffer *iobuf;
00688 struct net80211_rx_info *rxi;
00689
00690 list_for_each_entry ( rxi, &dev->mgmt_info_queue, list ) {
00691 list_del ( &rxi->list );
00692 if ( signal )
00693 *signal = rxi->signal;
00694 free ( rxi );
00695
00696 list_for_each_entry ( iobuf, &dev->mgmt_queue, list ) {
00697 list_del ( &iobuf->list );
00698 return iobuf;
00699 }
00700 assert ( 0 );
00701 }
00702
00703 return NULL;
00704 }
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723 int net80211_tx_mgmt ( struct net80211_device *dev, u16 fc, u8 dest[6],
00724 struct io_buffer *iob )
00725 {
00726 struct ieee80211_frame *hdr = iob_push ( iob,
00727 IEEE80211_TYP_FRAME_HEADER_LEN );
00728
00729 hdr->fc = IEEE80211_THIS_VERSION | IEEE80211_TYPE_MGMT |
00730 ( fc & ~IEEE80211_FC_PROTECTED );
00731 hdr->duration = net80211_duration ( dev, 10, dev->rates[dev->rate] );
00732 hdr->seq = IEEE80211_MAKESEQ ( ++dev->last_tx_seqnr, 0 );
00733
00734 memcpy ( hdr->addr1, dest, ETH_ALEN );
00735 memcpy ( hdr->addr2, dev->netdev->ll_addr, ETH_ALEN );
00736 memcpy ( hdr->addr3, dest, ETH_ALEN );
00737
00738 if ( fc & IEEE80211_FC_PROTECTED ) {
00739 if ( ! dev->crypto )
00740 return -EINVAL_CRYPTO_REQUEST;
00741
00742 struct io_buffer *eiob = dev->crypto->encrypt ( dev->crypto,
00743 iob );
00744 free_iob ( iob );
00745 iob = eiob;
00746 }
00747
00748 return netdev_tx ( dev->netdev, iob );
00749 }
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766 struct net80211_device * net80211_alloc ( size_t priv_size )
00767 {
00768 struct net80211_device *dev;
00769 struct net_device *netdev =
00770 alloc_netdev ( sizeof ( *dev ) + priv_size );
00771
00772 if ( ! netdev )
00773 return NULL;
00774
00775 netdev->ll_protocol = &net80211_ll_protocol;
00776 netdev->ll_broadcast = net80211_ll_broadcast;
00777 netdev->max_pkt_len = IEEE80211_MAX_DATA_LEN;
00778 netdev_init ( netdev, &net80211_netdev_ops );
00779
00780 dev = netdev->priv;
00781 dev->netdev = netdev;
00782 dev->priv = ( u8 * ) dev + sizeof ( *dev );
00783 dev->op = &net80211_null_ops;
00784
00785 process_init_stopped ( &dev->proc_assoc, net80211_step_associate,
00786 &netdev->refcnt );
00787 INIT_LIST_HEAD ( &dev->mgmt_queue );
00788 INIT_LIST_HEAD ( &dev->mgmt_info_queue );
00789
00790 return dev;
00791 }
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803 int net80211_register ( struct net80211_device *dev,
00804 struct net80211_device_operations *ops,
00805 struct net80211_hw_info *hw )
00806 {
00807 dev->op = ops;
00808 dev->hw = malloc ( sizeof ( *hw ) );
00809 if ( ! dev->hw )
00810 return -ENOMEM;
00811
00812 memcpy ( dev->hw, hw, sizeof ( *hw ) );
00813 memcpy ( dev->netdev->hw_addr, hw->hwaddr, ETH_ALEN );
00814
00815
00816 memcpy ( dev->channels, dev->hw->channels,
00817 NET80211_MAX_CHANNELS * sizeof ( dev->channels[0] ) );
00818 dev->channel = 0;
00819
00820 list_add_tail ( &dev->list, &net80211_devices );
00821 return register_netdev ( dev->netdev );
00822 }
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832 void net80211_unregister ( struct net80211_device *dev )
00833 {
00834 unregister_netdev ( dev->netdev );
00835 list_del ( &dev->list );
00836 dev->op = &net80211_null_ops;
00837 }
00838
00839
00840
00841
00842
00843
00844
00845
00846 void net80211_free ( struct net80211_device *dev )
00847 {
00848 free ( dev->hw );
00849 rc80211_free ( dev->rctl );
00850 netdev_nullify ( dev->netdev );
00851 netdev_put ( dev->netdev );
00852 }
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874 static inline void net80211_set_state ( struct net80211_device *dev,
00875 short clear, short set,
00876 u16 status )
00877 {
00878
00879
00880
00881
00882
00883
00884 const int statmsk = NET80211_STATUS_MASK | NET80211_IS_REASON;
00885
00886 if ( clear & NET80211_PROBED )
00887 clear |= NET80211_AUTHENTICATED;
00888
00889 if ( clear & NET80211_AUTHENTICATED )
00890 clear |= NET80211_ASSOCIATED;
00891
00892 if ( clear & NET80211_ASSOCIATED )
00893 clear |= NET80211_CRYPTO_SYNCED;
00894
00895 dev->state = ( dev->state & ~clear ) | set;
00896 dev->state = ( dev->state & ~statmsk ) | ( status & statmsk );
00897
00898 if ( clear & NET80211_ASSOCIATED )
00899 netdev_link_down ( dev->netdev );
00900
00901 if ( ( clear | set ) & NET80211_ASSOCIATED )
00902 dev->op->config ( dev, NET80211_CFG_ASSOC );
00903
00904 if ( status != 0 ) {
00905 if ( status & NET80211_IS_REASON )
00906 dev->assoc_rc = -E80211_REASON ( status );
00907 else
00908 dev->assoc_rc = -E80211_STATUS ( status );
00909 netdev_link_err ( dev->netdev, dev->assoc_rc );
00910 }
00911 }
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925 static void net80211_add_channels ( struct net80211_device *dev, int start,
00926 int len, int txpower )
00927 {
00928 int i, chan = start;
00929
00930 for ( i = dev->nr_channels; len-- && i < NET80211_MAX_CHANNELS; i++ ) {
00931 dev->channels[i].channel_nr = chan;
00932 dev->channels[i].maxpower = txpower;
00933 dev->channels[i].hw_value = 0;
00934
00935 if ( chan >= 1 && chan <= 14 ) {
00936 dev->channels[i].band = NET80211_BAND_2GHZ;
00937 if ( chan == 14 )
00938 dev->channels[i].center_freq = 2484;
00939 else
00940 dev->channels[i].center_freq = 2407 + 5 * chan;
00941 chan++;
00942 } else {
00943 dev->channels[i].band = NET80211_BAND_5GHZ;
00944 dev->channels[i].center_freq = 5000 + 5 * chan;
00945 chan += 4;
00946 }
00947 }
00948
00949 dev->nr_channels = i;
00950 }
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969 static void net80211_filter_hw_channels ( struct net80211_device *dev )
00970 {
00971 int delta = 0, i = 0;
00972 int old_freq = dev->channels[dev->channel].center_freq;
00973 struct net80211_channel *chan, *hwchan;
00974
00975 if ( ! dev->hw->nr_channels )
00976 return;
00977
00978 dev->channel = 0;
00979 for ( chan = dev->channels; chan < dev->channels + dev->nr_channels;
00980 chan++, i++ ) {
00981 int ok = 0;
00982 for ( hwchan = dev->hw->channels;
00983 hwchan < dev->hw->channels + dev->hw->nr_channels;
00984 hwchan++ ) {
00985 if ( hwchan->center_freq == chan->center_freq ) {
00986 ok = 1;
00987 break;
00988 }
00989 }
00990
00991 if ( ! ok )
00992 delta++;
00993 else {
00994 chan->hw_value = hwchan->hw_value;
00995 if ( hwchan->maxpower != 0 &&
00996 chan->maxpower > hwchan->maxpower )
00997 chan->maxpower = hwchan->maxpower;
00998 if ( old_freq == chan->center_freq )
00999 dev->channel = i - delta;
01000 if ( delta )
01001 chan[-delta] = *chan;
01002 }
01003 }
01004
01005 dev->nr_channels -= delta;
01006
01007 if ( dev->channels[dev->channel].center_freq != old_freq )
01008 dev->op->config ( dev, NET80211_CFG_CHANNEL );
01009 }
01010
01011
01012
01013
01014
01015
01016
01017
01018 static int net80211_process_capab ( struct net80211_device *dev,
01019 u16 capab )
01020 {
01021 u16 old_phy = dev->phy_flags;
01022
01023 if ( ( capab & ( IEEE80211_CAPAB_MANAGED | IEEE80211_CAPAB_ADHOC ) ) !=
01024 IEEE80211_CAPAB_MANAGED ) {
01025 DBGC ( dev, "802.11 %p cannot handle IBSS network\n", dev );
01026 return -ENOSYS;
01027 }
01028
01029 dev->phy_flags &= ~( NET80211_PHY_USE_SHORT_PREAMBLE |
01030 NET80211_PHY_USE_SHORT_SLOT );
01031
01032 if ( capab & IEEE80211_CAPAB_SHORT_PMBL )
01033 dev->phy_flags |= NET80211_PHY_USE_SHORT_PREAMBLE;
01034
01035 if ( capab & IEEE80211_CAPAB_SHORT_SLOT )
01036 dev->phy_flags |= NET80211_PHY_USE_SHORT_SLOT;
01037
01038 if ( old_phy != dev->phy_flags )
01039 dev->op->config ( dev, NET80211_CFG_PHY_PARAMS );
01040
01041 return 0;
01042 }
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052 static int net80211_process_ie ( struct net80211_device *dev,
01053 union ieee80211_ie *ie, void *ie_end )
01054 {
01055 u16 old_rate = dev->rates[dev->rate];
01056 u16 old_phy = dev->phy_flags;
01057 int have_rates = 0, i;
01058 int ds_channel = 0;
01059 int changed = 0;
01060 int band = dev->channels[dev->channel].band;
01061
01062 if ( ! ieee80211_ie_bound ( ie, ie_end ) )
01063 return 0;
01064
01065 for ( ; ie; ie = ieee80211_next_ie ( ie, ie_end ) ) {
01066 switch ( ie->id ) {
01067 case IEEE80211_IE_SSID:
01068 if ( ie->len <= 32 ) {
01069 memcpy ( dev->essid, ie->ssid, ie->len );
01070 dev->essid[ie->len] = 0;
01071 }
01072 break;
01073
01074 case IEEE80211_IE_RATES:
01075 case IEEE80211_IE_EXT_RATES:
01076 if ( ! have_rates ) {
01077 dev->nr_rates = 0;
01078 dev->basic_rates = 0;
01079 have_rates = 1;
01080 }
01081 for ( i = 0; i < ie->len &&
01082 dev->nr_rates < NET80211_MAX_RATES; i++ ) {
01083 u8 rid = ie->rates[i];
01084 u16 rate = ( rid & 0x7f ) * 5;
01085
01086 if ( rid & 0x80 )
01087 dev->basic_rates |=
01088 ( 1 << dev->nr_rates );
01089
01090 dev->rates[dev->nr_rates++] = rate;
01091 }
01092
01093 break;
01094
01095 case IEEE80211_IE_DS_PARAM:
01096 if ( dev->channel < dev->nr_channels && ds_channel ==
01097 dev->channels[dev->channel].channel_nr )
01098 break;
01099 ds_channel = ie->ds_param.current_channel;
01100 net80211_change_channel ( dev, ds_channel );
01101 break;
01102
01103 case IEEE80211_IE_COUNTRY:
01104 dev->nr_channels = 0;
01105
01106 DBGC ( dev, "802.11 %p setting country regulations "
01107 "for %c%c\n", dev, ie->country.name[0],
01108 ie->country.name[1] );
01109 for ( i = 0; i < ( ie->len - 3 ) / 3; i++ ) {
01110 union ieee80211_ie_country_triplet *t =
01111 &ie->country.triplet[i];
01112 if ( t->first > 200 ) {
01113 DBGC ( dev, "802.11 %p ignoring regulatory "
01114 "extension information\n", dev );
01115 } else {
01116 net80211_add_channels ( dev,
01117 t->band.first_channel,
01118 t->band.nr_channels,
01119 t->band.max_txpower );
01120 }
01121 }
01122 net80211_filter_hw_channels ( dev );
01123 break;
01124
01125 case IEEE80211_IE_ERP_INFO:
01126 dev->phy_flags &= ~( NET80211_PHY_USE_PROTECTION |
01127 NET80211_PHY_USE_SHORT_PREAMBLE );
01128 if ( ie->erp_info & IEEE80211_ERP_USE_PROTECTION )
01129 dev->phy_flags |= NET80211_PHY_USE_PROTECTION;
01130 if ( ! ( ie->erp_info & IEEE80211_ERP_BARKER_LONG ) )
01131 dev->phy_flags |= NET80211_PHY_USE_SHORT_PREAMBLE;
01132 break;
01133 }
01134 }
01135
01136 if ( have_rates ) {
01137
01138
01139 int delta = 0, j;
01140
01141 dev->rate = 0;
01142 for ( i = 0; i < dev->nr_rates; i++ ) {
01143 int ok = 0;
01144 for ( j = 0; j < dev->hw->nr_rates[band]; j++ ) {
01145 if ( dev->hw->rates[band][j] == dev->rates[i] ){
01146 ok = 1;
01147 break;
01148 }
01149 }
01150
01151 if ( ! ok )
01152 delta++;
01153 else {
01154 dev->rates[i - delta] = dev->rates[i];
01155 if ( old_rate == dev->rates[i] )
01156 dev->rate = i - delta;
01157 }
01158 }
01159
01160 dev->nr_rates -= delta;
01161
01162
01163
01164 for ( i = 1; i < dev->nr_rates; i++ ) {
01165 u16 rate = dev->rates[i];
01166 u32 tmp, br, mask;
01167
01168 for ( j = i - 1; j >= 0 && dev->rates[j] >= rate; j-- )
01169 dev->rates[j + 1] = dev->rates[j];
01170 dev->rates[j + 1] = rate;
01171
01172
01173
01174 mask = ( ( 1 << i ) - 1 ) & ~( ( 1 << ( j + 1 ) ) - 1 );
01175 br = dev->basic_rates;
01176 tmp = br & ( 1 << i );
01177 br = ( br & ~( mask | tmp ) ) | ( ( br & mask ) << 1 );
01178 br |= ( tmp >> ( i - j - 1 ) );
01179 dev->basic_rates = br;
01180 }
01181
01182 net80211_set_rtscts_rate ( dev );
01183
01184 if ( dev->rates[dev->rate] != old_rate )
01185 changed |= NET80211_CFG_RATE;
01186 }
01187
01188 if ( dev->hw->flags & NET80211_HW_NO_SHORT_PREAMBLE )
01189 dev->phy_flags &= ~NET80211_PHY_USE_SHORT_PREAMBLE;
01190 if ( dev->hw->flags & NET80211_HW_NO_SHORT_SLOT )
01191 dev->phy_flags &= ~NET80211_PHY_USE_SHORT_SLOT;
01192
01193 if ( old_phy != dev->phy_flags )
01194 changed |= NET80211_CFG_PHY_PARAMS;
01195
01196 if ( changed )
01197 dev->op->config ( dev, changed );
01198
01199 return 0;
01200 }
01201
01202
01203
01204
01205
01206
01207
01208
01209 static union ieee80211_ie *
01210 net80211_marshal_request_info ( struct net80211_device *dev,
01211 union ieee80211_ie *ie )
01212 {
01213 int i;
01214
01215 ie->id = IEEE80211_IE_SSID;
01216 ie->len = strlen ( dev->essid );
01217 memcpy ( ie->ssid, dev->essid, ie->len );
01218
01219 ie = ieee80211_next_ie ( ie, NULL );
01220
01221 ie->id = IEEE80211_IE_RATES;
01222 ie->len = dev->nr_rates;
01223 if ( ie->len > 8 )
01224 ie->len = 8;
01225
01226 for ( i = 0; i < ie->len; i++ ) {
01227 ie->rates[i] = dev->rates[i] / 5;
01228 if ( dev->basic_rates & ( 1 << i ) )
01229 ie->rates[i] |= 0x80;
01230 }
01231
01232 ie = ieee80211_next_ie ( ie, NULL );
01233
01234 if ( dev->rsn_ie && dev->rsn_ie->id == IEEE80211_IE_RSN ) {
01235 memcpy ( ie, dev->rsn_ie, dev->rsn_ie->len + 2 );
01236 ie = ieee80211_next_ie ( ie, NULL );
01237 }
01238
01239 if ( dev->nr_rates > 8 ) {
01240
01241
01242
01243 ie->id = IEEE80211_IE_EXT_RATES;
01244 ie->len = dev->nr_rates - 8;
01245
01246 for ( ; i < dev->nr_rates; i++ ) {
01247 ie->rates[i - 8] = dev->rates[i] / 5;
01248 if ( dev->basic_rates & ( 1 << i ) )
01249 ie->rates[i - 8] |= 0x80;
01250 }
01251
01252 ie = ieee80211_next_ie ( ie, NULL );
01253 }
01254
01255 if ( dev->rsn_ie && dev->rsn_ie->id == IEEE80211_IE_VENDOR ) {
01256 memcpy ( ie, dev->rsn_ie, dev->rsn_ie->len + 2 );
01257 ie = ieee80211_next_ie ( ie, NULL );
01258 }
01259
01260 return ie;
01261 }
01262
01263
01264
01265
01266
01267 #define NET80211_PROBE_GATHER 1
01268
01269
01270
01271
01272
01273
01274 #define NET80211_PROBE_GATHER_ALL 2
01275
01276
01277 #define NET80211_PROBE_TIMEOUT 6
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298 struct net80211_probe_ctx * net80211_probe_start ( struct net80211_device *dev,
01299 const char *essid,
01300 int active )
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
01336
01337
01338
01339
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 }
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371 int net80211_probe_step ( struct net80211_probe_ctx *ctx )
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
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
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;
01403
01404
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
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
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
01485 wlan = zalloc ( sizeof ( *wlan ) );
01486 strcpy ( wlan->essid, ssid );
01487 list_add_tail ( &wlan->list, ctx->beacons );
01488
01489
01490
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
01497
01498
01499
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 }
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551 struct net80211_wlan *
01552 net80211_probe_finish_best ( struct net80211_probe_ctx *ctx )
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 }
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593 struct list_head *net80211_probe_finish_all ( struct net80211_probe_ctx *ctx )
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 }
01609
01610
01611
01612
01613
01614
01615
01616 void net80211_free_wlan ( struct net80211_wlan *wlan )
01617 {
01618 if ( wlan ) {
01619 free_iob ( wlan->beacon );
01620 free ( wlan );
01621 }
01622 }
01623
01624
01625
01626
01627
01628
01629
01630 void net80211_free_wlanlist ( struct list_head *list )
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 }
01644
01645
01646
01647 #define ASSOC_TIMEOUT TICKS_PER_SEC
01648
01649
01650 #define ASSOC_RETRIES 2
01651
01652
01653
01654
01655
01656
01657 static void net80211_step_associate ( struct process *proc )
01658 {
01659 struct net80211_device *dev =
01660 container_of ( proc, struct net80211_device, proc_assoc );
01661 int rc = 0;
01662 int status = dev->state & NET80211_STATUS_MASK;
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679 if ( dev->state & NET80211_WAITING ) {
01680
01681 if ( ! dev->associating )
01682 return;
01683
01684 if ( currticks() - dev->ctx.assoc->last_packet > ASSOC_TIMEOUT ) {
01685
01686 dev->ctx.assoc->times_tried++;
01687 if ( ++dev->ctx.assoc->times_tried > ASSOC_RETRIES ) {
01688 rc = -ETIMEDOUT;
01689 goto fail;
01690 }
01691 } else {
01692
01693 return;
01694 }
01695 } else {
01696 if ( dev->state & NET80211_PROBED )
01697 dev->ctx.assoc->times_tried = 0;
01698 }
01699
01700 if ( ! ( dev->state & NET80211_PROBED ) ) {
01701
01702
01703 if ( ! dev->ctx.probe ) {
01704
01705 int active = fetch_intz_setting ( NULL,
01706 &net80211_active_setting );
01707 int band = dev->hw->bands;
01708
01709 if ( active )
01710 band &= ~NET80211_BAND_BIT_5GHZ;
01711
01712 rc = net80211_prepare_probe ( dev, band, active );
01713 if ( rc )
01714 goto fail;
01715
01716 dev->ctx.probe = net80211_probe_start ( dev, dev->essid,
01717 active );
01718 if ( ! dev->ctx.probe ) {
01719 dev->assoc_rc = -ENOMEM;
01720 goto fail;
01721 }
01722 }
01723
01724 rc = net80211_probe_step ( dev->ctx.probe );
01725 if ( ! rc ) {
01726 return;
01727 }
01728
01729 dev->associating = net80211_probe_finish_best ( dev->ctx.probe );
01730 dev->ctx.probe = NULL;
01731 if ( ! dev->associating ) {
01732 if ( rc > 0 )
01733 rc = -ETIMEDOUT;
01734 goto fail;
01735 }
01736
01737
01738
01739
01740 if ( ! dev->essid[0] )
01741 dev->state |= NET80211_AUTO_SSID;
01742
01743 DBGC ( dev, "802.11 %p found network %s (%s)\n", dev,
01744 dev->associating->essid,
01745 eth_ntoa ( dev->associating->bssid ) );
01746
01747 dev->ctx.assoc = zalloc ( sizeof ( *dev->ctx.assoc ) );
01748 if ( ! dev->ctx.assoc ) {
01749 rc = -ENOMEM;
01750 goto fail;
01751 }
01752
01753 dev->state |= NET80211_PROBED;
01754 dev->ctx.assoc->method = IEEE80211_AUTH_OPEN_SYSTEM;
01755
01756 return;
01757 }
01758
01759
01760 dev->ctx.assoc->last_packet = currticks();
01761
01762 if ( ! ( dev->state & NET80211_AUTHENTICATED ) ) {
01763
01764
01765 if ( status != IEEE80211_STATUS_SUCCESS ) {
01766
01767 int method = dev->ctx.assoc->method;
01768
01769 if ( method == IEEE80211_AUTH_OPEN_SYSTEM &&
01770 ( status == IEEE80211_STATUS_AUTH_CHALL_INVALID ||
01771 status == IEEE80211_STATUS_AUTH_ALGO_UNSUPP ) ) {
01772
01773 dev->ctx.assoc->method =
01774 IEEE80211_AUTH_SHARED_KEY;
01775 } else {
01776 goto fail;
01777 }
01778 }
01779
01780 DBGC ( dev, "802.11 %p authenticating with method %d\n", dev,
01781 dev->ctx.assoc->method );
01782
01783 rc = net80211_prepare_assoc ( dev, dev->associating );
01784 if ( rc )
01785 goto fail;
01786
01787 rc = net80211_send_auth ( dev, dev->associating,
01788 dev->ctx.assoc->method );
01789 if ( rc )
01790 goto fail;
01791
01792 return;
01793 }
01794
01795 if ( ! ( dev->state & NET80211_ASSOCIATED ) ) {
01796
01797
01798 if ( status != IEEE80211_STATUS_SUCCESS )
01799 goto fail;
01800
01801 DBGC ( dev, "802.11 %p associating\n", dev );
01802
01803 if ( dev->handshaker && dev->handshaker->start &&
01804 ! dev->handshaker->started ) {
01805 rc = dev->handshaker->start ( dev );
01806 if ( rc < 0 )
01807 goto fail;
01808 dev->handshaker->started = 1;
01809 }
01810
01811 rc = net80211_send_assoc ( dev, dev->associating );
01812 if ( rc )
01813 goto fail;
01814
01815 return;
01816 }
01817
01818 if ( ! ( dev->state & NET80211_CRYPTO_SYNCED ) ) {
01819
01820 DBGC ( dev, "802.11 %p security handshaking\n", dev );
01821
01822 if ( ! dev->handshaker || ! dev->handshaker->step ) {
01823 dev->state |= NET80211_CRYPTO_SYNCED;
01824 return;
01825 }
01826
01827 rc = dev->handshaker->step ( dev );
01828
01829 if ( rc < 0 ) {
01830
01831
01832
01833
01834
01835 if ( dev->state & NET80211_ASSOCIATED )
01836 dev->assoc_rc = rc;
01837 rc = 0;
01838 goto fail;
01839 }
01840
01841 if ( rc > 0 ) {
01842 dev->assoc_rc = 0;
01843 dev->state |= NET80211_CRYPTO_SYNCED;
01844 }
01845 return;
01846 }
01847
01848
01849 netdev_link_up ( dev->netdev );
01850 dev->assoc_rc = 0;
01851 dev->state &= ~NET80211_WORKING;
01852
01853 free ( dev->ctx.assoc );
01854 dev->ctx.assoc = NULL;
01855
01856 net80211_free_wlan ( dev->associating );
01857 dev->associating = NULL;
01858
01859 dev->rctl = rc80211_init ( dev );
01860
01861 process_del ( proc );
01862
01863 DBGC ( dev, "802.11 %p associated with %s (%s)\n", dev,
01864 dev->essid, eth_ntoa ( dev->bssid ) );
01865
01866 return;
01867
01868 fail:
01869 dev->state &= ~( NET80211_WORKING | NET80211_WAITING );
01870 if ( rc )
01871 dev->assoc_rc = rc;
01872
01873 netdev_link_err ( dev->netdev, dev->assoc_rc );
01874
01875
01876
01877
01878 if ( dev->state & NET80211_PROBED ) {
01879 free ( dev->ctx.assoc );
01880 dev->ctx.assoc = NULL;
01881 }
01882
01883 net80211_free_wlan ( dev->associating );
01884 dev->associating = NULL;
01885
01886 process_del ( proc );
01887
01888 DBGC ( dev, "802.11 %p association failed (state=%04x): "
01889 "%s\n", dev, dev->state, strerror ( dev->assoc_rc ) );
01890
01891
01892 net80211_autoassociate ( dev );
01893 }
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904 static int net80211_check_settings_update ( void )
01905 {
01906 struct net80211_device *dev;
01907 char ssid[IEEE80211_MAX_SSID_LEN + 1];
01908 int key_reassoc;
01909
01910 list_for_each_entry ( dev, &net80211_devices, list ) {
01911 if ( ! netdev_is_open ( dev->netdev ) )
01912 continue;
01913
01914 key_reassoc = 0;
01915 if ( dev->handshaker && dev->handshaker->change_key &&
01916 dev->handshaker->change_key ( dev ) < 0 )
01917 key_reassoc = 1;
01918
01919 fetch_string_setting ( netdev_settings ( dev->netdev ),
01920 &net80211_ssid_setting, ssid,
01921 IEEE80211_MAX_SSID_LEN + 1 );
01922
01923 if ( key_reassoc ||
01924 ( ! ( ! ssid[0] && ( dev->state & NET80211_AUTO_SSID ) ) &&
01925 strcmp ( ssid, dev->essid ) != 0 ) ) {
01926 DBGC ( dev, "802.11 %p updating association: "
01927 "%s -> %s\n", dev, dev->essid, ssid );
01928 net80211_autoassociate ( dev );
01929 }
01930 }
01931
01932 return 0;
01933 }
01934
01935
01936
01937
01938
01939
01940
01941
01942 void net80211_autoassociate ( struct net80211_device *dev )
01943 {
01944 if ( ! ( dev->state & NET80211_WORKING ) ) {
01945 DBGC2 ( dev, "802.11 %p spawning association process\n", dev );
01946 process_add ( &dev->proc_assoc );
01947 } else {
01948 DBGC2 ( dev, "802.11 %p restarting association\n", dev );
01949 }
01950
01951
01952
01953 if ( dev->associating )
01954 net80211_free_wlan ( dev->associating );
01955
01956 if ( ! ( dev->state & NET80211_PROBED ) )
01957 net80211_free_wlan (
01958 net80211_probe_finish_best ( dev->ctx.probe ) );
01959 else
01960 free ( dev->ctx.assoc );
01961
01962
01963 fetch_string_setting ( netdev_settings ( dev->netdev ),
01964 &net80211_ssid_setting, dev->essid,
01965 IEEE80211_MAX_SSID_LEN + 1 );
01966 dev->ctx.probe = NULL;
01967 dev->associating = NULL;
01968 dev->assoc_rc = 0;
01969 net80211_set_state ( dev, NET80211_PROBED, NET80211_WORKING, 0 );
01970 }
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980 static void net80211_set_rtscts_rate ( struct net80211_device *dev )
01981 {
01982 u16 datarate = dev->rates[dev->rate];
01983 u16 rtsrate = 0;
01984 int rts_idx = -1;
01985 int i;
01986
01987 for ( i = 0; i < dev->nr_rates; i++ ) {
01988 u16 rate = dev->rates[i];
01989
01990 if ( ! ( dev->basic_rates & ( 1 << i ) ) || rate > datarate )
01991 continue;
01992
01993 if ( rate > rtsrate ) {
01994 rtsrate = rate;
01995 rts_idx = i;
01996 }
01997 }
01998
01999
02000
02001 if ( rts_idx < 0 )
02002 rts_idx = 0;
02003
02004 dev->rtscts_rate = rts_idx;
02005 }
02006
02007
02008
02009
02010
02011
02012
02013 void net80211_set_rate_idx ( struct net80211_device *dev, int rate )
02014 {
02015 assert ( netdev_is_open ( dev->netdev ) );
02016
02017 if ( rate >= 0 && rate < dev->nr_rates && rate != dev->rate ) {
02018 DBGC2 ( dev, "802.11 %p changing rate from %d->%d Mbps\n",
02019 dev, dev->rates[dev->rate] / 10,
02020 dev->rates[rate] / 10 );
02021
02022 dev->rate = rate;
02023 net80211_set_rtscts_rate ( dev );
02024 dev->op->config ( dev, NET80211_CFG_RATE );
02025 }
02026 }
02027
02028
02029
02030
02031
02032
02033
02034 int net80211_change_channel ( struct net80211_device *dev, int channel )
02035 {
02036 int i, oldchan = dev->channel;
02037
02038 assert ( netdev_is_open ( dev->netdev ) );
02039
02040 for ( i = 0; i < dev->nr_channels; i++ ) {
02041 if ( dev->channels[i].channel_nr == channel ) {
02042 dev->channel = i;
02043 break;
02044 }
02045 }
02046
02047 if ( i == dev->nr_channels )
02048 return -ENOENT;
02049
02050 if ( i != oldchan )
02051 return dev->op->config ( dev, NET80211_CFG_CHANNEL );
02052
02053 return 0;
02054 }
02055
02056
02057
02058
02059
02060
02061
02062
02063
02064 int net80211_prepare_probe ( struct net80211_device *dev, int band,
02065 int active )
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
02077
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
02099 dev->channel = 0;
02100 dev->op->config ( dev, NET80211_CFG_CHANNEL );
02101
02102
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 }
02110
02111
02112
02113
02114
02115
02116
02117
02118 int net80211_prepare_assoc ( struct net80211_device *dev,
02119 struct net80211_wlan *wlan )
02120 {
02121 struct ieee80211_frame *hdr = wlan->beacon->data;
02122 struct ieee80211_beacon *beacon =
02123 ( struct ieee80211_beacon * ) hdr->data;
02124 struct net80211_handshaker *handshaker;
02125 int rc;
02126
02127 assert ( netdev_is_open ( dev->netdev ) );
02128
02129 net80211_set_state ( dev, NET80211_ASSOCIATED, 0, 0 );
02130 memcpy ( dev->bssid, wlan->bssid, ETH_ALEN );
02131 strcpy ( dev->essid, wlan->essid );
02132
02133 free ( dev->rsn_ie );
02134 dev->rsn_ie = NULL;
02135
02136 dev->last_beacon_timestamp = beacon->timestamp;
02137 dev->tx_beacon_interval = 1024 * beacon->beacon_interval;
02138
02139
02140
02141
02142 net80211_change_channel ( dev, wlan->channel );
02143
02144 rc = net80211_process_capab ( dev, beacon->capability );
02145 if ( rc )
02146 return rc;
02147
02148 rc = net80211_process_ie ( dev, beacon->info_element,
02149 wlan->beacon->tail );
02150 if ( rc )
02151 return rc;
02152
02153
02154 dev->rate = 0;
02155 dev->op->config ( dev, NET80211_CFG_RATE );
02156
02157
02158 if ( dev->handshaker && dev->handshaker->stop &&
02159 dev->handshaker->started )
02160 dev->handshaker->stop ( dev );
02161 free ( dev->handshaker );
02162 dev->handshaker = NULL;
02163 free ( dev->crypto );
02164 free ( dev->gcrypto );
02165 dev->crypto = dev->gcrypto = NULL;
02166
02167
02168 for_each_table_entry ( handshaker, NET80211_HANDSHAKERS ) {
02169 if ( handshaker->protocol == wlan->handshaking ) {
02170 dev->handshaker = zalloc ( sizeof ( *handshaker ) +
02171 handshaker->priv_len );
02172 if ( ! dev->handshaker )
02173 return -ENOMEM;
02174
02175 memcpy ( dev->handshaker, handshaker,
02176 sizeof ( *handshaker ) );
02177 dev->handshaker->priv = ( ( void * ) dev->handshaker +
02178 sizeof ( *handshaker ) );
02179 break;
02180 }
02181 }
02182
02183 if ( ( wlan->handshaking != NET80211_SECPROT_NONE ) &&
02184 ! dev->handshaker ) {
02185 DBGC ( dev, "802.11 %p no support for handshaking scheme %d\n",
02186 dev, wlan->handshaking );
02187 return -( ENOTSUP | ( wlan->handshaking << 8 ) );
02188 }
02189
02190
02191 if ( dev->handshaker ) {
02192 rc = dev->handshaker->init ( dev );
02193 if ( rc < 0 )
02194 return rc;
02195 }
02196
02197 return 0;
02198 }
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211
02212
02213 int net80211_send_auth ( struct net80211_device *dev,
02214 struct net80211_wlan *wlan, int method )
02215 {
02216 struct io_buffer *iob = alloc_iob ( 64 );
02217 struct ieee80211_auth *auth;
02218
02219 net80211_set_state ( dev, 0, NET80211_WAITING, 0 );
02220 iob_reserve ( iob, IEEE80211_TYP_FRAME_HEADER_LEN );
02221 auth = iob_put ( iob, sizeof ( *auth ) );
02222 auth->algorithm = method;
02223 auth->tx_seq = 1;
02224 auth->status = 0;
02225
02226 return net80211_tx_mgmt ( dev, IEEE80211_STYPE_AUTH, wlan->bssid, iob );
02227 }
02228
02229
02230
02231
02232
02233
02234
02235
02236
02237
02238
02239
02240 static void net80211_handle_auth ( struct net80211_device *dev,
02241 struct io_buffer *iob )
02242 {
02243 struct ieee80211_frame *hdr = iob->data;
02244 struct ieee80211_auth *auth =
02245 ( struct ieee80211_auth * ) hdr->data;
02246
02247 if ( auth->tx_seq & 1 ) {
02248 DBGC ( dev, "802.11 %p authentication received improperly "
02249 "directed frame (seq. %d)\n", dev, auth->tx_seq );
02250 net80211_set_state ( dev, NET80211_WAITING, 0,
02251 IEEE80211_STATUS_FAILURE );
02252 return;
02253 }
02254
02255 if ( auth->status != IEEE80211_STATUS_SUCCESS ) {
02256 DBGC ( dev, "802.11 %p authentication failed: status %d\n",
02257 dev, auth->status );
02258 net80211_set_state ( dev, NET80211_WAITING, 0,
02259 auth->status );
02260 return;
02261 }
02262
02263 if ( auth->algorithm == IEEE80211_AUTH_SHARED_KEY && ! dev->crypto ) {
02264 DBGC ( dev, "802.11 %p can't perform shared-key authentication "
02265 "without a cryptosystem\n", dev );
02266 net80211_set_state ( dev, NET80211_WAITING, 0,
02267 IEEE80211_STATUS_FAILURE );
02268 return;
02269 }
02270
02271 if ( auth->algorithm == IEEE80211_AUTH_SHARED_KEY &&
02272 auth->tx_seq == 2 ) {
02273
02274
02275
02276 auth->tx_seq = 3;
02277 auth->status = 0;
02278
02279 memcpy ( hdr->addr2, hdr->addr1, ETH_ALEN );
02280 memcpy ( hdr->addr1, hdr->addr3, ETH_ALEN );
02281
02282 netdev_tx ( dev->netdev,
02283 dev->crypto->encrypt ( dev->crypto, iob ) );
02284 return;
02285 }
02286
02287 net80211_set_state ( dev, NET80211_WAITING, NET80211_AUTHENTICATED,
02288 IEEE80211_STATUS_SUCCESS );
02289
02290 return;
02291 }
02292
02293
02294
02295
02296
02297
02298
02299
02300 int net80211_send_assoc ( struct net80211_device *dev,
02301 struct net80211_wlan *wlan )
02302 {
02303 struct io_buffer *iob = alloc_iob ( 128 );
02304 struct ieee80211_assoc_req *assoc;
02305 union ieee80211_ie *ie;
02306
02307 net80211_set_state ( dev, 0, NET80211_WAITING, 0 );
02308
02309 iob_reserve ( iob, IEEE80211_TYP_FRAME_HEADER_LEN );
02310 assoc = iob->data;
02311
02312 assoc->capability = IEEE80211_CAPAB_MANAGED;
02313 if ( ! ( dev->hw->flags & NET80211_HW_NO_SHORT_PREAMBLE ) )
02314 assoc->capability |= IEEE80211_CAPAB_SHORT_PMBL;
02315 if ( ! ( dev->hw->flags & NET80211_HW_NO_SHORT_SLOT ) )
02316 assoc->capability |= IEEE80211_CAPAB_SHORT_SLOT;
02317 if ( wlan->crypto )
02318 assoc->capability |= IEEE80211_CAPAB_PRIVACY;
02319
02320 assoc->listen_interval = 1;
02321
02322 ie = net80211_marshal_request_info ( dev, assoc->info_element );
02323
02324 DBGP ( "802.11 %p about to send association request:\n", dev );
02325 DBGP_HD ( iob->data, ( void * ) ie - iob->data );
02326
02327 iob_put ( iob, ( void * ) ie - iob->data );
02328
02329 return net80211_tx_mgmt ( dev, IEEE80211_STYPE_ASSOC_REQ,
02330 wlan->bssid, iob );
02331 }
02332
02333
02334
02335
02336
02337
02338
02339 static void net80211_handle_assoc_reply ( struct net80211_device *dev,
02340 struct io_buffer *iob )
02341 {
02342 struct ieee80211_frame *hdr = iob->data;
02343 struct ieee80211_assoc_resp *assoc =
02344 ( struct ieee80211_assoc_resp * ) hdr->data;
02345
02346 net80211_process_capab ( dev, assoc->capability );
02347 net80211_process_ie ( dev, assoc->info_element, iob->tail );
02348
02349 if ( assoc->status != IEEE80211_STATUS_SUCCESS ) {
02350 DBGC ( dev, "802.11 %p association failed: status %d\n",
02351 dev, assoc->status );
02352 net80211_set_state ( dev, NET80211_WAITING, 0,
02353 assoc->status );
02354 return;
02355 }
02356
02357
02358 memcpy ( dev->bssid, hdr->addr3, ETH_ALEN );
02359 dev->aid = assoc->aid;
02360
02361 net80211_set_state ( dev, NET80211_WAITING, NET80211_ASSOCIATED,
02362 IEEE80211_STATUS_SUCCESS );
02363 }
02364
02365
02366
02367
02368
02369
02370
02371
02372
02373
02374 static int net80211_send_disassoc ( struct net80211_device *dev, int reason,
02375 int deauth )
02376 {
02377 struct io_buffer *iob = alloc_iob ( 64 );
02378 struct ieee80211_disassoc *disassoc;
02379
02380 if ( ! ( dev->state & NET80211_ASSOCIATED ) )
02381 return -EINVAL;
02382
02383 net80211_set_state ( dev, NET80211_ASSOCIATED, 0, 0 );
02384 iob_reserve ( iob, IEEE80211_TYP_FRAME_HEADER_LEN );
02385 disassoc = iob_put ( iob, sizeof ( *disassoc ) );
02386 disassoc->reason = reason;
02387
02388 return net80211_tx_mgmt ( dev, deauth ? IEEE80211_STYPE_DEAUTH :
02389 IEEE80211_STYPE_DISASSOC, dev->bssid, iob );
02390 }
02391
02392
02393
02394
02395
02396
02397
02398
02399
02400
02401
02402
02403 void net80211_deauthenticate ( struct net80211_device *dev, int rc )
02404 {
02405 net80211_send_disassoc ( dev, IEEE80211_REASON_UNSPECIFIED, 1 );
02406 dev->assoc_rc = rc;
02407 netdev_link_err ( dev->netdev, rc );
02408
02409 net80211_autoassociate ( dev );
02410 }
02411
02412
02413
02414 #define LQ_SMOOTH 7
02415
02416
02417
02418
02419
02420
02421
02422
02423 static void net80211_update_link_quality ( struct net80211_device *dev,
02424 struct io_buffer *iob )
02425 {
02426 struct ieee80211_frame *hdr = iob->data;
02427 struct ieee80211_beacon *beacon;
02428 u32 dt, rxi;
02429
02430 if ( ! ( dev->state & NET80211_ASSOCIATED ) )
02431 return;
02432
02433 beacon = ( struct ieee80211_beacon * ) hdr->data;
02434 dt = ( u32 ) ( beacon->timestamp - dev->last_beacon_timestamp );
02435 rxi = dev->rx_beacon_interval;
02436
02437 rxi = ( LQ_SMOOTH * rxi ) + ( ( 8 - LQ_SMOOTH ) * dt );
02438 dev->rx_beacon_interval = rxi >> 3;
02439
02440 dev->last_beacon_timestamp = beacon->timestamp;
02441 }
02442
02443
02444
02445
02446
02447
02448
02449
02450
02451 static void net80211_handle_mgmt ( struct net80211_device *dev,
02452 struct io_buffer *iob, int signal )
02453 {
02454 struct ieee80211_frame *hdr = iob->data;
02455 struct ieee80211_disassoc *disassoc;
02456 u16 stype = hdr->fc & IEEE80211_FC_SUBTYPE;
02457 int keep = 0;
02458 int is_deauth = ( stype == IEEE80211_STYPE_DEAUTH );
02459
02460 if ( ( hdr->fc & IEEE80211_FC_TYPE ) != IEEE80211_TYPE_MGMT ) {
02461 free_iob ( iob );
02462 return;
02463 }
02464
02465 switch ( stype ) {
02466
02467 case IEEE80211_STYPE_DEAUTH:
02468 case IEEE80211_STYPE_DISASSOC:
02469 disassoc = ( struct ieee80211_disassoc * ) hdr->data;
02470 net80211_set_state ( dev, is_deauth ? NET80211_AUTHENTICATED :
02471 NET80211_ASSOCIATED, 0,
02472 NET80211_IS_REASON | disassoc->reason );
02473 DBGC ( dev, "802.11 %p %s: reason %d\n",
02474 dev, is_deauth ? "deauthenticated" : "disassociated",
02475 disassoc->reason );
02476
02477
02478 net80211_autoassociate ( dev );
02479
02480 break;
02481
02482
02483 case IEEE80211_STYPE_AUTH:
02484 if ( ! ( dev->state & NET80211_AUTHENTICATED ) )
02485 net80211_handle_auth ( dev, iob );
02486 break;
02487
02488 case IEEE80211_STYPE_ASSOC_RESP:
02489 case IEEE80211_STYPE_REASSOC_RESP:
02490 if ( ! ( dev->state & NET80211_ASSOCIATED ) )
02491 net80211_handle_assoc_reply ( dev, iob );
02492 break;
02493
02494
02495
02496 case IEEE80211_STYPE_BEACON:
02497 net80211_update_link_quality ( dev, iob );
02498
02499 case IEEE80211_STYPE_PROBE_RESP:
02500 case IEEE80211_STYPE_ACTION:
02501 if ( dev->keep_mgmt ) {
02502 struct net80211_rx_info *rxinf;
02503 rxinf = zalloc ( sizeof ( *rxinf ) );
02504 if ( ! rxinf ) {
02505 DBGC ( dev, "802.11 %p out of memory\n", dev );
02506 break;
02507 }
02508 rxinf->signal = signal;
02509 list_add_tail ( &iob->list, &dev->mgmt_queue );
02510 list_add_tail ( &rxinf->list, &dev->mgmt_info_queue );
02511 keep = 1;
02512 }
02513 break;
02514
02515 case IEEE80211_STYPE_PROBE_REQ:
02516
02517 break;
02518
02519 case IEEE80211_STYPE_ASSOC_REQ:
02520 case IEEE80211_STYPE_REASSOC_REQ:
02521
02522 DBGC ( dev, "802.11 %p received strange management request "
02523 "(%04x)\n", dev, stype );
02524 break;
02525
02526 default:
02527 DBGC ( dev, "802.11 %p received unimplemented management "
02528 "packet (%04x)\n", dev, stype );
02529 break;
02530 }
02531
02532 if ( ! keep )
02533 free_iob ( iob );
02534 }
02535
02536
02537
02538
02539
02540
02541
02542
02543
02544
02545
02546 static void net80211_free_frags ( struct net80211_device *dev, int fcid )
02547 {
02548 int j;
02549 struct net80211_frag_cache *frag = &dev->frags[fcid];
02550
02551 for ( j = 0; j < 16; j++ ) {
02552 if ( frag->iob[j] ) {
02553 free_iob ( frag->iob[j] );
02554 frag->iob[j] = NULL;
02555 }
02556 }
02557
02558 frag->seqnr = 0;
02559 frag->start_ticks = 0;
02560 frag->in_use = 0;
02561 }
02562
02563
02564
02565
02566
02567
02568
02569
02570
02571
02572
02573
02574 static struct io_buffer *net80211_accum_frags ( struct net80211_device *dev,
02575 int fcid, int nfrags, int size )
02576 {
02577 struct net80211_frag_cache *frag = &dev->frags[fcid];
02578 int hdrsize = IEEE80211_TYP_FRAME_HEADER_LEN;
02579 int nsize = size - hdrsize * ( nfrags - 1 );
02580 int i;
02581
02582 struct io_buffer *niob = alloc_iob ( nsize );
02583 struct ieee80211_frame *hdr;
02584
02585
02586 memcpy ( iob_put ( niob, hdrsize ), frag->iob[0]->data, hdrsize );
02587
02588
02589 for ( i = 0; i < nfrags; i++ ) {
02590 int len = iob_len ( frag->iob[i] ) - hdrsize;
02591 memcpy ( iob_put ( niob, len ),
02592 frag->iob[i]->data + hdrsize, len );
02593 }
02594
02595
02596 hdr = niob->data;
02597 hdr->fc &= ~IEEE80211_FC_MORE_FRAG;
02598
02599 return niob;
02600 }
02601
02602
02603
02604
02605
02606
02607
02608
02609 static void net80211_rx_frag ( struct net80211_device *dev,
02610 struct io_buffer *iob, int signal )
02611 {
02612 struct ieee80211_frame *hdr = iob->data;
02613 int fragnr = IEEE80211_FRAG ( hdr->seq );
02614
02615 if ( fragnr == 0 && ( hdr->fc & IEEE80211_FC_MORE_FRAG ) ) {
02616
02617 int i, newest = -1;
02618 u32 curr_ticks = currticks(), newest_ticks = 0;
02619 u32 timeout = ticks_per_sec() * NET80211_FRAG_TIMEOUT;
02620
02621 for ( i = 0; i < NET80211_NR_CONCURRENT_FRAGS; i++ ) {
02622 if ( dev->frags[i].in_use == 0 )
02623 break;
02624
02625 if ( dev->frags[i].start_ticks + timeout >=
02626 curr_ticks ) {
02627 net80211_free_frags ( dev, i );
02628 break;
02629 }
02630
02631 if ( dev->frags[i].start_ticks > newest_ticks ) {
02632 newest = i;
02633 newest_ticks = dev->frags[i].start_ticks;
02634 }
02635 }
02636
02637
02638
02639
02640 if ( i == NET80211_NR_CONCURRENT_FRAGS ) {
02641 i = newest;
02642 net80211_free_frags ( dev, i );
02643 }
02644
02645 dev->frags[i].in_use = 1;
02646 dev->frags[i].seqnr = IEEE80211_SEQNR ( hdr->seq );
02647 dev->frags[i].start_ticks = currticks();
02648 dev->frags[i].iob[0] = iob;
02649 return;
02650 } else {
02651 int i;
02652 for ( i = 0; i < NET80211_NR_CONCURRENT_FRAGS; i++ ) {
02653 if ( dev->frags[i].in_use && dev->frags[i].seqnr ==
02654 IEEE80211_SEQNR ( hdr->seq ) )
02655 break;
02656 }
02657 if ( i == NET80211_NR_CONCURRENT_FRAGS ) {
02658
02659 DBGC ( dev, "802.11 %p dropped fragment fc=%04x "
02660 "seq=%04x\n", dev, hdr->fc, hdr->seq );
02661 free_iob ( iob );
02662 return;
02663 }
02664
02665 dev->frags[i].iob[fragnr] = iob;
02666
02667 if ( ! ( hdr->fc & IEEE80211_FC_MORE_FRAG ) ) {
02668 int j, size = 0;
02669 for ( j = 0; j < fragnr; j++ ) {
02670 size += iob_len ( dev->frags[i].iob[j] );
02671 if ( dev->frags[i].iob[j] == NULL )
02672 break;
02673 }
02674 if ( j == fragnr ) {
02675
02676 struct io_buffer *niob =
02677 net80211_accum_frags ( dev, i, fragnr,
02678 size );
02679 net80211_free_frags ( dev, i );
02680 net80211_rx ( dev, niob, signal, 0 );
02681 } else {
02682 DBGC ( dev, "802.11 %p dropping fragmented "
02683 "packet due to out-of-order arrival, "
02684 "fc=%04x seq=%04x\n", dev, hdr->fc,
02685 hdr->seq );
02686 net80211_free_frags ( dev, i );
02687 }
02688 }
02689 }
02690 }
02691
02692
02693
02694
02695
02696
02697
02698
02699
02700
02701
02702 void net80211_rx ( struct net80211_device *dev, struct io_buffer *iob,
02703 int signal, u16 rate )
02704 {
02705 struct ieee80211_frame *hdr = iob->data;
02706 u16 type = hdr->fc & IEEE80211_FC_TYPE;
02707 if ( ( hdr->fc & IEEE80211_FC_VERSION ) != IEEE80211_THIS_VERSION )
02708 goto drop;
02709
02710 if ( type == IEEE80211_TYPE_CTRL )
02711 goto drop;
02712
02713
02714 if ( dev->last_rx_seq == hdr->seq )
02715 goto drop;
02716 dev->last_rx_seq = hdr->seq;
02717
02718 if ( dev->hw->flags & NET80211_HW_RX_HAS_FCS ) {
02719
02720 iob_unput ( iob, 4 );
02721 }
02722
02723
02724 if ( ( hdr->fc & IEEE80211_FC_PROTECTED ) &&
02725 ! memcmp ( hdr->addr2, dev->bssid, ETH_ALEN ) ) {
02726
02727 struct io_buffer *niob;
02728 struct net80211_crypto *crypto = dev->crypto;
02729
02730 if ( ! dev->crypto ) {
02731 DBGC ( dev, "802.11 %p cannot decrypt packet "
02732 "without a cryptosystem\n", dev );
02733 goto drop_crypt;
02734 }
02735
02736 if ( ( hdr->addr1[0] & 1 ) && dev->gcrypto ) {
02737
02738 crypto = dev->gcrypto;
02739 }
02740
02741 niob = crypto->decrypt ( crypto, iob );
02742 if ( ! niob ) {
02743 DBGC ( dev, "802.11 %p decryption error\n", dev );
02744 goto drop_crypt;
02745 }
02746 free_iob ( iob );
02747 iob = niob;
02748 }
02749
02750 dev->last_signal = signal;
02751
02752
02753 if ( IEEE80211_FRAG ( hdr->seq ) != 0
02754 || ( hdr->fc & IEEE80211_FC_MORE_FRAG ) ) {
02755 net80211_rx_frag ( dev, iob, signal );
02756 return;
02757 }
02758
02759
02760 if ( type == IEEE80211_TYPE_MGMT ) {
02761 net80211_handle_mgmt ( dev, iob, signal );
02762 return;
02763 }
02764
02765
02766 if ( ( hdr->fc & IEEE80211_FC_SUBTYPE ) != IEEE80211_STYPE_DATA )
02767 goto drop;
02768
02769
02770 if ( dev->rctl )
02771 rc80211_update_rx ( dev, hdr->fc & IEEE80211_FC_RETRY, rate );
02772
02773
02774 if ( dev->state & NET80211_ASSOCIATED ) {
02775 netdev_rx ( dev->netdev, iob );
02776 return;
02777 }
02778
02779
02780 goto drop;
02781
02782 drop_crypt:
02783 netdev_rx_err ( dev->netdev, NULL, EINVAL_CRYPTO_REQUEST );
02784 drop:
02785 DBGC2 ( dev, "802.11 %p dropped packet fc=%04x seq=%04x\n", dev,
02786 hdr->fc, hdr->seq );
02787 free_iob ( iob );
02788 return;
02789 }
02790
02791
02792
02793
02794
02795
02796
02797
02798
02799
02800 void net80211_rx_err ( struct net80211_device *dev,
02801 struct io_buffer *iob, int rc )
02802 {
02803 netdev_rx_err ( dev->netdev, iob, rc );
02804 }
02805
02806
02807
02808
02809
02810
02811
02812
02813
02814
02815
02816
02817
02818
02819
02820 void net80211_tx_complete ( struct net80211_device *dev,
02821 struct io_buffer *iob, int retries, int rc )
02822 {
02823
02824 if ( dev->rctl )
02825 rc80211_update_tx ( dev, retries, rc );
02826
02827
02828 netdev_tx_complete_err ( dev->netdev, iob, rc );
02829 }