2 * The iPXE 802.11 MAC layer.
4 * Copyright (c) 2009 Joshua Oreman <oremanj@rwcr.net>.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 FILE_LICENCE ( GPL2_OR_LATER
);
29 #include <ipxe/settings.h>
30 #include <ipxe/if_arp.h>
31 #include <ipxe/ethernet.h>
32 #include <ipxe/ieee80211.h>
33 #include <ipxe/netdevice.h>
34 #include <ipxe/net80211.h>
35 #include <ipxe/sec80211.h>
36 #include <ipxe/timer.h>
38 #include <ipxe/errortab.h>
39 #include <ipxe/net80211_err.h>
43 * 802.11 device management
46 /** List of 802.11 devices */
47 static struct list_head net80211_devices
= LIST_HEAD_INIT ( net80211_devices
);
49 /** Set of device operations that does nothing */
50 static struct net80211_device_operations net80211_null_ops
;
52 /** Information associated with a received management packet
54 * This is used to keep beacon signal strengths in a parallel queue to
55 * the beacons themselves.
57 struct net80211_rx_info
{
59 struct list_head list
;
62 /** Context for a probe operation */
63 struct net80211_probe_ctx
{
64 /** 802.11 device to probe on */
65 struct net80211_device
*dev
;
67 /** Value of keep_mgmt before probe was started */
70 /** If scanning actively, pointer to probe packet to send */
71 struct io_buffer
*probe
;
73 /** If non-"", the ESSID to limit ourselves to */
76 /** Time probe was started */
79 /** Time last useful beacon was received */
82 /** Time channel was last changed */
85 /** Time to stay on each channel */
88 /** Channels to hop by when changing channel */
91 /** List of best beacons for each network found so far */
92 struct list_head
*beacons
;
95 /** Context for the association task */
96 struct net80211_assoc_ctx
{
97 /** Next authentication method to try using */
100 /** Time (in ticks) of the last sent association-related packet */
103 /** Number of times we have tried sending it */
108 * Detect secure 802.11 network when security support is not available
110 * @return -ENOTSUP, always.
112 __weak
int sec80211_detect ( struct io_buffer
*iob __unused
,
113 enum net80211_security_proto
*secprot __unused
,
114 enum net80211_crypto_alg
*crypt __unused
) {
119 * @defgroup net80211_netdev Network device interface functions
122 static int net80211_netdev_open ( struct net_device
*netdev
);
123 static void net80211_netdev_close ( struct net_device
*netdev
);
124 static int net80211_netdev_transmit ( struct net_device
*netdev
,
125 struct io_buffer
*iobuf
);
126 static void net80211_netdev_poll ( struct net_device
*netdev
);
127 static void net80211_netdev_irq ( struct net_device
*netdev
, int enable
);
131 * @defgroup net80211_linklayer 802.11 link-layer protocol functions
134 static int net80211_ll_push ( struct net_device
*netdev
,
135 struct io_buffer
*iobuf
, const void *ll_dest
,
136 const void *ll_source
, uint16_t net_proto
);
137 static int net80211_ll_pull ( struct net_device
*netdev
,
138 struct io_buffer
*iobuf
, const void **ll_dest
,
139 const void **ll_source
, uint16_t * net_proto
,
140 unsigned int *flags
);
144 * @defgroup net80211_help 802.11 helper functions
147 static void net80211_add_channels ( struct net80211_device
*dev
, int start
,
148 int len
, int txpower
);
149 static void net80211_filter_hw_channels ( struct net80211_device
*dev
);
150 static void net80211_set_rtscts_rate ( struct net80211_device
*dev
);
151 static int net80211_process_capab ( struct net80211_device
*dev
,
153 static int net80211_process_ie ( struct net80211_device
*dev
,
154 union ieee80211_ie
*ie
, void *ie_end
);
155 static union ieee80211_ie
*
156 net80211_marshal_request_info ( struct net80211_device
*dev
,
157 union ieee80211_ie
*ie
);
161 * @defgroup net80211_assoc_ll 802.11 association handling functions
164 static void net80211_step_associate ( struct net80211_device
*dev
);
165 static void net80211_handle_auth ( struct net80211_device
*dev
,
166 struct io_buffer
*iob
);
167 static void net80211_handle_assoc_reply ( struct net80211_device
*dev
,
168 struct io_buffer
*iob
);
169 static int net80211_send_disassoc ( struct net80211_device
*dev
, int reason
,
171 static void net80211_handle_mgmt ( struct net80211_device
*dev
,
172 struct io_buffer
*iob
, int signal
);
176 * @defgroup net80211_frag 802.11 fragment handling functions
179 static void net80211_free_frags ( struct net80211_device
*dev
, int fcid
);
180 static struct io_buffer
*net80211_accum_frags ( struct net80211_device
*dev
,
181 int fcid
, int nfrags
, int size
);
182 static void net80211_rx_frag ( struct net80211_device
*dev
,
183 struct io_buffer
*iob
, int signal
);
187 * @defgroup net80211_settings 802.11 settings handlers
190 static int net80211_check_settings_update ( void );
192 /** 802.11 settings applicator
194 * When the SSID is changed, this will cause any open devices to
195 * re-associate; when the encryption key is changed, we similarly
196 * update their state.
198 struct settings_applicator net80211_applicator __settings_applicator
= {
199 .apply
= net80211_check_settings_update
,
202 /** The network name to associate with
204 * If this is blank, we scan for all networks and use the one with the
205 * greatest signal strength.
207 const struct setting net80211_ssid_setting
__setting ( SETTING_NETDEV_EXTRA
,
210 .description
= "Wireless SSID",
211 .type
= &setting_type_string
,
214 /** Whether to use active scanning
216 * In order to associate with a hidden SSID, it's necessary to use an
217 * active scan (send probe packets). If this setting is nonzero, an
218 * active scan on the 2.4GHz band will be used to associate.
220 const struct setting net80211_active_setting
__setting ( SETTING_NETDEV_EXTRA
,
222 .name
= "active-scan",
223 .description
= "Actively scan for wireless networks",
224 .type
= &setting_type_int8
,
227 /** The cryptographic key to use
229 * For hex WEP keys, as is common, this must be entered using the
230 * normal iPXE method for entering hex settings; an ASCII string of
231 * hex characters will not behave as expected.
233 const struct setting net80211_key_setting
__setting ( SETTING_NETDEV_EXTRA
,
236 .description
= "Wireless encryption key",
237 .type
= &setting_type_string
,
243 /* ---------- net_device wrapper ---------- */
246 * Open 802.11 device and start association
248 * @v netdev Wrapping network device
249 * @ret rc Return status code
251 * This sets up a default conservative set of channels for probing,
252 * and starts the auto-association task unless the @c
253 * NET80211_NO_ASSOC flag is set in the wrapped 802.11 device's @c
256 static int net80211_netdev_open ( struct net_device
*netdev
)
258 struct net80211_device
*dev
= netdev
->priv
;
261 if ( dev
->op
== &net80211_null_ops
)
265 rc
= dev
->op
->open ( dev
);
270 if ( ! ( dev
->state
& NET80211_NO_ASSOC
) )
271 net80211_autoassociate ( dev
);
277 * Close 802.11 device
279 * @v netdev Wrapping network device.
281 * If the association task is running, this will stop it.
283 static void net80211_netdev_close ( struct net_device
*netdev
)
285 struct net80211_device
*dev
= netdev
->priv
;
287 if ( dev
->state
& NET80211_WORKING
)
288 process_del ( &dev
->proc_assoc
);
290 /* Send disassociation frame to AP, to be polite */
291 if ( dev
->state
& NET80211_ASSOCIATED
)
292 net80211_send_disassoc ( dev
, IEEE80211_REASON_LEAVING
, 0 );
294 if ( dev
->handshaker
&& dev
->handshaker
->stop
&&
295 dev
->handshaker
->started
)
296 dev
->handshaker
->stop ( dev
);
298 free ( dev
->crypto
);
299 free ( dev
->handshaker
);
301 dev
->handshaker
= NULL
;
303 netdev_link_down ( netdev
);
306 if ( dev
->op
->close
)
307 dev
->op
->close ( dev
);
311 * Transmit packet on 802.11 device
313 * @v netdev Wrapping network device
314 * @v iobuf I/O buffer
315 * @ret rc Return status code
317 * If encryption is enabled for the currently associated network, the
318 * packet will be encrypted prior to transmission.
320 static int net80211_netdev_transmit ( struct net_device
*netdev
,
321 struct io_buffer
*iobuf
)
323 struct net80211_device
*dev
= netdev
->priv
;
324 struct ieee80211_frame
*hdr
= iobuf
->data
;
327 if ( dev
->crypto
&& ! ( hdr
->fc
& IEEE80211_FC_PROTECTED
) &&
328 ( ( hdr
->fc
& IEEE80211_FC_TYPE
) == IEEE80211_TYPE_DATA
) ) {
329 struct io_buffer
*niob
= dev
->crypto
->encrypt ( dev
->crypto
,
332 return -ENOMEM
; /* only reason encryption could fail */
334 /* Free the non-encrypted iob */
335 netdev_tx_complete ( netdev
, iobuf
);
337 /* Transmit the encrypted iob; the Protected flag is
338 set, so we won't recurse into here again */
339 netdev_tx ( netdev
, niob
);
341 /* Don't transmit the freed packet */
345 if ( dev
->op
->transmit
)
346 rc
= dev
->op
->transmit ( dev
, iobuf
);
352 * Poll 802.11 device for received packets and completed transmissions
354 * @v netdev Wrapping network device
356 static void net80211_netdev_poll ( struct net_device
*netdev
)
358 struct net80211_device
*dev
= netdev
->priv
;
361 dev
->op
->poll ( dev
);
365 * Enable or disable interrupts for 802.11 device
367 * @v netdev Wrapping network device
368 * @v enable Whether to enable interrupts
370 static void net80211_netdev_irq ( struct net_device
*netdev
, int enable
)
372 struct net80211_device
*dev
= netdev
->priv
;
375 dev
->op
->irq ( dev
, enable
);
378 /** Network device operations for a wrapped 802.11 device */
379 static struct net_device_operations net80211_netdev_ops
= {
380 .open
= net80211_netdev_open
,
381 .close
= net80211_netdev_close
,
382 .transmit
= net80211_netdev_transmit
,
383 .poll
= net80211_netdev_poll
,
384 .irq
= net80211_netdev_irq
,
388 /* ---------- 802.11 link-layer protocol ---------- */
391 * Determine whether a transmission rate uses ERP/OFDM
393 * @v rate Rate in 100 kbps units
394 * @ret is_erp TRUE if the rate is an ERP/OFDM rate
396 * 802.11b supports rates of 1.0, 2.0, 5.5, and 11.0 Mbps; any other
397 * rate than these on the 2.4GHz spectrum is an ERP (802.11g) rate.
399 static inline int net80211_rate_is_erp ( u16 rate
)
401 if ( rate
== 10 || rate
== 20 || rate
== 55 || rate
== 110 )
408 * Calculate one frame's contribution to 802.11 duration field
410 * @v dev 802.11 device
411 * @v bytes Amount of data to calculate duration for
412 * @ret dur Duration field in microseconds
414 * To avoid multiple stations attempting to transmit at once, 802.11
415 * provides that every packet shall include a duration field
416 * specifying a length of time for which the wireless medium will be
417 * reserved after it is transmitted. The duration is measured in
418 * microseconds and is calculated with respect to the current
419 * physical-layer parameters of the 802.11 device.
421 * For an unfragmented data or management frame, or the last fragment
422 * of a fragmented frame, the duration captures only the 10 data bytes
423 * of one ACK; call once with bytes = 10.
425 * For a fragment of a data or management rame that will be followed
426 * by more fragments, the duration captures an ACK, the following
427 * fragment, and its ACK; add the results of three calls, two with
428 * bytes = 10 and one with bytes set to the next fragment's size.
430 * For an RTS control frame, the duration captures the responding CTS,
431 * the frame being sent, and its ACK; add the results of three calls,
432 * two with bytes = 10 and one with bytes set to the next frame's size
433 * (assuming unfragmented).
435 * For a CTS-to-self control frame, the duration captures the frame
436 * being protected and its ACK; add the results of two calls, one with
437 * bytes = 10 and one with bytes set to the next frame's size.
439 * No other frame types are currently supported by iPXE.
441 u16
net80211_duration ( struct net80211_device
*dev
, int bytes
, u16 rate
)
443 struct net80211_channel
*chan
= &dev
->channels
[dev
->channel
];
444 u32 kbps
= rate
* 100;
446 if ( chan
->band
== NET80211_BAND_5GHZ
|| net80211_rate_is_erp ( rate
) ) {
447 /* OFDM encoding (802.11a/g) */
448 int bits_per_symbol
= ( kbps
* 4 ) / 1000; /* 4us/symbol */
449 int bits
= 22 + ( bytes
<< 3 ); /* 22-bit PLCP */
450 int symbols
= ( bits
+ bits_per_symbol
- 1 ) / bits_per_symbol
;
452 return 16 + 20 + ( symbols
* 4 ); /* 16us SIFS, 20us preamble */
454 /* CCK encoding (802.11b) */
455 int phy_time
= 144 + 48; /* preamble + PLCP */
456 int bits
= bytes
<< 3;
457 int data_time
= ( bits
* 1000 + kbps
- 1 ) / kbps
;
459 if ( dev
->phy_flags
& NET80211_PHY_USE_SHORT_PREAMBLE
)
462 return 10 + phy_time
+ data_time
; /* 10us SIFS */
467 * Add 802.11 link-layer header
469 * @v netdev Wrapping network device
470 * @v iobuf I/O buffer
471 * @v ll_dest Link-layer destination address
472 * @v ll_source Link-layer source address
473 * @v net_proto Network-layer protocol, in network byte order
474 * @ret rc Return status code
476 * This adds both the 802.11 frame header and the 802.2 LLC/SNAP
477 * header used on data packets.
479 * We also check here for state of the link that would make it invalid
480 * to send a data packet; every data packet must pass through here,
481 * and no non-data packet (e.g. management frame) should.
483 static int net80211_ll_push ( struct net_device
*netdev
,
484 struct io_buffer
*iobuf
, const void *ll_dest
,
485 const void *ll_source
, uint16_t net_proto
)
487 struct net80211_device
*dev
= netdev
->priv
;
488 struct ieee80211_frame
*hdr
= iob_push ( iobuf
,
489 IEEE80211_LLC_HEADER_LEN
+
490 IEEE80211_TYP_FRAME_HEADER_LEN
);
491 struct ieee80211_llc_snap_header
*lhdr
=
492 ( void * ) hdr
+ IEEE80211_TYP_FRAME_HEADER_LEN
;
494 /* We can't send data packets if we're not associated. */
495 if ( ! ( dev
->state
& NET80211_ASSOCIATED
) ) {
497 return dev
->assoc_rc
;
501 hdr
->fc
= IEEE80211_THIS_VERSION
| IEEE80211_TYPE_DATA
|
502 IEEE80211_STYPE_DATA
| IEEE80211_FC_TODS
;
504 /* We don't send fragmented frames, so duration is the time
505 for an SIFS + 10-byte ACK. */
506 hdr
->duration
= net80211_duration ( dev
, 10, dev
->rates
[dev
->rate
] );
508 memcpy ( hdr
->addr1
, dev
->bssid
, ETH_ALEN
);
509 memcpy ( hdr
->addr2
, ll_source
, ETH_ALEN
);
510 memcpy ( hdr
->addr3
, ll_dest
, ETH_ALEN
);
512 hdr
->seq
= IEEE80211_MAKESEQ ( ++dev
->last_tx_seqnr
, 0 );
514 lhdr
->dsap
= IEEE80211_LLC_DSAP
;
515 lhdr
->ssap
= IEEE80211_LLC_SSAP
;
516 lhdr
->ctrl
= IEEE80211_LLC_CTRL
;
517 memset ( lhdr
->oui
, 0x00, 3 );
518 lhdr
->ethertype
= net_proto
;
524 * Remove 802.11 link-layer header
526 * @v netdev Wrapping network device
527 * @v iobuf I/O buffer
528 * @ret ll_dest Link-layer destination address
529 * @ret ll_source Link-layer source
530 * @ret net_proto Network-layer protocol, in network byte order
531 * @ret flags Packet flags
532 * @ret rc Return status code
534 * This expects and removes both the 802.11 frame header and the 802.2
535 * LLC/SNAP header that are used on data packets.
537 static int net80211_ll_pull ( struct net_device
*netdev __unused
,
538 struct io_buffer
*iobuf
,
539 const void **ll_dest
, const void **ll_source
,
540 uint16_t * net_proto
, unsigned int *flags
)
542 struct ieee80211_frame
*hdr
= iobuf
->data
;
543 struct ieee80211_llc_snap_header
*lhdr
=
544 ( void * ) hdr
+ IEEE80211_TYP_FRAME_HEADER_LEN
;
546 /* Bunch of sanity checks */
547 if ( iob_len ( iobuf
) < IEEE80211_TYP_FRAME_HEADER_LEN
+
548 IEEE80211_LLC_HEADER_LEN
) {
549 DBGC ( netdev
->priv
, "802.11 %p packet too short (%zd bytes)\n",
550 netdev
->priv
, iob_len ( iobuf
) );
551 return -EINVAL_PKT_TOO_SHORT
;
554 if ( ( hdr
->fc
& IEEE80211_FC_VERSION
) != IEEE80211_THIS_VERSION
) {
555 DBGC ( netdev
->priv
, "802.11 %p packet invalid version %04x\n",
556 netdev
->priv
, hdr
->fc
& IEEE80211_FC_VERSION
);
557 return -EINVAL_PKT_VERSION
;
560 if ( ( hdr
->fc
& IEEE80211_FC_TYPE
) != IEEE80211_TYPE_DATA
||
561 ( hdr
->fc
& IEEE80211_FC_SUBTYPE
) != IEEE80211_STYPE_DATA
) {
562 DBGC ( netdev
->priv
, "802.11 %p packet not data/data (fc=%04x)\n",
563 netdev
->priv
, hdr
->fc
);
564 return -EINVAL_PKT_NOT_DATA
;
567 if ( ( hdr
->fc
& ( IEEE80211_FC_TODS
| IEEE80211_FC_FROMDS
) ) !=
568 IEEE80211_FC_FROMDS
) {
569 DBGC ( netdev
->priv
, "802.11 %p packet not from DS (fc=%04x)\n",
570 netdev
->priv
, hdr
->fc
);
571 return -EINVAL_PKT_NOT_FROMDS
;
574 if ( lhdr
->dsap
!= IEEE80211_LLC_DSAP
|| lhdr
->ssap
!= IEEE80211_LLC_SSAP
||
575 lhdr
->ctrl
!= IEEE80211_LLC_CTRL
|| lhdr
->oui
[0] || lhdr
->oui
[1] ||
577 DBGC ( netdev
->priv
, "802.11 %p LLC header is not plain EtherType "
578 "encapsulator: %02x->%02x [%02x] %02x:%02x:%02x %04x\n",
579 netdev
->priv
, lhdr
->dsap
, lhdr
->ssap
, lhdr
->ctrl
,
580 lhdr
->oui
[0], lhdr
->oui
[1], lhdr
->oui
[2], lhdr
->ethertype
);
581 return -EINVAL_PKT_LLC_HEADER
;
584 iob_pull ( iobuf
, sizeof ( *hdr
) + sizeof ( *lhdr
) );
586 *ll_dest
= hdr
->addr1
;
587 *ll_source
= hdr
->addr3
;
588 *net_proto
= lhdr
->ethertype
;
589 *flags
= ( ( is_multicast_ether_addr ( hdr
->addr1
) ?
591 ( is_broadcast_ether_addr ( hdr
->addr1
) ?
592 LL_BROADCAST
: 0 ) );
596 /** 802.11 link-layer protocol */
597 static struct ll_protocol net80211_ll_protocol __ll_protocol
= {
599 .push
= net80211_ll_push
,
600 .pull
= net80211_ll_pull
,
601 .init_addr
= eth_init_addr
,
603 .mc_hash
= eth_mc_hash
,
604 .eth_addr
= eth_eth_addr
,
606 .ll_proto
= htons ( ARPHRD_ETHER
), /* "encapsulated Ethernet" */
607 .hw_addr_len
= ETH_ALEN
,
608 .ll_addr_len
= ETH_ALEN
,
609 .ll_header_len
= IEEE80211_TYP_FRAME_HEADER_LEN
+
610 IEEE80211_LLC_HEADER_LEN
,
614 /* ---------- 802.11 network management API ---------- */
617 * Get 802.11 device from wrapping network device
619 * @v netdev Wrapping network device
620 * @ret dev 802.11 device wrapped by network device, or NULL
622 * Returns NULL if the network device does not wrap an 802.11 device.
624 struct net80211_device
* net80211_get ( struct net_device
*netdev
)
626 struct net80211_device
*dev
;
628 list_for_each_entry ( dev
, &net80211_devices
, list
) {
629 if ( netdev
->priv
== dev
)
637 * Set state of 802.11 device keeping management frames
639 * @v dev 802.11 device
640 * @v enable Whether to keep management frames
641 * @ret oldenab Whether management frames were enabled before this call
643 * If enable is TRUE, beacon, probe, and action frames will be kept
644 * and may be retrieved by calling net80211_mgmt_dequeue().
646 int net80211_keep_mgmt ( struct net80211_device
*dev
, int enable
)
648 int oldenab
= dev
->keep_mgmt
;
650 dev
->keep_mgmt
= enable
;
655 * Get 802.11 management frame
657 * @v dev 802.11 device
658 * @ret signal Signal strength of returned management frame
659 * @ret iob I/O buffer, or NULL if no management frame is queued
661 * Frames will only be returned by this function if
662 * net80211_keep_mgmt() has been previously called with enable set to
665 * The calling function takes ownership of the returned I/O buffer.
667 struct io_buffer
* net80211_mgmt_dequeue ( struct net80211_device
*dev
,
670 struct io_buffer
*iobuf
;
671 struct net80211_rx_info
*rxi
;
673 list_for_each_entry ( rxi
, &dev
->mgmt_info_queue
, list
) {
674 list_del ( &rxi
->list
);
676 *signal
= rxi
->signal
;
679 assert ( ! list_empty ( &dev
->mgmt_queue
) );
680 iobuf
= list_first_entry ( &dev
->mgmt_queue
, struct io_buffer
,
682 list_del ( &iobuf
->list
);
690 * Transmit 802.11 management frame
692 * @v dev 802.11 device
693 * @v fc Frame Control flags for management frame
694 * @v dest Destination access point
696 * @ret rc Return status code
698 * The @a fc argument must contain at least an IEEE 802.11 management
699 * subtype number (e.g. IEEE80211_STYPE_PROBE_REQ). If it contains
700 * IEEE80211_FC_PROTECTED, the frame will be encrypted prior to
703 * It is required that @a iob have at least 24 bytes of headroom
704 * reserved before its data start.
706 int net80211_tx_mgmt ( struct net80211_device
*dev
, u16 fc
, u8 dest
[6],
707 struct io_buffer
*iob
)
709 struct ieee80211_frame
*hdr
= iob_push ( iob
,
710 IEEE80211_TYP_FRAME_HEADER_LEN
);
712 hdr
->fc
= IEEE80211_THIS_VERSION
| IEEE80211_TYPE_MGMT
|
713 ( fc
& ~IEEE80211_FC_PROTECTED
);
714 hdr
->duration
= net80211_duration ( dev
, 10, dev
->rates
[dev
->rate
] );
715 hdr
->seq
= IEEE80211_MAKESEQ ( ++dev
->last_tx_seqnr
, 0 );
717 memcpy ( hdr
->addr1
, dest
, ETH_ALEN
); /* DA = RA */
718 memcpy ( hdr
->addr2
, dev
->netdev
->ll_addr
, ETH_ALEN
); /* SA = TA */
719 memcpy ( hdr
->addr3
, dest
, ETH_ALEN
); /* BSSID */
721 if ( fc
& IEEE80211_FC_PROTECTED
) {
723 return -EINVAL_CRYPTO_REQUEST
;
725 struct io_buffer
*eiob
= dev
->crypto
->encrypt ( dev
->crypto
,
731 return netdev_tx ( dev
->netdev
, iob
);
735 /* ---------- Driver API ---------- */
737 /** 802.11 association process descriptor */
738 static struct process_descriptor net80211_process_desc
=
739 PROC_DESC ( struct net80211_device
, proc_assoc
,
740 net80211_step_associate
);
743 * Allocate 802.11 device
745 * @v priv_size Size of driver-private allocation area
746 * @ret dev Newly allocated 802.11 device
748 * This function allocates a net_device with space in its private area
749 * for both the net80211_device it will wrap and the driver-private
750 * data space requested. It initializes the link-layer-specific parts
751 * of the net_device, and links the net80211_device to the net_device
754 struct net80211_device
* net80211_alloc ( size_t priv_size
)
756 struct net80211_device
*dev
;
757 struct net_device
*netdev
=
758 alloc_netdev ( sizeof ( *dev
) + priv_size
);
763 netdev
->ll_protocol
= &net80211_ll_protocol
;
764 netdev
->ll_broadcast
= eth_broadcast
;
765 netdev
->max_pkt_len
= IEEE80211_MAX_DATA_LEN
;
766 netdev_init ( netdev
, &net80211_netdev_ops
);
769 dev
->netdev
= netdev
;
770 dev
->priv
= ( u8
* ) dev
+ sizeof ( *dev
);
771 dev
->op
= &net80211_null_ops
;
773 process_init_stopped ( &dev
->proc_assoc
, &net80211_process_desc
,
775 INIT_LIST_HEAD ( &dev
->mgmt_queue
);
776 INIT_LIST_HEAD ( &dev
->mgmt_info_queue
);
782 * Register 802.11 device with network stack
784 * @v dev 802.11 device
785 * @v ops 802.11 device operations
786 * @v hw 802.11 hardware information
788 * This also registers the wrapping net_device with the higher network
791 int net80211_register ( struct net80211_device
*dev
,
792 struct net80211_device_operations
*ops
,
793 struct net80211_hw_info
*hw
)
796 dev
->hw
= malloc ( sizeof ( *hw
) );
800 memcpy ( dev
->hw
, hw
, sizeof ( *hw
) );
801 memcpy ( dev
->netdev
->hw_addr
, hw
->hwaddr
, ETH_ALEN
);
803 /* Set some sensible channel defaults for driver's open() function */
804 memcpy ( dev
->channels
, dev
->hw
->channels
,
805 NET80211_MAX_CHANNELS
* sizeof ( dev
->channels
[0] ) );
808 /* Mark device as not supporting interrupts, if applicable */
810 dev
->netdev
->state
|= NETDEV_IRQ_UNSUPPORTED
;
812 list_add_tail ( &dev
->list
, &net80211_devices
);
813 return register_netdev ( dev
->netdev
);
817 * Unregister 802.11 device from network stack
819 * @v dev 802.11 device
821 * After this call, the device operations are cleared so that they
822 * will not be called.
824 void net80211_unregister ( struct net80211_device
*dev
)
826 unregister_netdev ( dev
->netdev
);
827 list_del ( &dev
->list
);
828 dev
->op
= &net80211_null_ops
;
834 * @v dev 802.11 device
836 * The device should be unregistered before this function is called.
838 void net80211_free ( struct net80211_device
*dev
)
841 rc80211_free ( dev
->rctl
);
842 netdev_nullify ( dev
->netdev
);
843 netdev_put ( dev
->netdev
);
847 /* ---------- 802.11 network management workhorse code ---------- */
850 * Set state of 802.11 device
852 * @v dev 802.11 device
853 * @v clear Bitmask of flags to clear
854 * @v set Bitmask of flags to set
855 * @v status Status or reason code for most recent operation
857 * If @a status represents a reason code, it should be OR'ed with
858 * NET80211_IS_REASON.
860 * Clearing authentication also clears association; clearing
861 * association also clears security handshaking state. Clearing
862 * association removes the link-up flag from the wrapping net_device,
863 * but setting it does not automatically set the flag; that is left to
864 * the judgment of higher-level code.
866 static inline void net80211_set_state ( struct net80211_device
*dev
,
867 short clear
, short set
,
870 /* The conditions in this function are deliberately formulated
871 to be decidable at compile-time in most cases. Since clear
872 and set are generally passed as constants, the body of this
873 function can be reduced down to a few statements by the
876 const int statmsk
= NET80211_STATUS_MASK
| NET80211_IS_REASON
;
878 if ( clear
& NET80211_PROBED
)
879 clear
|= NET80211_AUTHENTICATED
;
881 if ( clear
& NET80211_AUTHENTICATED
)
882 clear
|= NET80211_ASSOCIATED
;
884 if ( clear
& NET80211_ASSOCIATED
)
885 clear
|= NET80211_CRYPTO_SYNCED
;
887 dev
->state
= ( dev
->state
& ~clear
) | set
;
888 dev
->state
= ( dev
->state
& ~statmsk
) | ( status
& statmsk
);
890 if ( clear
& NET80211_ASSOCIATED
)
891 netdev_link_down ( dev
->netdev
);
893 if ( ( clear
| set
) & NET80211_ASSOCIATED
)
894 dev
->op
->config ( dev
, NET80211_CFG_ASSOC
);
897 if ( status
& NET80211_IS_REASON
)
898 dev
->assoc_rc
= -E80211_REASON ( status
);
900 dev
->assoc_rc
= -E80211_STATUS ( status
);
901 netdev_link_err ( dev
->netdev
, dev
->assoc_rc
);
906 * Add channels to 802.11 device
908 * @v dev 802.11 device
909 * @v start First channel number to add
910 * @v len Number of channels to add
911 * @v txpower TX power (dBm) to allow on added channels
913 * To replace the current list of channels instead of adding to it,
914 * set the nr_channels field of the 802.11 device to 0 before calling
917 static void net80211_add_channels ( struct net80211_device
*dev
, int start
,
918 int len
, int txpower
)
922 for ( i
= dev
->nr_channels
; len
-- && i
< NET80211_MAX_CHANNELS
; i
++ ) {
923 dev
->channels
[i
].channel_nr
= chan
;
924 dev
->channels
[i
].maxpower
= txpower
;
925 dev
->channels
[i
].hw_value
= 0;
927 if ( chan
>= 1 && chan
<= 14 ) {
928 dev
->channels
[i
].band
= NET80211_BAND_2GHZ
;
930 dev
->channels
[i
].center_freq
= 2484;
932 dev
->channels
[i
].center_freq
= 2407 + 5 * chan
;
935 dev
->channels
[i
].band
= NET80211_BAND_5GHZ
;
936 dev
->channels
[i
].center_freq
= 5000 + 5 * chan
;
941 dev
->nr_channels
= i
;
945 * Filter 802.11 device channels for hardware capabilities
947 * @v dev 802.11 device
949 * Hardware may support fewer channels than regulatory restrictions
950 * allow; this function filters out channels in dev->channels that are
951 * not supported by the hardware list in dev->hwinfo. It also copies
952 * over the net80211_channel::hw_value and limits maximum TX power
955 * Channels are matched based on center frequency, ignoring band and
958 * If the driver specifies no supported channels, the effect will be
959 * as though all were supported.
961 static void net80211_filter_hw_channels ( struct net80211_device
*dev
)
963 int delta
= 0, i
= 0;
964 int old_freq
= dev
->channels
[dev
->channel
].center_freq
;
965 struct net80211_channel
*chan
, *hwchan
;
967 if ( ! dev
->hw
->nr_channels
)
971 for ( chan
= dev
->channels
; chan
< dev
->channels
+ dev
->nr_channels
;
974 for ( hwchan
= dev
->hw
->channels
;
975 hwchan
< dev
->hw
->channels
+ dev
->hw
->nr_channels
;
977 if ( hwchan
->center_freq
== chan
->center_freq
) {
986 chan
->hw_value
= hwchan
->hw_value
;
987 if ( hwchan
->maxpower
!= 0 &&
988 chan
->maxpower
> hwchan
->maxpower
)
989 chan
->maxpower
= hwchan
->maxpower
;
990 if ( old_freq
== chan
->center_freq
)
991 dev
->channel
= i
- delta
;
993 chan
[-delta
] = *chan
;
997 dev
->nr_channels
-= delta
;
999 if ( dev
->channels
[dev
->channel
].center_freq
!= old_freq
)
1000 dev
->op
->config ( dev
, NET80211_CFG_CHANNEL
);
1004 * Update 802.11 device state to reflect received capabilities field
1006 * @v dev 802.11 device
1007 * @v capab Capabilities field in beacon, probe, or association frame
1008 * @ret rc Return status code
1010 static int net80211_process_capab ( struct net80211_device
*dev
,
1013 u16 old_phy
= dev
->phy_flags
;
1015 if ( ( capab
& ( IEEE80211_CAPAB_MANAGED
| IEEE80211_CAPAB_ADHOC
) ) !=
1016 IEEE80211_CAPAB_MANAGED
) {
1017 DBGC ( dev
, "802.11 %p cannot handle IBSS network\n", dev
);
1021 dev
->phy_flags
&= ~( NET80211_PHY_USE_SHORT_PREAMBLE
|
1022 NET80211_PHY_USE_SHORT_SLOT
);
1024 if ( capab
& IEEE80211_CAPAB_SHORT_PMBL
)
1025 dev
->phy_flags
|= NET80211_PHY_USE_SHORT_PREAMBLE
;
1027 if ( capab
& IEEE80211_CAPAB_SHORT_SLOT
)
1028 dev
->phy_flags
|= NET80211_PHY_USE_SHORT_SLOT
;
1030 if ( old_phy
!= dev
->phy_flags
)
1031 dev
->op
->config ( dev
, NET80211_CFG_PHY_PARAMS
);
1037 * Update 802.11 device state to reflect received information elements
1039 * @v dev 802.11 device
1040 * @v ie Pointer to first information element
1041 * @v ie_end Pointer to tail of packet I/O buffer
1042 * @ret rc Return status code
1044 static int net80211_process_ie ( struct net80211_device
*dev
,
1045 union ieee80211_ie
*ie
, void *ie_end
)
1047 u16 old_rate
= dev
->rates
[dev
->rate
];
1048 u16 old_phy
= dev
->phy_flags
;
1049 int have_rates
= 0, i
;
1052 int band
= dev
->channels
[dev
->channel
].band
;
1054 if ( ! ieee80211_ie_bound ( ie
, ie_end
) )
1057 for ( ; ie
; ie
= ieee80211_next_ie ( ie
, ie_end
) ) {
1059 case IEEE80211_IE_SSID
:
1060 if ( ie
->len
<= 32 ) {
1061 memcpy ( dev
->essid
, ie
->ssid
, ie
->len
);
1062 dev
->essid
[ie
->len
] = 0;
1066 case IEEE80211_IE_RATES
:
1067 case IEEE80211_IE_EXT_RATES
:
1068 if ( ! have_rates
) {
1070 dev
->basic_rates
= 0;
1073 for ( i
= 0; i
< ie
->len
&&
1074 dev
->nr_rates
< NET80211_MAX_RATES
; i
++ ) {
1075 u8 rid
= ie
->rates
[i
];
1076 u16 rate
= ( rid
& 0x7f ) * 5;
1080 ( 1 << dev
->nr_rates
);
1082 dev
->rates
[dev
->nr_rates
++] = rate
;
1087 case IEEE80211_IE_DS_PARAM
:
1088 if ( dev
->channel
< dev
->nr_channels
&& ds_channel
==
1089 dev
->channels
[dev
->channel
].channel_nr
)
1091 ds_channel
= ie
->ds_param
.current_channel
;
1092 net80211_change_channel ( dev
, ds_channel
);
1095 case IEEE80211_IE_COUNTRY
:
1096 dev
->nr_channels
= 0;
1098 DBGC ( dev
, "802.11 %p setting country regulations "
1099 "for %c%c\n", dev
, ie
->country
.name
[0],
1100 ie
->country
.name
[1] );
1101 for ( i
= 0; i
< ( ie
->len
- 3 ) / 3; i
++ ) {
1102 union ieee80211_ie_country_triplet
*t
=
1103 &ie
->country
.triplet
[i
];
1104 if ( t
->first
> 200 ) {
1105 DBGC ( dev
, "802.11 %p ignoring regulatory "
1106 "extension information\n", dev
);
1108 net80211_add_channels ( dev
,
1109 t
->band
.first_channel
,
1110 t
->band
.nr_channels
,
1111 t
->band
.max_txpower
);
1114 net80211_filter_hw_channels ( dev
);
1117 case IEEE80211_IE_ERP_INFO
:
1118 dev
->phy_flags
&= ~( NET80211_PHY_USE_PROTECTION
|
1119 NET80211_PHY_USE_SHORT_PREAMBLE
);
1120 if ( ie
->erp_info
& IEEE80211_ERP_USE_PROTECTION
)
1121 dev
->phy_flags
|= NET80211_PHY_USE_PROTECTION
;
1122 if ( ! ( ie
->erp_info
& IEEE80211_ERP_BARKER_LONG
) )
1123 dev
->phy_flags
|= NET80211_PHY_USE_SHORT_PREAMBLE
;
1129 /* Allow only those rates that are also supported by
1134 for ( i
= 0; i
< dev
->nr_rates
; i
++ ) {
1136 for ( j
= 0; j
< dev
->hw
->nr_rates
[band
]; j
++ ) {
1137 if ( dev
->hw
->rates
[band
][j
] == dev
->rates
[i
] ){
1146 dev
->rates
[i
- delta
] = dev
->rates
[i
];
1147 if ( old_rate
== dev
->rates
[i
] )
1148 dev
->rate
= i
- delta
;
1152 dev
->nr_rates
-= delta
;
1154 /* Sort available rates - sorted subclumps tend to already
1155 exist, so insertion sort works well. */
1156 for ( i
= 1; i
< dev
->nr_rates
; i
++ ) {
1157 u16 rate
= dev
->rates
[i
];
1160 for ( j
= i
- 1; j
>= 0 && dev
->rates
[j
] >= rate
; j
-- )
1161 dev
->rates
[j
+ 1] = dev
->rates
[j
];
1162 dev
->rates
[j
+ 1] = rate
;
1164 /* Adjust basic_rates to match by rotating the
1165 bits from bit j+1 to bit i left one position. */
1166 mask
= ( ( 1 << i
) - 1 ) & ~( ( 1 << ( j
+ 1 ) ) - 1 );
1167 br
= dev
->basic_rates
;
1168 tmp
= br
& ( 1 << i
);
1169 br
= ( br
& ~( mask
| tmp
) ) | ( ( br
& mask
) << 1 );
1170 br
|= ( tmp
>> ( i
- j
- 1 ) );
1171 dev
->basic_rates
= br
;
1174 net80211_set_rtscts_rate ( dev
);
1176 if ( dev
->rates
[dev
->rate
] != old_rate
)
1177 changed
|= NET80211_CFG_RATE
;
1180 if ( dev
->hw
->flags
& NET80211_HW_NO_SHORT_PREAMBLE
)
1181 dev
->phy_flags
&= ~NET80211_PHY_USE_SHORT_PREAMBLE
;
1182 if ( dev
->hw
->flags
& NET80211_HW_NO_SHORT_SLOT
)
1183 dev
->phy_flags
&= ~NET80211_PHY_USE_SHORT_SLOT
;
1185 if ( old_phy
!= dev
->phy_flags
)
1186 changed
|= NET80211_CFG_PHY_PARAMS
;
1189 dev
->op
->config ( dev
, changed
);
1195 * Create information elements for outgoing probe or association packet
1197 * @v dev 802.11 device
1198 * @v ie Pointer to start of information element area
1199 * @ret next_ie Pointer to first byte after added information elements
1201 static union ieee80211_ie
*
1202 net80211_marshal_request_info ( struct net80211_device
*dev
,
1203 union ieee80211_ie
*ie
)
1207 ie
->id
= IEEE80211_IE_SSID
;
1208 ie
->len
= strlen ( dev
->essid
);
1209 memcpy ( ie
->ssid
, dev
->essid
, ie
->len
);
1211 ie
= ieee80211_next_ie ( ie
, NULL
);
1213 ie
->id
= IEEE80211_IE_RATES
;
1214 ie
->len
= dev
->nr_rates
;
1218 for ( i
= 0; i
< ie
->len
; i
++ ) {
1219 ie
->rates
[i
] = dev
->rates
[i
] / 5;
1220 if ( dev
->basic_rates
& ( 1 << i
) )
1221 ie
->rates
[i
] |= 0x80;
1224 ie
= ieee80211_next_ie ( ie
, NULL
);
1226 if ( dev
->rsn_ie
&& dev
->rsn_ie
->id
== IEEE80211_IE_RSN
) {
1227 memcpy ( ie
, dev
->rsn_ie
, dev
->rsn_ie
->len
+ 2 );
1228 ie
= ieee80211_next_ie ( ie
, NULL
);
1231 if ( dev
->nr_rates
> 8 ) {
1232 /* 802.11 requires we use an Extended Basic Rates IE
1233 for the rates beyond the eighth. */
1235 ie
->id
= IEEE80211_IE_EXT_RATES
;
1236 ie
->len
= dev
->nr_rates
- 8;
1238 for ( ; i
< dev
->nr_rates
; i
++ ) {
1239 ie
->rates
[i
- 8] = dev
->rates
[i
] / 5;
1240 if ( dev
->basic_rates
& ( 1 << i
) )
1241 ie
->rates
[i
- 8] |= 0x80;
1244 ie
= ieee80211_next_ie ( ie
, NULL
);
1247 if ( dev
->rsn_ie
&& dev
->rsn_ie
->id
== IEEE80211_IE_VENDOR
) {
1248 memcpy ( ie
, dev
->rsn_ie
, dev
->rsn_ie
->len
+ 2 );
1249 ie
= ieee80211_next_ie ( ie
, NULL
);
1255 /** Seconds to wait after finding a network, to possibly find better APs for it
1257 * This is used when a specific SSID to scan for is specified.
1259 #define NET80211_PROBE_GATHER 1
1261 /** Seconds to wait after finding a network, to possibly find other networks
1263 * This is used when an empty SSID is specified, to scan for all
1266 #define NET80211_PROBE_GATHER_ALL 2
1268 /** Seconds to allow a probe to take if no network has been found */
1269 #define NET80211_PROBE_TIMEOUT 6
1272 * Begin probe of 802.11 networks
1274 * @v dev 802.11 device
1275 * @v essid SSID to probe for, or "" to accept any (may not be NULL)
1276 * @v active Whether to use active scanning
1277 * @ret ctx Probe context
1279 * Active scanning may only be used on channels 1-11 in the 2.4GHz
1280 * band, due to iPXE's lack of a complete regulatory database. If
1281 * active scanning is used, probe packets will be sent on each
1282 * channel; this can allow association with hidden-SSID networks if
1283 * the SSID is properly specified.
1285 * A @c NULL return indicates an out-of-memory condition.
1287 * The returned context must be periodically passed to
1288 * net80211_probe_step() until that function returns zero.
1290 struct net80211_probe_ctx
* net80211_probe_start ( struct net80211_device
*dev
,
1294 struct net80211_probe_ctx
*ctx
= zalloc ( sizeof ( *ctx
) );
1299 assert ( netdev_is_open ( dev
->netdev
) );
1302 ctx
->old_keep_mgmt
= net80211_keep_mgmt ( dev
, 1 );
1304 if ( dev
->essid
!= ctx
->essid
)
1305 strcpy ( dev
->essid
, ctx
->essid
);
1308 struct ieee80211_probe_req
*probe_req
;
1309 union ieee80211_ie
*ie
;
1311 ctx
->probe
= alloc_iob ( 128 );
1312 iob_reserve ( ctx
->probe
, IEEE80211_TYP_FRAME_HEADER_LEN
);
1313 probe_req
= ctx
->probe
->data
;
1315 ie
= net80211_marshal_request_info ( dev
,
1316 probe_req
->info_element
);
1318 iob_put ( ctx
->probe
, ( void * ) ie
- ctx
->probe
->data
);
1321 ctx
->ticks_start
= currticks();
1322 ctx
->ticks_beacon
= 0;
1323 ctx
->ticks_channel
= currticks();
1324 ctx
->hop_time
= ticks_per_sec() / ( active ?
2 : 6 );
1327 * Channels on 2.4GHz overlap, and the most commonly used
1328 * are 1, 6, and 11. We'll get a result faster if we check
1329 * every 5 channels, but in order to hit all of them the
1330 * number of channels must be relatively prime to 5. If it's
1331 * not, tweak the hop.
1334 while ( dev
->nr_channels
% ctx
->hop_step
== 0 && ctx
->hop_step
> 1 )
1337 ctx
->beacons
= malloc ( sizeof ( *ctx
->beacons
) );
1338 INIT_LIST_HEAD ( ctx
->beacons
);
1341 dev
->op
->config ( dev
, NET80211_CFG_CHANNEL
);
1347 * Continue probe of 802.11 networks
1349 * @v ctx Probe context returned by net80211_probe_start()
1350 * @ret rc Probe status
1352 * The return code will be 0 if the probe is still going on (and this
1353 * function should be called again), a positive number if the probe
1354 * completed successfully, or a negative error code if the probe
1355 * failed for that reason.
1357 * Whether the probe succeeded or failed, you must call
1358 * net80211_probe_finish_all() or net80211_probe_finish_best()
1359 * (depending on whether you want information on all networks or just
1360 * the best-signal one) in order to release the probe context. A
1361 * failed probe may still have acquired some valid data.
1363 int net80211_probe_step ( struct net80211_probe_ctx
*ctx
)
1365 struct net80211_device
*dev
= ctx
->dev
;
1366 u32 start_timeout
= NET80211_PROBE_TIMEOUT
* ticks_per_sec();
1367 u32 gather_timeout
= ticks_per_sec();
1368 u32 now
= currticks();
1369 struct io_buffer
*iob
;
1372 char ssid
[IEEE80211_MAX_SSID_LEN
+ 1];
1374 gather_timeout
*= ( ctx
->essid
[0] ? NET80211_PROBE_GATHER
:
1375 NET80211_PROBE_GATHER_ALL
);
1377 /* Time out if necessary */
1378 if ( now
>= ctx
->ticks_start
+ start_timeout
)
1379 return list_empty ( ctx
->beacons
) ?
-ETIMEDOUT
: +1;
1381 if ( ctx
->ticks_beacon
> 0 && now
>= ctx
->ticks_start
+ gather_timeout
)
1384 /* Change channels if necessary */
1385 if ( now
>= ctx
->ticks_channel
+ ctx
->hop_time
) {
1386 dev
->channel
= ( dev
->channel
+ ctx
->hop_step
)
1388 dev
->op
->config ( dev
, NET80211_CFG_CHANNEL
);
1389 udelay ( dev
->hw
->channel_change_time
);
1391 ctx
->ticks_channel
= now
;
1394 struct io_buffer
*siob
= ctx
->probe
; /* to send */
1396 /* make a copy for future use */
1397 iob
= alloc_iob ( siob
->tail
- siob
->head
);
1398 iob_reserve ( iob
, iob_headroom ( siob
) );
1399 memcpy ( iob_put ( iob
, iob_len ( siob
) ),
1400 siob
->data
, iob_len ( siob
) );
1403 rc
= net80211_tx_mgmt ( dev
, IEEE80211_STYPE_PROBE_REQ
,
1405 iob_disown ( siob
) );
1407 DBGC ( dev
, "802.11 %p send probe failed: "
1408 "%s\n", dev
, strerror ( rc
) );
1414 /* Check for new management packets */
1415 while ( ( iob
= net80211_mgmt_dequeue ( dev
, &signal
) ) != NULL
) {
1416 struct ieee80211_frame
*hdr
;
1417 struct ieee80211_beacon
*beacon
;
1418 union ieee80211_ie
*ie
;
1419 struct net80211_wlan
*wlan
;
1423 type
= hdr
->fc
& IEEE80211_FC_SUBTYPE
;
1424 beacon
= ( struct ieee80211_beacon
* ) hdr
->data
;
1426 if ( type
!= IEEE80211_STYPE_BEACON
&&
1427 type
!= IEEE80211_STYPE_PROBE_RESP
) {
1428 DBGC2 ( dev
, "802.11 %p probe: non-beacon\n", dev
);
1432 if ( ( void * ) beacon
->info_element
>= iob
->tail
) {
1433 DBGC ( dev
, "802.11 %p probe: beacon with no IEs\n",
1438 ie
= beacon
->info_element
;
1440 if ( ! ieee80211_ie_bound ( ie
, iob
->tail
) )
1443 while ( ie
&& ie
->id
!= IEEE80211_IE_SSID
)
1444 ie
= ieee80211_next_ie ( ie
, iob
->tail
);
1447 DBGC ( dev
, "802.11 %p probe: beacon with no SSID\n",
1452 memcpy ( ssid
, ie
->ssid
, ie
->len
);
1455 if ( ctx
->essid
[0] && strcmp ( ctx
->essid
, ssid
) != 0 ) {
1456 DBGC2 ( dev
, "802.11 %p probe: beacon with wrong SSID "
1457 "(%s)\n", dev
, ssid
);
1461 /* See if we've got an entry for this network */
1462 list_for_each_entry ( wlan
, ctx
->beacons
, list
) {
1463 if ( strcmp ( wlan
->essid
, ssid
) != 0 )
1466 if ( signal
< wlan
->signal
) {
1467 DBGC2 ( dev
, "802.11 %p probe: beacon for %s "
1468 "(%s) with weaker signal %d\n", dev
,
1469 ssid
, eth_ntoa ( hdr
->addr3
), signal
);
1476 /* No entry yet - make one */
1477 wlan
= zalloc ( sizeof ( *wlan
) );
1478 strcpy ( wlan
->essid
, ssid
);
1479 list_add_tail ( &wlan
->list
, ctx
->beacons
);
1481 /* Whether we're using an old entry or a new one, fill
1482 it with new data. */
1484 memcpy ( wlan
->bssid
, hdr
->addr3
, ETH_ALEN
);
1485 wlan
->signal
= signal
;
1486 wlan
->channel
= dev
->channels
[dev
->channel
].channel_nr
;
1488 /* Copy this I/O buffer into a new wlan->beacon; the
1489 * iob we've got probably came from the device driver
1490 * and may have the full 2.4k allocation, which we
1491 * don't want to keep around wasting memory.
1493 free_iob ( wlan
->beacon
);
1494 wlan
->beacon
= alloc_iob ( iob_len ( iob
) );
1495 memcpy ( iob_put ( wlan
->beacon
, iob_len ( iob
) ),
1496 iob
->data
, iob_len ( iob
) );
1498 if ( ( rc
= sec80211_detect ( wlan
->beacon
, &wlan
->handshaking
,
1499 &wlan
->crypto
) ) == -ENOTSUP
) {
1500 struct ieee80211_beacon
*beacon
=
1501 ( struct ieee80211_beacon
* ) hdr
->data
;
1503 if ( beacon
->capability
& IEEE80211_CAPAB_PRIVACY
) {
1504 DBG ( "802.11 %p probe: secured network %s but "
1505 "encryption support not compiled in\n",
1507 wlan
->handshaking
= NET80211_SECPROT_UNKNOWN
;
1508 wlan
->crypto
= NET80211_CRYPT_UNKNOWN
;
1510 wlan
->handshaking
= NET80211_SECPROT_NONE
;
1511 wlan
->crypto
= NET80211_CRYPT_NONE
;
1513 } else if ( rc
!= 0 ) {
1514 DBGC ( dev
, "802.11 %p probe warning: network "
1515 "%s with unidentifiable security "
1516 "settings: %s\n", dev
, wlan
->essid
,
1520 ctx
->ticks_beacon
= now
;
1522 DBGC2 ( dev
, "802.11 %p probe: good beacon for %s (%s)\n",
1523 dev
, wlan
->essid
, eth_ntoa ( wlan
->bssid
) );
1534 * Finish probe of 802.11 networks, returning best-signal network found
1536 * @v ctx Probe context
1537 * @ret wlan Best-signal network found, or @c NULL if none were found
1539 * If net80211_probe_start() was called with a particular SSID
1540 * parameter as filter, only a network with that SSID (matching
1541 * case-sensitively) can be returned from this function.
1543 struct net80211_wlan
*
1544 net80211_probe_finish_best ( struct net80211_probe_ctx
*ctx
)
1546 struct net80211_wlan
*best
= NULL
, *wlan
;
1551 list_for_each_entry ( wlan
, ctx
->beacons
, list
) {
1552 if ( ! best
|| best
->signal
< wlan
->signal
)
1557 list_del ( &best
->list
);
1559 DBGC ( ctx
->dev
, "802.11 %p probe: found nothing for '%s'\n",
1560 ctx
->dev
, ctx
->essid
);
1562 net80211_free_wlanlist ( ctx
->beacons
);
1564 net80211_keep_mgmt ( ctx
->dev
, ctx
->old_keep_mgmt
);
1567 free_iob ( ctx
->probe
);
1576 * Finish probe of 802.11 networks, returning all networks found
1578 * @v ctx Probe context
1579 * @ret list List of net80211_wlan detailing networks found
1581 * If net80211_probe_start() was called with a particular SSID
1582 * parameter as filter, this will always return either an empty or a
1585 struct list_head
*net80211_probe_finish_all ( struct net80211_probe_ctx
*ctx
)
1587 struct list_head
*beacons
= ctx
->beacons
;
1592 net80211_keep_mgmt ( ctx
->dev
, ctx
->old_keep_mgmt
);
1595 free_iob ( ctx
->probe
);
1604 * Free WLAN structure
1606 * @v wlan WLAN structure to free
1608 void net80211_free_wlan ( struct net80211_wlan
*wlan
)
1611 free_iob ( wlan
->beacon
);
1618 * Free list of WLAN structures
1620 * @v list List of WLAN structures to free
1622 void net80211_free_wlanlist ( struct list_head
*list
)
1624 struct net80211_wlan
*wlan
, *tmp
;
1629 list_for_each_entry_safe ( wlan
, tmp
, list
, list
) {
1630 list_del ( &wlan
->list
);
1631 net80211_free_wlan ( wlan
);
1638 /** Number of ticks to wait for replies to association management frames */
1639 #define ASSOC_TIMEOUT TICKS_PER_SEC
1641 /** Number of times to try sending a particular association management frame */
1642 #define ASSOC_RETRIES 2
1645 * Step 802.11 association process
1647 * @v dev 802.11 device
1649 static void net80211_step_associate ( struct net80211_device
*dev
)
1652 int status
= dev
->state
& NET80211_STATUS_MASK
;
1655 * We use a sort of state machine implemented using bits in
1656 * the dev->state variable. At each call, we take the
1657 * logically first step that has not yet succeeded; either it
1658 * has not been tried yet, it's being retried, or it failed.
1659 * If it failed, we return an error indication; otherwise we
1660 * perform the step. If it succeeds, RX handling code will set
1661 * the appropriate status bit for us.
1663 * Probe works a bit differently, since we have to step it
1664 * on every call instead of waiting for a packet to arrive
1665 * that will set the completion bit for us.
1668 /* If we're waiting for a reply, check for timeout condition */
1669 if ( dev
->state
& NET80211_WAITING
) {
1671 if ( ! dev
->associating
)
1674 if ( currticks() - dev
->ctx
.assoc
->last_packet
> ASSOC_TIMEOUT
) {
1675 /* Timed out - fail if too many retries, or retry */
1676 dev
->ctx
.assoc
->times_tried
++;
1677 if ( ++dev
->ctx
.assoc
->times_tried
> ASSOC_RETRIES
) {
1682 /* Didn't time out - let it keep going */
1686 if ( dev
->state
& NET80211_PROBED
)
1687 dev
->ctx
.assoc
->times_tried
= 0;
1690 if ( ! ( dev
->state
& NET80211_PROBED
) ) {
1693 if ( ! dev
->ctx
.probe
) {
1695 int active
= fetch_intz_setting ( NULL
,
1696 &net80211_active_setting
);
1697 int band
= dev
->hw
->bands
;
1700 band
&= ~NET80211_BAND_BIT_5GHZ
;
1702 rc
= net80211_prepare_probe ( dev
, band
, active
);
1706 dev
->ctx
.probe
= net80211_probe_start ( dev
, dev
->essid
,
1708 if ( ! dev
->ctx
.probe
) {
1709 dev
->assoc_rc
= -ENOMEM
;
1714 rc
= net80211_probe_step ( dev
->ctx
.probe
);
1716 return; /* still going */
1719 dev
->associating
= net80211_probe_finish_best ( dev
->ctx
.probe
);
1720 dev
->ctx
.probe
= NULL
;
1721 if ( ! dev
->associating
) {
1722 if ( rc
> 0 ) /* "successful" probe found nothing */
1727 /* If we probed using a broadcast SSID, record that
1728 fact for the settings applicator before we clobber
1729 it with the specific SSID we've chosen. */
1730 if ( ! dev
->essid
[0] )
1731 dev
->state
|= NET80211_AUTO_SSID
;
1733 DBGC ( dev
, "802.11 %p found network %s (%s)\n", dev
,
1734 dev
->associating
->essid
,
1735 eth_ntoa ( dev
->associating
->bssid
) );
1737 dev
->ctx
.assoc
= zalloc ( sizeof ( *dev
->ctx
.assoc
) );
1738 if ( ! dev
->ctx
.assoc
) {
1743 dev
->state
|= NET80211_PROBED
;
1744 dev
->ctx
.assoc
->method
= IEEE80211_AUTH_OPEN_SYSTEM
;
1749 /* Record time of sending the packet we're about to send, for timeout */
1750 dev
->ctx
.assoc
->last_packet
= currticks();
1752 if ( ! ( dev
->state
& NET80211_AUTHENTICATED
) ) {
1753 /* state: prepare and authenticate */
1755 if ( status
!= IEEE80211_STATUS_SUCCESS
) {
1756 /* we tried authenticating already, but failed */
1757 int method
= dev
->ctx
.assoc
->method
;
1759 if ( method
== IEEE80211_AUTH_OPEN_SYSTEM
&&
1760 ( status
== IEEE80211_STATUS_AUTH_CHALL_INVALID
||
1761 status
== IEEE80211_STATUS_AUTH_ALGO_UNSUPP
) ) {
1762 /* Maybe this network uses Shared Key? */
1763 dev
->ctx
.assoc
->method
=
1764 IEEE80211_AUTH_SHARED_KEY
;
1770 DBGC ( dev
, "802.11 %p authenticating with method %d\n", dev
,
1771 dev
->ctx
.assoc
->method
);
1773 rc
= net80211_prepare_assoc ( dev
, dev
->associating
);
1777 rc
= net80211_send_auth ( dev
, dev
->associating
,
1778 dev
->ctx
.assoc
->method
);
1785 if ( ! ( dev
->state
& NET80211_ASSOCIATED
) ) {
1786 /* state: associate */
1788 if ( status
!= IEEE80211_STATUS_SUCCESS
)
1791 DBGC ( dev
, "802.11 %p associating\n", dev
);
1793 if ( dev
->handshaker
&& dev
->handshaker
->start
&&
1794 ! dev
->handshaker
->started
) {
1795 rc
= dev
->handshaker
->start ( dev
);
1798 dev
->handshaker
->started
= 1;
1801 rc
= net80211_send_assoc ( dev
, dev
->associating
);
1808 if ( ! ( dev
->state
& NET80211_CRYPTO_SYNCED
) ) {
1809 /* state: crypto sync */
1810 DBGC ( dev
, "802.11 %p security handshaking\n", dev
);
1812 if ( ! dev
->handshaker
|| ! dev
->handshaker
->step
) {
1813 dev
->state
|= NET80211_CRYPTO_SYNCED
;
1817 rc
= dev
->handshaker
->step ( dev
);
1820 /* Only record the returned error if we're
1821 still marked as associated, because an
1822 asynchronous error will have already been
1823 reported to net80211_deauthenticate() and
1824 assoc_rc thereby set. */
1825 if ( dev
->state
& NET80211_ASSOCIATED
)
1833 dev
->state
|= NET80211_CRYPTO_SYNCED
;
1839 netdev_link_up ( dev
->netdev
);
1841 dev
->state
&= ~NET80211_WORKING
;
1843 free ( dev
->ctx
.assoc
);
1844 dev
->ctx
.assoc
= NULL
;
1846 net80211_free_wlan ( dev
->associating
);
1847 dev
->associating
= NULL
;
1849 dev
->rctl
= rc80211_init ( dev
);
1851 process_del ( &dev
->proc_assoc
);
1853 DBGC ( dev
, "802.11 %p associated with %s (%s)\n", dev
,
1854 dev
->essid
, eth_ntoa ( dev
->bssid
) );
1859 dev
->state
&= ~( NET80211_WORKING
| NET80211_WAITING
);
1863 netdev_link_err ( dev
->netdev
, dev
->assoc_rc
);
1865 /* We never reach here from the middle of a probe, so we don't
1866 need to worry about freeing dev->ctx.probe. */
1868 if ( dev
->state
& NET80211_PROBED
) {
1869 free ( dev
->ctx
.assoc
);
1870 dev
->ctx
.assoc
= NULL
;
1873 net80211_free_wlan ( dev
->associating
);
1874 dev
->associating
= NULL
;
1876 process_del ( &dev
->proc_assoc
);
1878 DBGC ( dev
, "802.11 %p association failed (state=%04x): "
1879 "%s\n", dev
, dev
->state
, strerror ( dev
->assoc_rc
) );
1882 net80211_autoassociate ( dev
);
1886 * Check for 802.11 SSID or key updates
1888 * This acts as a settings applicator; if the user changes netX/ssid,
1889 * and netX is currently open, the association task will be invoked
1890 * again. If the user changes the encryption key, the current security
1891 * handshaker will be asked to update its state to match; if that is
1892 * impossible without reassociation, we reassociate.
1894 static int net80211_check_settings_update ( void )
1896 struct net80211_device
*dev
;
1897 char ssid
[IEEE80211_MAX_SSID_LEN
+ 1];
1900 list_for_each_entry ( dev
, &net80211_devices
, list
) {
1901 if ( ! netdev_is_open ( dev
->netdev
) )
1905 if ( dev
->handshaker
&& dev
->handshaker
->change_key
&&
1906 dev
->handshaker
->change_key ( dev
) < 0 )
1909 fetch_string_setting ( netdev_settings ( dev
->netdev
),
1910 &net80211_ssid_setting
, ssid
,
1911 IEEE80211_MAX_SSID_LEN
+ 1 );
1914 ( ! ( ! ssid
[0] && ( dev
->state
& NET80211_AUTO_SSID
) ) &&
1915 strcmp ( ssid
, dev
->essid
) != 0 ) ) {
1916 DBGC ( dev
, "802.11 %p updating association: "
1917 "%s -> %s\n", dev
, dev
->essid
, ssid
);
1918 net80211_autoassociate ( dev
);
1926 * Start 802.11 association process
1928 * @v dev 802.11 device
1930 * If the association process is running, it will be restarted.
1932 void net80211_autoassociate ( struct net80211_device
*dev
)
1934 if ( ! ( dev
->state
& NET80211_WORKING
) ) {
1935 DBGC2 ( dev
, "802.11 %p spawning association process\n", dev
);
1936 process_add ( &dev
->proc_assoc
);
1938 DBGC2 ( dev
, "802.11 %p restarting association\n", dev
);
1941 /* Clean up everything an earlier association process might
1942 have been in the middle of using */
1943 if ( dev
->associating
)
1944 net80211_free_wlan ( dev
->associating
);
1946 if ( ! ( dev
->state
& NET80211_PROBED
) )
1947 net80211_free_wlan (
1948 net80211_probe_finish_best ( dev
->ctx
.probe
) );
1950 free ( dev
->ctx
.assoc
);
1952 /* Reset to a clean state */
1953 fetch_string_setting ( netdev_settings ( dev
->netdev
),
1954 &net80211_ssid_setting
, dev
->essid
,
1955 IEEE80211_MAX_SSID_LEN
+ 1 );
1956 dev
->ctx
.probe
= NULL
;
1957 dev
->associating
= NULL
;
1959 net80211_set_state ( dev
, NET80211_PROBED
, NET80211_WORKING
, 0 );
1963 * Pick TX rate for RTS/CTS packets based on data rate
1965 * @v dev 802.11 device
1967 * The RTS/CTS rate is the fastest TX rate marked as "basic" that is
1968 * not faster than the data rate.
1970 static void net80211_set_rtscts_rate ( struct net80211_device
*dev
)
1972 u16 datarate
= dev
->rates
[dev
->rate
];
1977 for ( i
= 0; i
< dev
->nr_rates
; i
++ ) {
1978 u16 rate
= dev
->rates
[i
];
1980 if ( ! ( dev
->basic_rates
& ( 1 << i
) ) || rate
> datarate
)
1983 if ( rate
> rtsrate
) {
1989 /* If this is in initialization, we might not have any basic
1990 rates; just use the first data rate in that case. */
1994 dev
->rtscts_rate
= rts_idx
;
1998 * Set data transmission rate for 802.11 device
2000 * @v dev 802.11 device
2001 * @v rate Rate to set, as index into @c dev->rates array
2003 void net80211_set_rate_idx ( struct net80211_device
*dev
, int rate
)
2005 assert ( netdev_is_open ( dev
->netdev
) );
2007 if ( rate
>= 0 && rate
< dev
->nr_rates
&& rate
!= dev
->rate
) {
2008 DBGC2 ( dev
, "802.11 %p changing rate from %d->%d Mbps\n",
2009 dev
, dev
->rates
[dev
->rate
] / 10,
2010 dev
->rates
[rate
] / 10 );
2013 net80211_set_rtscts_rate ( dev
);
2014 dev
->op
->config ( dev
, NET80211_CFG_RATE
);
2019 * Configure 802.11 device to transmit on a certain channel
2021 * @v dev 802.11 device
2022 * @v channel Channel number (1-11 for 2.4GHz) to transmit on
2024 int net80211_change_channel ( struct net80211_device
*dev
, int channel
)
2026 int i
, oldchan
= dev
->channel
;
2028 assert ( netdev_is_open ( dev
->netdev
) );
2030 for ( i
= 0; i
< dev
->nr_channels
; i
++ ) {
2031 if ( dev
->channels
[i
].channel_nr
== channel
) {
2037 if ( i
== dev
->nr_channels
)
2041 return dev
->op
->config ( dev
, NET80211_CFG_CHANNEL
);
2047 * Prepare 802.11 device channel and rate set for scanning
2049 * @v dev 802.11 device
2050 * @v band RF band(s) on which to prepare for scanning
2051 * @v active Whether the scanning will be active
2052 * @ret rc Return status code
2054 int net80211_prepare_probe ( struct net80211_device
*dev
, int band
,
2057 assert ( netdev_is_open ( dev
->netdev
) );
2059 if ( active
&& ( band
& NET80211_BAND_BIT_5GHZ
) ) {
2060 DBGC ( dev
, "802.11 %p cannot perform active scanning on "
2061 "5GHz band\n", dev
);
2062 return -EINVAL_ACTIVE_SCAN
;
2066 /* This can happen for a 5GHz-only card with 5GHz
2067 scanning masked out by an active request. */
2068 DBGC ( dev
, "802.11 %p asked to prepare for scanning nothing\n",
2070 return -EINVAL_ACTIVE_SCAN
;
2073 dev
->nr_channels
= 0;
2076 net80211_add_channels ( dev
, 1, 11, NET80211_REG_TXPOWER
);
2078 if ( band
& NET80211_BAND_BIT_2GHZ
)
2079 net80211_add_channels ( dev
, 1, 14,
2080 NET80211_REG_TXPOWER
);
2081 if ( band
& NET80211_BAND_BIT_5GHZ
)
2082 net80211_add_channels ( dev
, 36, 8,
2083 NET80211_REG_TXPOWER
);
2086 net80211_filter_hw_channels ( dev
);
2088 /* Use channel 1 for now */
2090 dev
->op
->config ( dev
, NET80211_CFG_CHANNEL
);
2092 /* Always do active probes at lowest (presumably first) speed */
2095 dev
->rates
[0] = dev
->hw
->rates
[dev
->channels
[0].band
][0];
2096 dev
->op
->config ( dev
, NET80211_CFG_RATE
);
2102 * Prepare 802.11 device channel and rate set for communication
2104 * @v dev 802.11 device
2105 * @v wlan WLAN to prepare for communication with
2106 * @ret rc Return status code
2108 int net80211_prepare_assoc ( struct net80211_device
*dev
,
2109 struct net80211_wlan
*wlan
)
2111 struct ieee80211_frame
*hdr
= wlan
->beacon
->data
;
2112 struct ieee80211_beacon
*beacon
=
2113 ( struct ieee80211_beacon
* ) hdr
->data
;
2114 struct net80211_handshaker
*handshaker
;
2117 assert ( netdev_is_open ( dev
->netdev
) );
2119 net80211_set_state ( dev
, NET80211_ASSOCIATED
, 0, 0 );
2120 memcpy ( dev
->bssid
, wlan
->bssid
, ETH_ALEN
);
2121 strcpy ( dev
->essid
, wlan
->essid
);
2123 free ( dev
->rsn_ie
);
2126 dev
->last_beacon_timestamp
= beacon
->timestamp
;
2127 dev
->tx_beacon_interval
= 1024 * beacon
->beacon_interval
;
2129 /* Barring an IE that tells us the channel outright, assume
2130 the channel we heard this AP best on is the channel it's
2131 communicating on. */
2132 net80211_change_channel ( dev
, wlan
->channel
);
2134 rc
= net80211_process_capab ( dev
, beacon
->capability
);
2138 rc
= net80211_process_ie ( dev
, beacon
->info_element
,
2139 wlan
->beacon
->tail
);
2143 /* Associate at the lowest rate so we know it'll get through */
2145 dev
->op
->config ( dev
, NET80211_CFG_RATE
);
2147 /* Free old handshaker and crypto, if they exist */
2148 if ( dev
->handshaker
&& dev
->handshaker
->stop
&&
2149 dev
->handshaker
->started
)
2150 dev
->handshaker
->stop ( dev
);
2151 free ( dev
->handshaker
);
2152 dev
->handshaker
= NULL
;
2153 free ( dev
->crypto
);
2154 free ( dev
->gcrypto
);
2155 dev
->crypto
= dev
->gcrypto
= NULL
;
2157 /* Find new security handshaker to use */
2158 for_each_table_entry ( handshaker
, NET80211_HANDSHAKERS
) {
2159 if ( handshaker
->protocol
== wlan
->handshaking
) {
2160 dev
->handshaker
= zalloc ( sizeof ( *handshaker
) +
2161 handshaker
->priv_len
);
2162 if ( ! dev
->handshaker
)
2165 memcpy ( dev
->handshaker
, handshaker
,
2166 sizeof ( *handshaker
) );
2167 dev
->handshaker
->priv
= ( ( void * ) dev
->handshaker
+
2168 sizeof ( *handshaker
) );
2173 if ( ( wlan
->handshaking
!= NET80211_SECPROT_NONE
) &&
2174 ! dev
->handshaker
) {
2175 DBGC ( dev
, "802.11 %p no support for handshaking scheme %d\n",
2176 dev
, wlan
->handshaking
);
2177 return -( ENOTSUP
| ( wlan
->handshaking
<< 8 ) );
2180 /* Initialize security handshaker */
2181 if ( dev
->handshaker
) {
2182 rc
= dev
->handshaker
->init ( dev
);
2191 * Send 802.11 initial authentication frame
2193 * @v dev 802.11 device
2194 * @v wlan WLAN to authenticate with
2195 * @v method Authentication method
2196 * @ret rc Return status code
2198 * @a method may be 0 for Open System authentication or 1 for Shared
2199 * Key authentication. Open System provides no security in association
2200 * whatsoever, relying on encryption for confidentiality, but Shared
2201 * Key actively introduces security problems and is very rarely used.
2203 int net80211_send_auth ( struct net80211_device
*dev
,
2204 struct net80211_wlan
*wlan
, int method
)
2206 struct io_buffer
*iob
= alloc_iob ( 64 );
2207 struct ieee80211_auth
*auth
;
2209 net80211_set_state ( dev
, 0, NET80211_WAITING
, 0 );
2210 iob_reserve ( iob
, IEEE80211_TYP_FRAME_HEADER_LEN
);
2211 auth
= iob_put ( iob
, sizeof ( *auth
) );
2212 auth
->algorithm
= method
;
2216 return net80211_tx_mgmt ( dev
, IEEE80211_STYPE_AUTH
, wlan
->bssid
, iob
);
2220 * Handle receipt of 802.11 authentication frame
2222 * @v dev 802.11 device
2225 * If the authentication method being used is Shared Key, and the
2226 * frame that was received included challenge text, the frame is
2227 * encrypted using the cryptosystem currently in effect and sent back
2228 * to the AP to complete the authentication.
2230 static void net80211_handle_auth ( struct net80211_device
*dev
,
2231 struct io_buffer
*iob
)
2233 struct ieee80211_frame
*hdr
= iob
->data
;
2234 struct ieee80211_auth
*auth
=
2235 ( struct ieee80211_auth
* ) hdr
->data
;
2237 if ( auth
->tx_seq
& 1 ) {
2238 DBGC ( dev
, "802.11 %p authentication received improperly "
2239 "directed frame (seq. %d)\n", dev
, auth
->tx_seq
);
2240 net80211_set_state ( dev
, NET80211_WAITING
, 0,
2241 IEEE80211_STATUS_FAILURE
);
2245 if ( auth
->status
!= IEEE80211_STATUS_SUCCESS
) {
2246 DBGC ( dev
, "802.11 %p authentication failed: status %d\n",
2247 dev
, auth
->status
);
2248 net80211_set_state ( dev
, NET80211_WAITING
, 0,
2253 if ( auth
->algorithm
== IEEE80211_AUTH_SHARED_KEY
&& ! dev
->crypto
) {
2254 DBGC ( dev
, "802.11 %p can't perform shared-key authentication "
2255 "without a cryptosystem\n", dev
);
2256 net80211_set_state ( dev
, NET80211_WAITING
, 0,
2257 IEEE80211_STATUS_FAILURE
);
2261 if ( auth
->algorithm
== IEEE80211_AUTH_SHARED_KEY
&&
2262 auth
->tx_seq
== 2 ) {
2263 /* Since the iob we got is going to be freed as soon
2264 as we return, we can do some in-place
2269 memcpy ( hdr
->addr2
, hdr
->addr1
, ETH_ALEN
);
2270 memcpy ( hdr
->addr1
, hdr
->addr3
, ETH_ALEN
);
2272 netdev_tx ( dev
->netdev
,
2273 dev
->crypto
->encrypt ( dev
->crypto
, iob
) );
2277 net80211_set_state ( dev
, NET80211_WAITING
, NET80211_AUTHENTICATED
,
2278 IEEE80211_STATUS_SUCCESS
);
2284 * Send 802.11 association frame
2286 * @v dev 802.11 device
2287 * @v wlan WLAN to associate with
2288 * @ret rc Return status code
2290 int net80211_send_assoc ( struct net80211_device
*dev
,
2291 struct net80211_wlan
*wlan
)
2293 struct io_buffer
*iob
= alloc_iob ( 128 );
2294 struct ieee80211_assoc_req
*assoc
;
2295 union ieee80211_ie
*ie
;
2297 net80211_set_state ( dev
, 0, NET80211_WAITING
, 0 );
2299 iob_reserve ( iob
, IEEE80211_TYP_FRAME_HEADER_LEN
);
2302 assoc
->capability
= IEEE80211_CAPAB_MANAGED
;
2303 if ( ! ( dev
->hw
->flags
& NET80211_HW_NO_SHORT_PREAMBLE
) )
2304 assoc
->capability
|= IEEE80211_CAPAB_SHORT_PMBL
;
2305 if ( ! ( dev
->hw
->flags
& NET80211_HW_NO_SHORT_SLOT
) )
2306 assoc
->capability
|= IEEE80211_CAPAB_SHORT_SLOT
;
2308 assoc
->capability
|= IEEE80211_CAPAB_PRIVACY
;
2310 assoc
->listen_interval
= 1;
2312 ie
= net80211_marshal_request_info ( dev
, assoc
->info_element
);
2314 DBGP ( "802.11 %p about to send association request:\n", dev
);
2315 DBGP_HD ( iob
->data
, ( void * ) ie
- iob
->data
);
2317 iob_put ( iob
, ( void * ) ie
- iob
->data
);
2319 return net80211_tx_mgmt ( dev
, IEEE80211_STYPE_ASSOC_REQ
,
2324 * Handle receipt of 802.11 association reply frame
2326 * @v dev 802.11 device
2329 static void net80211_handle_assoc_reply ( struct net80211_device
*dev
,
2330 struct io_buffer
*iob
)
2332 struct ieee80211_frame
*hdr
= iob
->data
;
2333 struct ieee80211_assoc_resp
*assoc
=
2334 ( struct ieee80211_assoc_resp
* ) hdr
->data
;
2336 net80211_process_capab ( dev
, assoc
->capability
);
2337 net80211_process_ie ( dev
, assoc
->info_element
, iob
->tail
);
2339 if ( assoc
->status
!= IEEE80211_STATUS_SUCCESS
) {
2340 DBGC ( dev
, "802.11 %p association failed: status %d\n",
2341 dev
, assoc
->status
);
2342 net80211_set_state ( dev
, NET80211_WAITING
, 0,
2347 /* ESSID was filled before the association request was sent */
2348 memcpy ( dev
->bssid
, hdr
->addr3
, ETH_ALEN
);
2349 dev
->aid
= assoc
->aid
;
2351 net80211_set_state ( dev
, NET80211_WAITING
, NET80211_ASSOCIATED
,
2352 IEEE80211_STATUS_SUCCESS
);
2357 * Send 802.11 disassociation frame
2359 * @v dev 802.11 device
2360 * @v reason Reason for disassociation
2361 * @v deauth If TRUE, send deauthentication instead of disassociation
2362 * @ret rc Return status code
2364 static int net80211_send_disassoc ( struct net80211_device
*dev
, int reason
,
2367 struct io_buffer
*iob
= alloc_iob ( 64 );
2368 struct ieee80211_disassoc
*disassoc
;
2370 if ( ! ( dev
->state
& NET80211_ASSOCIATED
) )
2373 net80211_set_state ( dev
, NET80211_ASSOCIATED
, 0, 0 );
2374 iob_reserve ( iob
, IEEE80211_TYP_FRAME_HEADER_LEN
);
2375 disassoc
= iob_put ( iob
, sizeof ( *disassoc
) );
2376 disassoc
->reason
= reason
;
2378 return net80211_tx_mgmt ( dev
, deauth ? IEEE80211_STYPE_DEAUTH
:
2379 IEEE80211_STYPE_DISASSOC
, dev
->bssid
, iob
);
2384 * Deauthenticate from current network and try again
2386 * @v dev 802.11 device
2387 * @v rc Return status code indicating reason
2389 * The deauthentication will be sent using an 802.11 "unspecified
2390 * reason", as is common, but @a rc will be set as a link-up
2391 * error to aid the user in debugging.
2393 void net80211_deauthenticate ( struct net80211_device
*dev
, int rc
)
2395 net80211_send_disassoc ( dev
, IEEE80211_REASON_UNSPECIFIED
, 1 );
2397 netdev_link_err ( dev
->netdev
, rc
);
2399 net80211_autoassociate ( dev
);
2403 /** Smoothing factor (1-7) for link quality calculation */
2407 * Update link quality information based on received beacon
2409 * @v dev 802.11 device
2410 * @v iob I/O buffer containing beacon
2411 * @ret rc Return status code
2413 static void net80211_update_link_quality ( struct net80211_device
*dev
,
2414 struct io_buffer
*iob
)
2416 struct ieee80211_frame
*hdr
= iob
->data
;
2417 struct ieee80211_beacon
*beacon
;
2420 if ( ! ( dev
->state
& NET80211_ASSOCIATED
) )
2423 beacon
= ( struct ieee80211_beacon
* ) hdr
->data
;
2424 dt
= ( u32
) ( beacon
->timestamp
- dev
->last_beacon_timestamp
);
2425 rxi
= dev
->rx_beacon_interval
;
2427 rxi
= ( LQ_SMOOTH
* rxi
) + ( ( 8 - LQ_SMOOTH
) * dt
);
2428 dev
->rx_beacon_interval
= rxi
>> 3;
2430 dev
->last_beacon_timestamp
= beacon
->timestamp
;
2435 * Handle receipt of 802.11 management frame
2437 * @v dev 802.11 device
2439 * @v signal Signal strength of received frame
2441 static void net80211_handle_mgmt ( struct net80211_device
*dev
,
2442 struct io_buffer
*iob
, int signal
)
2444 struct ieee80211_frame
*hdr
= iob
->data
;
2445 struct ieee80211_disassoc
*disassoc
;
2446 u16 stype
= hdr
->fc
& IEEE80211_FC_SUBTYPE
;
2448 int is_deauth
= ( stype
== IEEE80211_STYPE_DEAUTH
);
2450 if ( ( hdr
->fc
& IEEE80211_FC_TYPE
) != IEEE80211_TYPE_MGMT
) {
2452 return; /* only handle management frames */
2456 /* We reconnect on deauthentication and disassociation. */
2457 case IEEE80211_STYPE_DEAUTH
:
2458 case IEEE80211_STYPE_DISASSOC
:
2459 disassoc
= ( struct ieee80211_disassoc
* ) hdr
->data
;
2460 net80211_set_state ( dev
, is_deauth ? NET80211_AUTHENTICATED
:
2461 NET80211_ASSOCIATED
, 0,
2462 NET80211_IS_REASON
| disassoc
->reason
);
2463 DBGC ( dev
, "802.11 %p %s: reason %d\n",
2464 dev
, is_deauth ?
"deauthenticated" : "disassociated",
2467 /* Try to reassociate, in case it's transient. */
2468 net80211_autoassociate ( dev
);
2472 /* We handle authentication and association. */
2473 case IEEE80211_STYPE_AUTH
:
2474 if ( ! ( dev
->state
& NET80211_AUTHENTICATED
) )
2475 net80211_handle_auth ( dev
, iob
);
2478 case IEEE80211_STYPE_ASSOC_RESP
:
2479 case IEEE80211_STYPE_REASSOC_RESP
:
2480 if ( ! ( dev
->state
& NET80211_ASSOCIATED
) )
2481 net80211_handle_assoc_reply ( dev
, iob
);
2484 /* We pass probes and beacons onto network scanning
2485 code. Pass actions for future extensibility. */
2486 case IEEE80211_STYPE_BEACON
:
2487 net80211_update_link_quality ( dev
, iob
);
2489 case IEEE80211_STYPE_PROBE_RESP
:
2490 case IEEE80211_STYPE_ACTION
:
2491 if ( dev
->keep_mgmt
) {
2492 struct net80211_rx_info
*rxinf
;
2493 rxinf
= zalloc ( sizeof ( *rxinf
) );
2495 DBGC ( dev
, "802.11 %p out of memory\n", dev
);
2498 rxinf
->signal
= signal
;
2499 list_add_tail ( &iob
->list
, &dev
->mgmt_queue
);
2500 list_add_tail ( &rxinf
->list
, &dev
->mgmt_info_queue
);
2505 case IEEE80211_STYPE_PROBE_REQ
:
2506 /* Some nodes send these broadcast. Ignore them. */
2509 case IEEE80211_STYPE_ASSOC_REQ
:
2510 case IEEE80211_STYPE_REASSOC_REQ
:
2511 /* We should never receive these, only send them. */
2512 DBGC ( dev
, "802.11 %p received strange management request "
2513 "(%04x)\n", dev
, stype
);
2517 DBGC ( dev
, "802.11 %p received unimplemented management "
2518 "packet (%04x)\n", dev
, stype
);
2526 /* ---------- Packet handling functions ---------- */
2529 * Free buffers used by 802.11 fragment cache entry
2531 * @v dev 802.11 device
2532 * @v fcid Fragment cache entry index
2534 * After this function, the referenced entry will be marked unused.
2536 static void net80211_free_frags ( struct net80211_device
*dev
, int fcid
)
2539 struct net80211_frag_cache
*frag
= &dev
->frags
[fcid
];
2541 for ( j
= 0; j
< 16; j
++ ) {
2542 if ( frag
->iob
[j
] ) {
2543 free_iob ( frag
->iob
[j
] );
2544 frag
->iob
[j
] = NULL
;
2549 frag
->start_ticks
= 0;
2554 * Accumulate 802.11 fragments into one I/O buffer
2556 * @v dev 802.11 device
2557 * @v fcid Fragment cache entry index
2558 * @v nfrags Number of fragments received
2559 * @v size Sum of sizes of all fragments, including headers
2560 * @ret iob I/O buffer containing reassembled packet
2562 * This function does not free the fragment buffers.
2564 static struct io_buffer
*net80211_accum_frags ( struct net80211_device
*dev
,
2565 int fcid
, int nfrags
, int size
)
2567 struct net80211_frag_cache
*frag
= &dev
->frags
[fcid
];
2568 int hdrsize
= IEEE80211_TYP_FRAME_HEADER_LEN
;
2569 int nsize
= size
- hdrsize
* ( nfrags
- 1 );
2572 struct io_buffer
*niob
= alloc_iob ( nsize
);
2573 struct ieee80211_frame
*hdr
;
2575 /* Add the header from the first one... */
2576 memcpy ( iob_put ( niob
, hdrsize
), frag
->iob
[0]->data
, hdrsize
);
2578 /* ... and all the data from all of them. */
2579 for ( i
= 0; i
< nfrags
; i
++ ) {
2580 int len
= iob_len ( frag
->iob
[i
] ) - hdrsize
;
2581 memcpy ( iob_put ( niob
, len
),
2582 frag
->iob
[i
]->data
+ hdrsize
, len
);
2585 /* Turn off the fragment bit. */
2587 hdr
->fc
&= ~IEEE80211_FC_MORE_FRAG
;
2593 * Handle receipt of 802.11 fragment
2595 * @v dev 802.11 device
2596 * @v iob I/O buffer containing fragment
2597 * @v signal Signal strength with which fragment was received
2599 static void net80211_rx_frag ( struct net80211_device
*dev
,
2600 struct io_buffer
*iob
, int signal
)
2602 struct ieee80211_frame
*hdr
= iob
->data
;
2603 int fragnr
= IEEE80211_FRAG ( hdr
->seq
);
2605 if ( fragnr
== 0 && ( hdr
->fc
& IEEE80211_FC_MORE_FRAG
) ) {
2606 /* start a frag cache entry */
2608 u32 curr_ticks
= currticks(), newest_ticks
= 0;
2609 u32 timeout
= ticks_per_sec() * NET80211_FRAG_TIMEOUT
;
2611 for ( i
= 0; i
< NET80211_NR_CONCURRENT_FRAGS
; i
++ ) {
2612 if ( dev
->frags
[i
].in_use
== 0 )
2615 if ( dev
->frags
[i
].start_ticks
+ timeout
>=
2617 net80211_free_frags ( dev
, i
);
2621 if ( dev
->frags
[i
].start_ticks
> newest_ticks
) {
2623 newest_ticks
= dev
->frags
[i
].start_ticks
;
2627 /* If we're being sent more concurrent fragmented
2628 packets than we can handle, drop the newest so the
2629 older ones have time to complete. */
2630 if ( i
== NET80211_NR_CONCURRENT_FRAGS
) {
2632 net80211_free_frags ( dev
, i
);
2635 dev
->frags
[i
].in_use
= 1;
2636 dev
->frags
[i
].seqnr
= IEEE80211_SEQNR ( hdr
->seq
);
2637 dev
->frags
[i
].start_ticks
= currticks();
2638 dev
->frags
[i
].iob
[0] = iob
;
2642 for ( i
= 0; i
< NET80211_NR_CONCURRENT_FRAGS
; i
++ ) {
2643 if ( dev
->frags
[i
].in_use
&& dev
->frags
[i
].seqnr
==
2644 IEEE80211_SEQNR ( hdr
->seq
) )
2647 if ( i
== NET80211_NR_CONCURRENT_FRAGS
) {
2648 /* Drop non-first not-in-cache fragments */
2649 DBGC ( dev
, "802.11 %p dropped fragment fc=%04x "
2650 "seq=%04x\n", dev
, hdr
->fc
, hdr
->seq
);
2655 dev
->frags
[i
].iob
[fragnr
] = iob
;
2657 if ( ! ( hdr
->fc
& IEEE80211_FC_MORE_FRAG
) ) {
2659 for ( j
= 0; j
< fragnr
; j
++ ) {
2660 size
+= iob_len ( dev
->frags
[i
].iob
[j
] );
2661 if ( dev
->frags
[i
].iob
[j
] == NULL
)
2664 if ( j
== fragnr
) {
2665 /* We've got everything */
2666 struct io_buffer
*niob
=
2667 net80211_accum_frags ( dev
, i
, fragnr
,
2669 net80211_free_frags ( dev
, i
);
2670 net80211_rx ( dev
, niob
, signal
, 0 );
2672 DBGC ( dev
, "802.11 %p dropping fragmented "
2673 "packet due to out-of-order arrival, "
2674 "fc=%04x seq=%04x\n", dev
, hdr
->fc
,
2676 net80211_free_frags ( dev
, i
);
2683 * Handle receipt of 802.11 frame
2685 * @v dev 802.11 device
2687 * @v signal Received signal strength
2688 * @v rate Bitrate at which frame was received, in 100 kbps units
2690 * If the rate or signal is unknown, 0 should be passed.
2692 void net80211_rx ( struct net80211_device
*dev
, struct io_buffer
*iob
,
2693 int signal
, u16 rate
)
2695 struct ieee80211_frame
*hdr
= iob
->data
;
2696 u16 type
= hdr
->fc
& IEEE80211_FC_TYPE
;
2697 if ( ( hdr
->fc
& IEEE80211_FC_VERSION
) != IEEE80211_THIS_VERSION
)
2698 goto drop
; /* drop invalid-version packets */
2700 if ( type
== IEEE80211_TYPE_CTRL
)
2701 goto drop
; /* we don't handle control packets,
2702 the hardware does */
2704 if ( dev
->last_rx_seq
== hdr
->seq
)
2705 goto drop
; /* avoid duplicate packet */
2706 dev
->last_rx_seq
= hdr
->seq
;
2708 if ( dev
->hw
->flags
& NET80211_HW_RX_HAS_FCS
) {
2709 /* discard the FCS */
2710 iob_unput ( iob
, 4 );
2713 /* Only decrypt packets from our BSSID, to avoid spurious errors */
2714 if ( ( hdr
->fc
& IEEE80211_FC_PROTECTED
) &&
2715 ! memcmp ( hdr
->addr2
, dev
->bssid
, ETH_ALEN
) ) {
2716 /* Decrypt packet; record and drop if it fails */
2717 struct io_buffer
*niob
;
2718 struct net80211_crypto
*crypto
= dev
->crypto
;
2720 if ( ! dev
->crypto
) {
2721 DBGC ( dev
, "802.11 %p cannot decrypt packet "
2722 "without a cryptosystem\n", dev
);
2726 if ( ( hdr
->addr1
[0] & 1 ) && dev
->gcrypto
) {
2727 /* Use group decryption if needed */
2728 crypto
= dev
->gcrypto
;
2731 niob
= crypto
->decrypt ( crypto
, iob
);
2733 DBGC ( dev
, "802.11 %p decryption error\n", dev
);
2741 dev
->last_signal
= signal
;
2743 /* Fragments go into the frag cache or get dropped. */
2744 if ( IEEE80211_FRAG ( hdr
->seq
) != 0
2745 || ( hdr
->fc
& IEEE80211_FC_MORE_FRAG
) ) {
2746 net80211_rx_frag ( dev
, iob
, signal
);
2750 /* Management frames get handled, enqueued, or dropped. */
2751 if ( type
== IEEE80211_TYPE_MGMT
) {
2752 net80211_handle_mgmt ( dev
, iob
, signal
);
2756 /* Data frames get dropped or sent to the net_device. */
2757 if ( ( hdr
->fc
& IEEE80211_FC_SUBTYPE
) != IEEE80211_STYPE_DATA
)
2758 goto drop
; /* drop QoS, CFP, or null data packets */
2760 /* Update rate-control algorithm */
2762 rc80211_update_rx ( dev
, hdr
->fc
& IEEE80211_FC_RETRY
, rate
);
2764 /* Pass packet onward */
2765 if ( dev
->state
& NET80211_ASSOCIATED
) {
2766 netdev_rx ( dev
->netdev
, iob
);
2770 /* No association? Drop it. */
2774 netdev_rx_err ( dev
->netdev
, NULL
, EINVAL_CRYPTO_REQUEST
);
2776 DBGC2 ( dev
, "802.11 %p dropped packet fc=%04x seq=%04x\n", dev
,
2777 hdr
->fc
, hdr
->seq
);
2782 /** Indicate an error in receiving a packet
2784 * @v dev 802.11 device
2785 * @v iob I/O buffer with received packet, or NULL
2788 * This logs the error with the wrapping net_device, and frees iob if
2791 void net80211_rx_err ( struct net80211_device
*dev
,
2792 struct io_buffer
*iob
, int rc
)
2794 netdev_rx_err ( dev
->netdev
, iob
, rc
);
2797 /** Indicate the completed transmission of a packet
2799 * @v dev 802.11 device
2800 * @v iob I/O buffer of transmitted packet
2801 * @v retries Number of times this packet was retransmitted
2802 * @v rc Error code, or 0 for success
2804 * This logs an error with the wrapping net_device if one occurred,
2805 * and removes and frees the I/O buffer from its TX queue. The
2806 * provided retry information is used to tune our transmission rate.
2808 * If the packet did not need to be retransmitted because it was
2809 * properly ACKed the first time, @a retries should be 0.
2811 void net80211_tx_complete ( struct net80211_device
*dev
,
2812 struct io_buffer
*iob
, int retries
, int rc
)
2814 /* Update rate-control algorithm */
2816 rc80211_update_tx ( dev
, retries
, rc
);
2818 /* Pass completion onward */
2819 netdev_tx_complete_err ( dev
->netdev
, iob
, rc
);
2822 /** Common 802.11 errors */
2823 struct errortab common_wireless_errors
[] __errortab
= {
2824 __einfo_errortab ( EINFO_EINVAL_CRYPTO_REQUEST
),
2825 __einfo_errortab ( EINFO_ECONNRESET_UNSPECIFIED
),
2826 __einfo_errortab ( EINFO_ECONNRESET_INACTIVITY
),
2827 __einfo_errortab ( EINFO_ECONNRESET_4WAY_TIMEOUT
),
2828 __einfo_errortab ( EINFO_ECONNRESET_8021X_FAILURE
),
2829 __einfo_errortab ( EINFO_ECONNREFUSED_FAILURE
),
2830 __einfo_errortab ( EINFO_ECONNREFUSED_ASSOC_DENIED
),
2831 __einfo_errortab ( EINFO_ECONNREFUSED_AUTH_ALGO_UNSUPP
),
2834 /* Drag in objects via net80211_ll_protocol */
2835 REQUIRING_SYMBOL ( net80211_ll_protocol
);
2837 /* Drag in 802.11 configuration */
2838 REQUIRE_OBJECT ( config_net80211
);