iPXE
net80211.c
Go to the documentation of this file.
1/*
2 * The iPXE 802.11 MAC layer.
3 *
4 * Copyright (c) 2009 Joshua Oreman <oremanj@rwcr.net>.
5 *
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.
10 *
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.
15 *
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
19 * 02110-1301, USA.
20 */
21
22FILE_LICENCE ( GPL2_OR_LATER );
23FILE_SECBOOT ( FORBIDDEN );
24
25#include <string.h>
26#include <byteswap.h>
27#include <stdlib.h>
28#include <unistd.h>
29#include <errno.h>
30#include <ipxe/settings.h>
31#include <ipxe/if_arp.h>
32#include <ipxe/ethernet.h>
33#include <ipxe/ieee80211.h>
34#include <ipxe/netdevice.h>
35#include <ipxe/net80211.h>
36#include <ipxe/sec80211.h>
37#include <ipxe/timer.h>
38#include <ipxe/nap.h>
39#include <ipxe/errortab.h>
40#include <ipxe/net80211_err.h>
41
42/** @file
43 *
44 * 802.11 device management
45 */
46
47/** List of 802.11 devices */
49
50/** Set of device operations that does nothing */
52
53/** Information associated with a received management packet
54 *
55 * This is used to keep beacon signal strengths in a parallel queue to
56 * the beacons themselves.
57 */
59 int signal;
61};
62
63/** Context for a probe operation */
65 /** 802.11 device to probe on */
67
68 /** Value of keep_mgmt before probe was started */
70
71 /** If scanning actively, pointer to probe packet to send */
73
74 /** If non-"", the ESSID to limit ourselves to */
75 const char *essid;
76
77 /** Time probe was started */
79
80 /** Time last useful beacon was received */
82
83 /** Time channel was last changed */
85
86 /** Time to stay on each channel */
88
89 /** Channels to hop by when changing channel */
91
92 /** List of best beacons for each network found so far */
94};
95
96/** Context for the association task */
98 /** Next authentication method to try using */
99 int method;
100
101 /** Time (in ticks) of the last sent association-related packet */
103
104 /** Number of times we have tried sending it */
106};
107
108/**
109 * Detect secure 802.11 network when security support is not available
110 *
111 * @return -ENOTSUP, always.
112 */
114 enum net80211_security_proto *secprot __unused,
115 enum net80211_crypto_alg *crypt __unused ) {
116 return -ENOTSUP;
117}
118
119/**
120 * @defgroup net80211_netdev Network device interface functions
121 * @{
122 */
123static int net80211_netdev_open ( struct net_device *netdev );
124static void net80211_netdev_close ( struct net_device *netdev );
125static int net80211_netdev_transmit ( struct net_device *netdev,
126 struct io_buffer *iobuf );
127static void net80211_netdev_poll ( struct net_device *netdev );
128static void net80211_netdev_irq ( struct net_device *netdev, int enable );
129/** @} */
130
131/**
132 * @defgroup net80211_linklayer 802.11 link-layer protocol functions
133 * @{
134 */
135static int net80211_ll_push ( struct net_device *netdev,
136 struct io_buffer *iobuf, const void *ll_dest,
137 const void *ll_source, uint16_t net_proto );
138static int net80211_ll_pull ( struct net_device *netdev,
139 struct io_buffer *iobuf, const void **ll_dest,
140 const void **ll_source, uint16_t * net_proto,
141 unsigned int *flags );
142/** @} */
143
144/**
145 * @defgroup net80211_help 802.11 helper functions
146 * @{
147 */
148static void net80211_add_channels ( struct net80211_device *dev, int start,
149 int len, int txpower );
150static void net80211_filter_hw_channels ( struct net80211_device *dev );
151static void net80211_set_rtscts_rate ( struct net80211_device *dev );
152static int net80211_process_capab ( struct net80211_device *dev,
153 u16 capab );
154static int net80211_process_ie ( struct net80211_device *dev,
155 union ieee80211_ie *ie, void *ie_end );
156static union ieee80211_ie *
158 union ieee80211_ie *ie );
159/** @} */
160
161/**
162 * @defgroup net80211_assoc_ll 802.11 association handling functions
163 * @{
164 */
165static void net80211_step_associate ( struct net80211_device *dev );
166static void net80211_handle_auth ( struct net80211_device *dev,
167 struct io_buffer *iob );
168static void net80211_handle_assoc_reply ( struct net80211_device *dev,
169 struct io_buffer *iob );
170static int net80211_send_disassoc ( struct net80211_device *dev, int reason,
171 int deauth );
172static void net80211_handle_mgmt ( struct net80211_device *dev,
173 struct io_buffer *iob, int signal );
174/** @} */
175
176/**
177 * @defgroup net80211_frag 802.11 fragment handling functions
178 * @{
179 */
180static void net80211_free_frags ( struct net80211_device *dev, int fcid );
181static struct io_buffer *net80211_accum_frags ( struct net80211_device *dev,
182 int fcid, int nfrags, int size );
183static void net80211_rx_frag ( struct net80211_device *dev,
184 struct io_buffer *iob, int signal );
185/** @} */
186
187/**
188 * @defgroup net80211_settings 802.11 settings handlers
189 * @{
190 */
191static int net80211_check_settings_update ( void );
192
193/** 802.11 settings applicator
194 *
195 * When the SSID is changed, this will cause any open devices to
196 * re-associate; when the encryption key is changed, we similarly
197 * update their state.
198 */
199struct settings_applicator net80211_applicator __settings_applicator = {
201};
202
203/** The network name to associate with
204 *
205 * If this is blank, we scan for all networks and use the one with the
206 * greatest signal strength.
207 */
208const struct setting net80211_ssid_setting __setting ( SETTING_NETDEV_EXTRA,
209 ssid ) = {
210 .name = "ssid",
211 .description = "Wireless SSID",
212 .type = &setting_type_string,
213};
214
215/** Whether to use active scanning
216 *
217 * In order to associate with a hidden SSID, it's necessary to use an
218 * active scan (send probe packets). If this setting is nonzero, an
219 * active scan on the 2.4GHz band will be used to associate.
220 */
221const struct setting net80211_active_setting __setting ( SETTING_NETDEV_EXTRA,
222 active-scan ) = {
223 .name = "active-scan",
224 .description = "Actively scan for wireless networks",
225 .type = &setting_type_int8,
226};
227
228/** The cryptographic key to use
229 *
230 * For hex WEP keys, as is common, this must be entered using the
231 * normal iPXE method for entering hex settings; an ASCII string of
232 * hex characters will not behave as expected.
233 */
234const struct setting net80211_key_setting __setting ( SETTING_NETDEV_EXTRA,
235 key ) = {
236 .name = "key",
237 .description = "Wireless encryption key",
238 .type = &setting_type_string,
239};
240
241/** @} */
242
243
244/* ---------- net_device wrapper ---------- */
245
246/**
247 * Open 802.11 device and start association
248 *
249 * @v netdev Wrapping network device
250 * @ret rc Return status code
251 *
252 * This sets up a default conservative set of channels for probing,
253 * and starts the auto-association task unless the @c
254 * NET80211_NO_ASSOC flag is set in the wrapped 802.11 device's @c
255 * state field.
256 */
258{
259 struct net80211_device *dev = netdev->priv;
260 int rc = 0;
261
262 if ( dev->op == &net80211_null_ops )
263 return -EFAULT;
264
265 if ( dev->op->open )
266 rc = dev->op->open ( dev );
267
268 if ( rc < 0 )
269 return rc;
270
271 if ( ! ( dev->state & NET80211_NO_ASSOC ) )
273
274 return 0;
275}
276
277/**
278 * Close 802.11 device
279 *
280 * @v netdev Wrapping network device.
281 *
282 * If the association task is running, this will stop it.
283 */
285{
286 struct net80211_device *dev = netdev->priv;
287
288 if ( dev->state & NET80211_WORKING )
289 process_del ( &dev->proc_assoc );
290
291 /* Send disassociation frame to AP, to be polite */
292 if ( dev->state & NET80211_ASSOCIATED )
294
295 if ( dev->handshaker && dev->handshaker->stop &&
296 dev->handshaker->started )
297 dev->handshaker->stop ( dev );
298
299 free ( dev->crypto );
300 free ( dev->handshaker );
301 dev->crypto = NULL;
302 dev->handshaker = NULL;
303
305 dev->state = 0;
306
307 if ( dev->op->close )
308 dev->op->close ( dev );
309}
310
311/**
312 * Transmit packet on 802.11 device
313 *
314 * @v netdev Wrapping network device
315 * @v iobuf I/O buffer
316 * @ret rc Return status code
317 *
318 * If encryption is enabled for the currently associated network, the
319 * packet will be encrypted prior to transmission.
320 */
322 struct io_buffer *iobuf )
323{
324 struct net80211_device *dev = netdev->priv;
325 struct ieee80211_frame *hdr = iobuf->data;
326 int rc = -ENOSYS;
327
328 if ( dev->crypto && ! ( hdr->fc & IEEE80211_FC_PROTECTED ) &&
329 ( ( hdr->fc & IEEE80211_FC_TYPE ) == IEEE80211_TYPE_DATA ) ) {
330 struct io_buffer *niob = dev->crypto->encrypt ( dev->crypto,
331 iobuf );
332 if ( ! niob )
333 return -ENOMEM; /* only reason encryption could fail */
334
335 /* Free the non-encrypted iob */
336 netdev_tx_complete ( netdev, iobuf );
337
338 /* Transmit the encrypted iob; the Protected flag is
339 set, so we won't recurse into here again */
340 netdev_tx ( netdev, niob );
341
342 /* Don't transmit the freed packet */
343 return 0;
344 }
345
346 if ( dev->op->transmit )
347 rc = dev->op->transmit ( dev, iobuf );
348
349 return rc;
350}
351
352/**
353 * Poll 802.11 device for received packets and completed transmissions
354 *
355 * @v netdev Wrapping network device
356 */
358{
359 struct net80211_device *dev = netdev->priv;
360
361 if ( dev->op->poll )
362 dev->op->poll ( dev );
363}
364
365/**
366 * Enable or disable interrupts for 802.11 device
367 *
368 * @v netdev Wrapping network device
369 * @v enable Whether to enable interrupts
370 */
371static void net80211_netdev_irq ( struct net_device *netdev, int enable )
372{
373 struct net80211_device *dev = netdev->priv;
374
375 if ( dev->op->irq )
376 dev->op->irq ( dev, enable );
377}
378
379/** Network device operations for a wrapped 802.11 device */
381 .open = net80211_netdev_open,
382 .close = net80211_netdev_close,
383 .transmit = net80211_netdev_transmit,
384 .poll = net80211_netdev_poll,
385 .irq = net80211_netdev_irq,
386};
387
388
389/* ---------- 802.11 link-layer protocol ---------- */
390
391/**
392 * Determine whether a transmission rate uses ERP/OFDM
393 *
394 * @v rate Rate in 100 kbps units
395 * @ret is_erp TRUE if the rate is an ERP/OFDM rate
396 *
397 * 802.11b supports rates of 1.0, 2.0, 5.5, and 11.0 Mbps; any other
398 * rate than these on the 2.4GHz spectrum is an ERP (802.11g) rate.
399 */
400static inline int net80211_rate_is_erp ( u16 rate )
401{
402 if ( rate == 10 || rate == 20 || rate == 55 || rate == 110 )
403 return 0;
404 return 1;
405}
406
407
408/**
409 * Calculate one frame's contribution to 802.11 duration field
410 *
411 * @v dev 802.11 device
412 * @v bytes Amount of data to calculate duration for
413 * @ret dur Duration field in microseconds
414 *
415 * To avoid multiple stations attempting to transmit at once, 802.11
416 * provides that every packet shall include a duration field
417 * specifying a length of time for which the wireless medium will be
418 * reserved after it is transmitted. The duration is measured in
419 * microseconds and is calculated with respect to the current
420 * physical-layer parameters of the 802.11 device.
421 *
422 * For an unfragmented data or management frame, or the last fragment
423 * of a fragmented frame, the duration captures only the 10 data bytes
424 * of one ACK; call once with bytes = 10.
425 *
426 * For a fragment of a data or management rame that will be followed
427 * by more fragments, the duration captures an ACK, the following
428 * fragment, and its ACK; add the results of three calls, two with
429 * bytes = 10 and one with bytes set to the next fragment's size.
430 *
431 * For an RTS control frame, the duration captures the responding CTS,
432 * the frame being sent, and its ACK; add the results of three calls,
433 * two with bytes = 10 and one with bytes set to the next frame's size
434 * (assuming unfragmented).
435 *
436 * For a CTS-to-self control frame, the duration captures the frame
437 * being protected and its ACK; add the results of two calls, one with
438 * bytes = 10 and one with bytes set to the next frame's size.
439 *
440 * No other frame types are currently supported by iPXE.
441 */
443{
444 struct net80211_channel *chan = &dev->channels[dev->channel];
445 u32 kbps = rate * 100;
446
447 if ( chan->band == NET80211_BAND_5GHZ || net80211_rate_is_erp ( rate ) ) {
448 /* OFDM encoding (802.11a/g) */
449 int bits_per_symbol = ( kbps * 4 ) / 1000; /* 4us/symbol */
450 int bits = 22 + ( bytes << 3 ); /* 22-bit PLCP */
451 int symbols = ( bits + bits_per_symbol - 1 ) / bits_per_symbol;
452
453 return 16 + 20 + ( symbols * 4 ); /* 16us SIFS, 20us preamble */
454 } else {
455 /* CCK encoding (802.11b) */
456 int phy_time = 144 + 48; /* preamble + PLCP */
457 int bits = bytes << 3;
458 int data_time = ( bits * 1000 + kbps - 1 ) / kbps;
459
461 phy_time >>= 1;
462
463 return 10 + phy_time + data_time; /* 10us SIFS */
464 }
465}
466
467/**
468 * Add 802.11 link-layer header
469 *
470 * @v netdev Wrapping network device
471 * @v iobuf I/O buffer
472 * @v ll_dest Link-layer destination address
473 * @v ll_source Link-layer source address
474 * @v net_proto Network-layer protocol, in network byte order
475 * @ret rc Return status code
476 *
477 * This adds both the 802.11 frame header and the 802.2 LLC/SNAP
478 * header used on data packets.
479 *
480 * We also check here for state of the link that would make it invalid
481 * to send a data packet; every data packet must pass through here,
482 * and no non-data packet (e.g. management frame) should.
483 */
484static int net80211_ll_push ( struct net_device *netdev,
485 struct io_buffer *iobuf, const void *ll_dest,
486 const void *ll_source, uint16_t net_proto )
487{
488 struct net80211_device *dev = netdev->priv;
489 struct ieee80211_frame *hdr = iob_push ( iobuf,
492 struct ieee80211_llc_snap_header *lhdr =
494
495 /* We can't send data packets if we're not associated. */
496 if ( ! ( dev->state & NET80211_ASSOCIATED ) ) {
497 if ( dev->assoc_rc )
498 return dev->assoc_rc;
499 return -ENETUNREACH;
500 }
501
504
505 /* We don't send fragmented frames, so duration is the time
506 for an SIFS + 10-byte ACK. */
507 hdr->duration = net80211_duration ( dev, 10, dev->rates[dev->rate] );
508
509 memcpy ( hdr->addr1, dev->bssid, ETH_ALEN );
510 memcpy ( hdr->addr2, ll_source, ETH_ALEN );
511 memcpy ( hdr->addr3, ll_dest, ETH_ALEN );
512
513 hdr->seq = IEEE80211_MAKESEQ ( ++dev->last_tx_seqnr, 0 );
514
515 lhdr->dsap = IEEE80211_LLC_DSAP;
516 lhdr->ssap = IEEE80211_LLC_SSAP;
517 lhdr->ctrl = IEEE80211_LLC_CTRL;
518 memset ( lhdr->oui, 0x00, 3 );
519 lhdr->ethertype = net_proto;
520
521 return 0;
522}
523
524/**
525 * Remove 802.11 link-layer header
526 *
527 * @v netdev Wrapping network device
528 * @v iobuf I/O buffer
529 * @ret ll_dest Link-layer destination address
530 * @ret ll_source Link-layer source
531 * @ret net_proto Network-layer protocol, in network byte order
532 * @ret flags Packet flags
533 * @ret rc Return status code
534 *
535 * This expects and removes both the 802.11 frame header and the 802.2
536 * LLC/SNAP header that are used on data packets.
537 */
539 struct io_buffer *iobuf,
540 const void **ll_dest, const void **ll_source,
541 uint16_t * net_proto, unsigned int *flags )
542{
543 struct ieee80211_frame *hdr = iobuf->data;
544 struct ieee80211_llc_snap_header *lhdr =
546
547 /* Bunch of sanity checks */
548 if ( iob_len ( iobuf ) < IEEE80211_TYP_FRAME_HEADER_LEN +
550 DBGC ( netdev->priv, "802.11 %p packet too short (%zd bytes)\n",
551 netdev->priv, iob_len ( iobuf ) );
552 return -EINVAL_PKT_TOO_SHORT;
553 }
554
556 DBGC ( netdev->priv, "802.11 %p packet invalid version %04x\n",
557 netdev->priv, hdr->fc & IEEE80211_FC_VERSION );
558 return -EINVAL_PKT_VERSION;
559 }
560
561 if ( ( hdr->fc & IEEE80211_FC_TYPE ) != IEEE80211_TYPE_DATA ||
563 DBGC ( netdev->priv, "802.11 %p packet not data/data (fc=%04x)\n",
564 netdev->priv, hdr->fc );
565 return -EINVAL_PKT_NOT_DATA;
566 }
567
568 if ( ( hdr->fc & ( IEEE80211_FC_TODS | IEEE80211_FC_FROMDS ) ) !=
570 DBGC ( netdev->priv, "802.11 %p packet not from DS (fc=%04x)\n",
571 netdev->priv, hdr->fc );
572 return -EINVAL_PKT_NOT_FROMDS;
573 }
574
575 if ( lhdr->dsap != IEEE80211_LLC_DSAP || lhdr->ssap != IEEE80211_LLC_SSAP ||
576 lhdr->ctrl != IEEE80211_LLC_CTRL || lhdr->oui[0] || lhdr->oui[1] ||
577 lhdr->oui[2] ) {
578 DBGC ( netdev->priv, "802.11 %p LLC header is not plain EtherType "
579 "encapsulator: %02x->%02x [%02x] %02x:%02x:%02x %04x\n",
580 netdev->priv, lhdr->dsap, lhdr->ssap, lhdr->ctrl,
581 lhdr->oui[0], lhdr->oui[1], lhdr->oui[2], lhdr->ethertype );
582 return -EINVAL_PKT_LLC_HEADER;
583 }
584
585 iob_pull ( iobuf, sizeof ( *hdr ) + sizeof ( *lhdr ) );
586
587 *ll_dest = hdr->addr1;
588 *ll_source = hdr->addr3;
589 *net_proto = lhdr->ethertype;
590 *flags = ( ( is_multicast_ether_addr ( hdr->addr1 ) ?
591 LL_MULTICAST : 0 ) |
592 ( is_broadcast_ether_addr ( hdr->addr1 ) ?
593 LL_BROADCAST : 0 ) );
594 return 0;
595}
596
597/** 802.11 link-layer protocol */
598static struct ll_protocol net80211_ll_protocol __ll_protocol = {
599 .name = "802.11",
600 .push = net80211_ll_push,
601 .pull = net80211_ll_pull,
602 .init_addr = eth_init_addr,
603 .ntoa = eth_ntoa,
604 .mc_hash = eth_mc_hash,
605 .eth_addr = eth_eth_addr,
606 .eui64 = eth_eui64,
607 .ll_proto = htons ( ARPHRD_ETHER ), /* "encapsulated Ethernet" */
608 .hw_addr_len = ETH_ALEN,
609 .ll_addr_len = ETH_ALEN,
610 .ll_header_len = IEEE80211_TYP_FRAME_HEADER_LEN +
612};
613
614
615/* ---------- 802.11 network management API ---------- */
616
617/**
618 * Get 802.11 device from wrapping network device
619 *
620 * @v netdev Wrapping network device
621 * @ret dev 802.11 device wrapped by network device, or NULL
622 *
623 * Returns NULL if the network device does not wrap an 802.11 device.
624 */
626{
627 struct net80211_device *dev;
628
630 if ( netdev->priv == dev )
631 return netdev->priv;
632 }
633
634 return NULL;
635}
636
637/**
638 * Set state of 802.11 device keeping management frames
639 *
640 * @v dev 802.11 device
641 * @v enable Whether to keep management frames
642 * @ret oldenab Whether management frames were enabled before this call
643 *
644 * If enable is TRUE, beacon, probe, and action frames will be kept
645 * and may be retrieved by calling net80211_mgmt_dequeue().
646 */
647int net80211_keep_mgmt ( struct net80211_device *dev, int enable )
648{
649 int oldenab = dev->keep_mgmt;
650
651 dev->keep_mgmt = enable;
652 return oldenab;
653}
654
655/**
656 * Get 802.11 management frame
657 *
658 * @v dev 802.11 device
659 * @ret signal Signal strength of returned management frame
660 * @ret iob I/O buffer, or NULL if no management frame is queued
661 *
662 * Frames will only be returned by this function if
663 * net80211_keep_mgmt() has been previously called with enable set to
664 * TRUE.
665 *
666 * The calling function takes ownership of the returned I/O buffer.
667 */
669 int *signal )
670{
671 struct io_buffer *iobuf;
672 struct net80211_rx_info *rxi;
673
675 list_del ( &rxi->list );
676 if ( signal )
677 *signal = rxi->signal;
678 free ( rxi );
679
680 assert ( ! list_empty ( &dev->mgmt_queue ) );
681 iobuf = list_first_entry ( &dev->mgmt_queue, struct io_buffer,
682 list );
683 list_del ( &iobuf->list );
684 return iobuf;
685 }
686
687 return NULL;
688}
689
690/**
691 * Transmit 802.11 management frame
692 *
693 * @v dev 802.11 device
694 * @v fc Frame Control flags for management frame
695 * @v dest Destination access point
696 * @v iob I/O buffer
697 * @ret rc Return status code
698 *
699 * The @a fc argument must contain at least an IEEE 802.11 management
700 * subtype number (e.g. IEEE80211_STYPE_PROBE_REQ). If it contains
701 * IEEE80211_FC_PROTECTED, the frame will be encrypted prior to
702 * transmission.
703 *
704 * It is required that @a iob have at least 24 bytes of headroom
705 * reserved before its data start.
706 */
708 struct io_buffer *iob )
709{
710 struct ieee80211_frame *hdr = iob_push ( iob,
712
715 hdr->duration = net80211_duration ( dev, 10, dev->rates[dev->rate] );
716 hdr->seq = IEEE80211_MAKESEQ ( ++dev->last_tx_seqnr, 0 );
717
718 memcpy ( hdr->addr1, dest, ETH_ALEN ); /* DA = RA */
719 memcpy ( hdr->addr2, dev->netdev->ll_addr, ETH_ALEN ); /* SA = TA */
720 memcpy ( hdr->addr3, dest, ETH_ALEN ); /* BSSID */
721
722 if ( fc & IEEE80211_FC_PROTECTED ) {
723 if ( ! dev->crypto )
724 return -EINVAL_CRYPTO_REQUEST;
725
726 struct io_buffer *eiob = dev->crypto->encrypt ( dev->crypto,
727 iob );
728 free_iob ( iob );
729 iob = eiob;
730 }
731
732 return netdev_tx ( dev->netdev, iob );
733}
734
735
736/* ---------- Driver API ---------- */
737
738/** 802.11 association process descriptor */
740 PROC_DESC ( struct net80211_device, proc_assoc,
742
743/**
744 * Allocate 802.11 device
745 *
746 * @v priv_size Size of driver-private allocation area
747 * @ret dev Newly allocated 802.11 device
748 *
749 * This function allocates a net_device with space in its private area
750 * for both the net80211_device it will wrap and the driver-private
751 * data space requested. It initializes the link-layer-specific parts
752 * of the net_device, and links the net80211_device to the net_device
753 * appropriately.
754 */
755struct net80211_device * net80211_alloc ( size_t priv_size )
756{
757 struct net80211_device *dev;
758 struct net_device *netdev =
759 alloc_netdev ( sizeof ( *dev ) + priv_size );
760
761 if ( ! netdev )
762 return NULL;
763
764 netdev->ll_protocol = &net80211_ll_protocol;
765 netdev->ll_broadcast = eth_broadcast;
766 netdev->max_pkt_len = IEEE80211_MAX_DATA_LEN;
768
769 dev = netdev->priv;
770 dev->netdev = netdev;
771 dev->priv = ( u8 * ) dev + sizeof ( *dev );
772 dev->op = &net80211_null_ops;
773
775 &netdev->refcnt );
776 INIT_LIST_HEAD ( &dev->mgmt_queue );
777 INIT_LIST_HEAD ( &dev->mgmt_info_queue );
778
779 return dev;
780}
781
782/**
783 * Register 802.11 device with network stack
784 *
785 * @v dev 802.11 device
786 * @v ops 802.11 device operations
787 * @v hw 802.11 hardware information
788 *
789 * This also registers the wrapping net_device with the higher network
790 * layers.
791 */
793 struct net80211_device_operations *ops,
794 struct net80211_hw_info *hw )
795{
796 dev->op = ops;
797 dev->hw = malloc ( sizeof ( *hw ) );
798 if ( ! dev->hw )
799 return -ENOMEM;
800
801 memcpy ( dev->hw, hw, sizeof ( *hw ) );
802 memcpy ( dev->netdev->hw_addr, hw->hwaddr, ETH_ALEN );
803
804 /* Set some sensible channel defaults for driver's open() function */
805 memcpy ( dev->channels, dev->hw->channels,
806 NET80211_MAX_CHANNELS * sizeof ( dev->channels[0] ) );
807 dev->channel = 0;
808
809 /* Mark device as not supporting interrupts, if applicable */
810 if ( ! ops->irq )
811 dev->netdev->state |= NETDEV_IRQ_UNSUPPORTED;
812
814 return register_netdev ( dev->netdev );
815}
816
817/**
818 * Unregister 802.11 device from network stack
819 *
820 * @v dev 802.11 device
821 *
822 * After this call, the device operations are cleared so that they
823 * will not be called.
824 */
826{
827 unregister_netdev ( dev->netdev );
828 list_del ( &dev->list );
829 dev->op = &net80211_null_ops;
830}
831
832/**
833 * Free 802.11 device
834 *
835 * @v dev 802.11 device
836 *
837 * The device should be unregistered before this function is called.
838 */
840{
841 free ( dev->hw );
842 rc80211_free ( dev->rctl );
843 netdev_nullify ( dev->netdev );
844 netdev_put ( dev->netdev );
845}
846
847
848/* ---------- 802.11 network management workhorse code ---------- */
849
850/**
851 * Set state of 802.11 device
852 *
853 * @v dev 802.11 device
854 * @v clear Bitmask of flags to clear
855 * @v set Bitmask of flags to set
856 * @v status Status or reason code for most recent operation
857 *
858 * If @a status represents a reason code, it should be OR'ed with
859 * NET80211_IS_REASON.
860 *
861 * Clearing authentication also clears association; clearing
862 * association also clears security handshaking state. Clearing
863 * association removes the link-up flag from the wrapping net_device,
864 * but setting it does not automatically set the flag; that is left to
865 * the judgment of higher-level code.
866 */
867static inline void net80211_set_state ( struct net80211_device *dev,
868 short clear, short set,
869 u16 status )
870{
871 /* The conditions in this function are deliberately formulated
872 to be decidable at compile-time in most cases. Since clear
873 and set are generally passed as constants, the body of this
874 function can be reduced down to a few statements by the
875 compiler. */
876
877 const int statmsk = NET80211_STATUS_MASK | NET80211_IS_REASON;
878
879 if ( clear & NET80211_PROBED )
881
884
887
888 dev->state = ( dev->state & ~clear ) | set;
889 dev->state = ( dev->state & ~statmsk ) | ( status & statmsk );
890
892 netdev_link_down ( dev->netdev );
893
894 if ( ( clear | set ) & NET80211_ASSOCIATED )
895 dev->op->config ( dev, NET80211_CFG_ASSOC );
896
897 if ( status != 0 ) {
899 dev->assoc_rc = -E80211_REASON ( status );
900 else
901 dev->assoc_rc = -E80211_STATUS ( status );
902 netdev_link_err ( dev->netdev, dev->assoc_rc );
903 }
904}
905
906/**
907 * Add channels to 802.11 device
908 *
909 * @v dev 802.11 device
910 * @v start First channel number to add
911 * @v len Number of channels to add
912 * @v txpower TX power (dBm) to allow on added channels
913 *
914 * To replace the current list of channels instead of adding to it,
915 * set the nr_channels field of the 802.11 device to 0 before calling
916 * this function.
917 */
919 int len, int txpower )
920{
921 int i, chan = start;
922
923 for ( i = dev->nr_channels; len-- && i < NET80211_MAX_CHANNELS; i++ ) {
924 dev->channels[i].channel_nr = chan;
925 dev->channels[i].maxpower = txpower;
926 dev->channels[i].hw_value = 0;
927
928 if ( chan >= 1 && chan <= 14 ) {
929 dev->channels[i].band = NET80211_BAND_2GHZ;
930 if ( chan == 14 )
931 dev->channels[i].center_freq = 2484;
932 else
933 dev->channels[i].center_freq = 2407 + 5 * chan;
934 chan++;
935 } else {
936 dev->channels[i].band = NET80211_BAND_5GHZ;
937 dev->channels[i].center_freq = 5000 + 5 * chan;
938 chan += 4;
939 }
940 }
941
942 dev->nr_channels = i;
943}
944
945/**
946 * Filter 802.11 device channels for hardware capabilities
947 *
948 * @v dev 802.11 device
949 *
950 * Hardware may support fewer channels than regulatory restrictions
951 * allow; this function filters out channels in dev->channels that are
952 * not supported by the hardware list in dev->hwinfo. It also copies
953 * over the net80211_channel::hw_value and limits maximum TX power
954 * appropriately.
955 *
956 * Channels are matched based on center frequency, ignoring band and
957 * channel number.
958 *
959 * If the driver specifies no supported channels, the effect will be
960 * as though all were supported.
961 */
963{
964 int delta = 0, i = 0;
965 int old_freq = dev->channels[dev->channel].center_freq;
966 struct net80211_channel *chan, *hwchan;
967
968 if ( ! dev->hw->nr_channels )
969 return;
970
971 dev->channel = 0;
972 for ( chan = dev->channels; chan < dev->channels + dev->nr_channels;
973 chan++, i++ ) {
974 int ok = 0;
975 for ( hwchan = dev->hw->channels;
976 hwchan < dev->hw->channels + dev->hw->nr_channels;
977 hwchan++ ) {
978 if ( hwchan->center_freq == chan->center_freq ) {
979 ok = 1;
980 break;
981 }
982 }
983
984 if ( ! ok )
985 delta++;
986 else {
987 chan->hw_value = hwchan->hw_value;
988 if ( hwchan->maxpower != 0 &&
989 chan->maxpower > hwchan->maxpower )
990 chan->maxpower = hwchan->maxpower;
991 if ( old_freq == chan->center_freq )
992 dev->channel = i - delta;
993 if ( delta )
994 chan[-delta] = *chan;
995 }
996 }
997
998 dev->nr_channels -= delta;
999
1000 if ( dev->channels[dev->channel].center_freq != old_freq )
1001 dev->op->config ( dev, NET80211_CFG_CHANNEL );
1002}
1003
1004/**
1005 * Update 802.11 device state to reflect received capabilities field
1006 *
1007 * @v dev 802.11 device
1008 * @v capab Capabilities field in beacon, probe, or association frame
1009 * @ret rc Return status code
1010 */
1012 u16 capab )
1013{
1014 u16 old_phy = dev->phy_flags;
1015
1016 if ( ( capab & ( IEEE80211_CAPAB_MANAGED | IEEE80211_CAPAB_ADHOC ) ) !=
1018 DBGC ( dev, "802.11 %p cannot handle IBSS network\n", dev );
1019 return -ENOSYS;
1020 }
1021
1024
1025 if ( capab & IEEE80211_CAPAB_SHORT_PMBL )
1027
1028 if ( capab & IEEE80211_CAPAB_SHORT_SLOT )
1030
1031 if ( old_phy != dev->phy_flags )
1032 dev->op->config ( dev, NET80211_CFG_PHY_PARAMS );
1033
1034 return 0;
1035}
1036
1037/**
1038 * Update 802.11 device state to reflect received information elements
1039 *
1040 * @v dev 802.11 device
1041 * @v ie Pointer to first information element
1042 * @v ie_end Pointer to tail of packet I/O buffer
1043 * @ret rc Return status code
1044 */
1045static int net80211_process_ie ( struct net80211_device *dev,
1046 union ieee80211_ie *ie, void *ie_end )
1047{
1048 u16 old_rate = dev->rates[dev->rate];
1049 u16 old_phy = dev->phy_flags;
1050 int have_rates = 0, i;
1051 int ds_channel = 0;
1052 int changed = 0;
1053 int band = dev->channels[dev->channel].band;
1054
1055 if ( ! ieee80211_ie_bound ( ie, ie_end ) )
1056 return 0;
1057
1058 for ( ; ie; ie = ieee80211_next_ie ( ie, ie_end ) ) {
1059 switch ( ie->id ) {
1060 case IEEE80211_IE_SSID:
1061 if ( ie->len <= 32 ) {
1062 memcpy ( dev->essid, ie->ssid, ie->len );
1063 dev->essid[ie->len] = 0;
1064 }
1065 break;
1066
1067 case IEEE80211_IE_RATES:
1069 if ( ! have_rates ) {
1070 dev->nr_rates = 0;
1071 dev->basic_rates = 0;
1072 have_rates = 1;
1073 }
1074 for ( i = 0; i < ie->len &&
1075 dev->nr_rates < NET80211_MAX_RATES; i++ ) {
1076 u8 rid = ie->rates[i];
1077 u16 rate = ( rid & 0x7f ) * 5;
1078
1079 if ( rid & 0x80 )
1080 dev->basic_rates |=
1081 ( 1 << dev->nr_rates );
1082
1083 dev->rates[dev->nr_rates++] = rate;
1084 }
1085
1086 break;
1087
1089 if ( dev->channel < dev->nr_channels && ds_channel ==
1090 dev->channels[dev->channel].channel_nr )
1091 break;
1092 ds_channel = ie->ds_param.current_channel;
1093 net80211_change_channel ( dev, ds_channel );
1094 break;
1095
1097 dev->nr_channels = 0;
1098
1099 DBGC ( dev, "802.11 %p setting country regulations "
1100 "for %c%c\n", dev, ie->country.name[0],
1101 ie->country.name[1] );
1102 for ( i = 0; i < ( ie->len - 3 ) / 3; i++ ) {
1104 &ie->country.triplet[i];
1105 if ( t->first > 200 ) {
1106 DBGC ( dev, "802.11 %p ignoring regulatory "
1107 "extension information\n", dev );
1108 } else {
1111 t->band.nr_channels,
1112 t->band.max_txpower );
1113 }
1114 }
1116 break;
1117
1123 if ( ! ( ie->erp_info & IEEE80211_ERP_BARKER_LONG ) )
1125 break;
1126 }
1127 }
1128
1129 if ( have_rates ) {
1130 /* Allow only those rates that are also supported by
1131 the hardware. */
1132 int delta = 0, j;
1133
1134 dev->rate = 0;
1135 for ( i = 0; i < dev->nr_rates; i++ ) {
1136 int ok = 0;
1137 for ( j = 0; j < dev->hw->nr_rates[band]; j++ ) {
1138 if ( dev->hw->rates[band][j] == dev->rates[i] ){
1139 ok = 1;
1140 break;
1141 }
1142 }
1143
1144 if ( ! ok )
1145 delta++;
1146 else {
1147 dev->rates[i - delta] = dev->rates[i];
1148 if ( old_rate == dev->rates[i] )
1149 dev->rate = i - delta;
1150 }
1151 }
1152
1153 dev->nr_rates -= delta;
1154
1155 /* Sort available rates - sorted subclumps tend to already
1156 exist, so insertion sort works well. */
1157 for ( i = 1; i < dev->nr_rates; i++ ) {
1158 u16 rate = dev->rates[i];
1159 u32 tmp, br, mask;
1160
1161 for ( j = i - 1; j >= 0 && dev->rates[j] >= rate; j-- )
1162 dev->rates[j + 1] = dev->rates[j];
1163 dev->rates[j + 1] = rate;
1164
1165 /* Adjust basic_rates to match by rotating the
1166 bits from bit j+1 to bit i left one position. */
1167 mask = ( ( 1 << i ) - 1 ) & ~( ( 1 << ( j + 1 ) ) - 1 );
1168 br = dev->basic_rates;
1169 tmp = br & ( 1 << i );
1170 br = ( br & ~( mask | tmp ) ) | ( ( br & mask ) << 1 );
1171 br |= ( tmp >> ( i - j - 1 ) );
1172 dev->basic_rates = br;
1173 }
1174
1176
1177 if ( dev->rates[dev->rate] != old_rate )
1178 changed |= NET80211_CFG_RATE;
1179 }
1180
1181 if ( dev->hw->flags & NET80211_HW_NO_SHORT_PREAMBLE )
1183 if ( dev->hw->flags & NET80211_HW_NO_SHORT_SLOT )
1185
1186 if ( old_phy != dev->phy_flags )
1187 changed |= NET80211_CFG_PHY_PARAMS;
1188
1189 if ( changed )
1190 dev->op->config ( dev, changed );
1191
1192 return 0;
1193}
1194
1195/**
1196 * Create information elements for outgoing probe or association packet
1197 *
1198 * @v dev 802.11 device
1199 * @v ie Pointer to start of information element area
1200 * @ret next_ie Pointer to first byte after added information elements
1201 */
1202static union ieee80211_ie *
1204 union ieee80211_ie *ie )
1205{
1206 int i;
1207
1208 ie->id = IEEE80211_IE_SSID;
1209 ie->len = strlen ( dev->essid );
1210 memcpy ( ie->ssid, dev->essid, ie->len );
1211
1212 ie = ieee80211_next_ie ( ie, NULL );
1213
1214 ie->id = IEEE80211_IE_RATES;
1215 ie->len = dev->nr_rates;
1216 if ( ie->len > 8 )
1217 ie->len = 8;
1218
1219 for ( i = 0; i < ie->len; i++ ) {
1220 ie->rates[i] = dev->rates[i] / 5;
1221 if ( dev->basic_rates & ( 1 << i ) )
1222 ie->rates[i] |= 0x80;
1223 }
1224
1225 ie = ieee80211_next_ie ( ie, NULL );
1226
1227 if ( dev->rsn_ie && dev->rsn_ie->id == IEEE80211_IE_RSN ) {
1228 memcpy ( ie, dev->rsn_ie, dev->rsn_ie->len + 2 );
1229 ie = ieee80211_next_ie ( ie, NULL );
1230 }
1231
1232 if ( dev->nr_rates > 8 ) {
1233 /* 802.11 requires we use an Extended Basic Rates IE
1234 for the rates beyond the eighth. */
1235
1237 ie->len = dev->nr_rates - 8;
1238
1239 for ( ; i < dev->nr_rates; i++ ) {
1240 ie->rates[i - 8] = dev->rates[i] / 5;
1241 if ( dev->basic_rates & ( 1 << i ) )
1242 ie->rates[i - 8] |= 0x80;
1243 }
1244
1245 ie = ieee80211_next_ie ( ie, NULL );
1246 }
1247
1248 if ( dev->rsn_ie && dev->rsn_ie->id == IEEE80211_IE_VENDOR ) {
1249 memcpy ( ie, dev->rsn_ie, dev->rsn_ie->len + 2 );
1250 ie = ieee80211_next_ie ( ie, NULL );
1251 }
1252
1253 return ie;
1254}
1255
1256/** Seconds to wait after finding a network, to possibly find better APs for it
1257 *
1258 * This is used when a specific SSID to scan for is specified.
1259 */
1260#define NET80211_PROBE_GATHER 1
1261
1262/** Seconds to wait after finding a network, to possibly find other networks
1263 *
1264 * This is used when an empty SSID is specified, to scan for all
1265 * networks.
1266 */
1267#define NET80211_PROBE_GATHER_ALL 2
1268
1269/** Seconds to allow a probe to take if no network has been found */
1270#define NET80211_PROBE_TIMEOUT 6
1271
1272/**
1273 * Begin probe of 802.11 networks
1274 *
1275 * @v dev 802.11 device
1276 * @v essid SSID to probe for, or "" to accept any (may not be NULL)
1277 * @v active Whether to use active scanning
1278 * @ret ctx Probe context
1279 *
1280 * Active scanning may only be used on channels 1-11 in the 2.4GHz
1281 * band, due to iPXE's lack of a complete regulatory database. If
1282 * active scanning is used, probe packets will be sent on each
1283 * channel; this can allow association with hidden-SSID networks if
1284 * the SSID is properly specified.
1285 *
1286 * A @c NULL return indicates an out-of-memory condition.
1287 *
1288 * The returned context must be periodically passed to
1289 * net80211_probe_step() until that function returns zero.
1290 */
1292 const char *essid,
1293 int active )
1294{
1295 struct net80211_probe_ctx *ctx = zalloc ( sizeof ( *ctx ) );
1296
1297 if ( ! ctx )
1298 return NULL;
1299
1301
1302 ctx->dev = dev;
1303 ctx->old_keep_mgmt = net80211_keep_mgmt ( dev, 1 );
1304 ctx->essid = essid;
1305 if ( dev->essid != ctx->essid )
1306 strcpy ( dev->essid, ctx->essid );
1307
1308 if ( active ) {
1309 struct ieee80211_probe_req *probe_req;
1310 union ieee80211_ie *ie;
1311
1312 ctx->probe = alloc_iob ( 128 );
1314 probe_req = ctx->probe->data;
1315
1317 probe_req->info_element );
1318
1319 iob_put ( ctx->probe, ( void * ) ie - ctx->probe->data );
1320 }
1321
1322 ctx->ticks_start = currticks();
1323 ctx->ticks_beacon = 0;
1324 ctx->ticks_channel = currticks();
1325 ctx->hop_time = TICKS_PER_SEC / ( active ? 2 : 6 );
1326
1327 /*
1328 * Channels on 2.4GHz overlap, and the most commonly used
1329 * are 1, 6, and 11. We'll get a result faster if we check
1330 * every 5 channels, but in order to hit all of them the
1331 * number of channels must be relatively prime to 5. If it's
1332 * not, tweak the hop.
1333 */
1334 ctx->hop_step = 5;
1335 while ( dev->nr_channels % ctx->hop_step == 0 && ctx->hop_step > 1 )
1336 ctx->hop_step--;
1337
1338 ctx->beacons = malloc ( sizeof ( *ctx->beacons ) );
1339 INIT_LIST_HEAD ( ctx->beacons );
1340
1341 dev->channel = 0;
1342 dev->op->config ( dev, NET80211_CFG_CHANNEL );
1343
1344 return ctx;
1345}
1346
1347/**
1348 * Continue probe of 802.11 networks
1349 *
1350 * @v ctx Probe context returned by net80211_probe_start()
1351 * @ret rc Probe status
1352 *
1353 * The return code will be 0 if the probe is still going on (and this
1354 * function should be called again), a positive number if the probe
1355 * completed successfully, or a negative error code if the probe
1356 * failed for that reason.
1357 *
1358 * Whether the probe succeeded or failed, you must call
1359 * net80211_probe_finish_all() or net80211_probe_finish_best()
1360 * (depending on whether you want information on all networks or just
1361 * the best-signal one) in order to release the probe context. A
1362 * failed probe may still have acquired some valid data.
1363 */
1365{
1366 struct net80211_device *dev = ctx->dev;
1367 u32 start_timeout = NET80211_PROBE_TIMEOUT * TICKS_PER_SEC;
1368 u32 gather_timeout = TICKS_PER_SEC;
1369 u32 now = currticks();
1370 struct io_buffer *iob;
1371 int signal;
1372 int rc;
1373 char ssid[IEEE80211_MAX_SSID_LEN + 1];
1374
1375 gather_timeout *= ( ctx->essid[0] ? NET80211_PROBE_GATHER :
1377
1378 /* Time out if necessary */
1379 if ( now >= ctx->ticks_start + start_timeout )
1380 return list_empty ( ctx->beacons ) ? -ETIMEDOUT : +1;
1381
1382 if ( ctx->ticks_beacon > 0 && now >= ctx->ticks_start + gather_timeout )
1383 return +1;
1384
1385 /* Change channels if necessary */
1386 if ( now >= ctx->ticks_channel + ctx->hop_time ) {
1387 dev->channel = ( dev->channel + ctx->hop_step )
1388 % dev->nr_channels;
1389 dev->op->config ( dev, NET80211_CFG_CHANNEL );
1390 udelay ( dev->hw->channel_change_time );
1391
1392 ctx->ticks_channel = now;
1393
1394 if ( ctx->probe ) {
1395 struct io_buffer *siob = ctx->probe; /* to send */
1396
1397 /* make a copy for future use */
1398 iob = alloc_iob ( siob->tail - siob->head );
1399 iob_reserve ( iob, iob_headroom ( siob ) );
1400 memcpy ( iob_put ( iob, iob_len ( siob ) ),
1401 siob->data, iob_len ( siob ) );
1402
1403 ctx->probe = iob;
1406 iob_disown ( siob ) );
1407 if ( rc ) {
1408 DBGC ( dev, "802.11 %p send probe failed: "
1409 "%s\n", dev, strerror ( rc ) );
1410 return rc;
1411 }
1412 }
1413 }
1414
1415 /* Check for new management packets */
1416 while ( ( iob = net80211_mgmt_dequeue ( dev, &signal ) ) != NULL ) {
1417 struct ieee80211_frame *hdr;
1418 struct ieee80211_beacon *beacon;
1419 union ieee80211_ie *ie;
1420 struct net80211_wlan *wlan;
1421 u16 type;
1422
1423 hdr = iob->data;
1425 beacon = ( struct ieee80211_beacon * ) hdr->data;
1426
1427 if ( type != IEEE80211_STYPE_BEACON &&
1429 DBGC2 ( dev, "802.11 %p probe: non-beacon\n", dev );
1430 goto drop;
1431 }
1432
1433 if ( ( void * ) beacon->info_element >= iob->tail ) {
1434 DBGC ( dev, "802.11 %p probe: beacon with no IEs\n",
1435 dev );
1436 goto drop;
1437 }
1438
1439 ie = beacon->info_element;
1440
1441 if ( ! ieee80211_ie_bound ( ie, iob->tail ) )
1442 ie = NULL;
1443
1444 while ( ie && ie->id != IEEE80211_IE_SSID )
1445 ie = ieee80211_next_ie ( ie, iob->tail );
1446
1447 if ( ! ie ) {
1448 DBGC ( dev, "802.11 %p probe: beacon with no SSID\n",
1449 dev );
1450 goto drop;
1451 }
1452
1453 memcpy ( ssid, ie->ssid, ie->len );
1454 ssid[ie->len] = 0;
1455
1456 if ( ctx->essid[0] && strcmp ( ctx->essid, ssid ) != 0 ) {
1457 DBGC2 ( dev, "802.11 %p probe: beacon with wrong SSID "
1458 "(%s)\n", dev, ssid );
1459 goto drop;
1460 }
1461
1462 /* See if we've got an entry for this network */
1463 list_for_each_entry ( wlan, ctx->beacons, list ) {
1464 if ( strcmp ( wlan->essid, ssid ) != 0 )
1465 continue;
1466
1467 if ( signal < wlan->signal ) {
1468 DBGC2 ( dev, "802.11 %p probe: beacon for %s "
1469 "(%s) with weaker signal %d\n", dev,
1470 ssid, eth_ntoa ( hdr->addr3 ), signal );
1471 goto drop;
1472 }
1473
1474 goto fill;
1475 }
1476
1477 /* No entry yet - make one */
1478 wlan = zalloc ( sizeof ( *wlan ) );
1479 strcpy ( wlan->essid, ssid );
1480 list_add_tail ( &wlan->list, ctx->beacons );
1481
1482 /* Whether we're using an old entry or a new one, fill
1483 it with new data. */
1484 fill:
1485 memcpy ( wlan->bssid, hdr->addr3, ETH_ALEN );
1486 wlan->signal = signal;
1487 wlan->channel = dev->channels[dev->channel].channel_nr;
1488
1489 /* Copy this I/O buffer into a new wlan->beacon; the
1490 * iob we've got probably came from the device driver
1491 * and may have the full 2.4k allocation, which we
1492 * don't want to keep around wasting memory.
1493 */
1494 free_iob ( wlan->beacon );
1495 wlan->beacon = alloc_iob ( iob_len ( iob ) );
1496 memcpy ( iob_put ( wlan->beacon, iob_len ( iob ) ),
1497 iob->data, iob_len ( iob ) );
1498
1499 if ( ( rc = sec80211_detect ( wlan->beacon, &wlan->handshaking,
1500 &wlan->crypto ) ) == -ENOTSUP ) {
1501 struct ieee80211_beacon *beacon =
1502 ( struct ieee80211_beacon * ) hdr->data;
1503
1504 if ( beacon->capability & IEEE80211_CAPAB_PRIVACY ) {
1505 DBG ( "802.11 %p probe: secured network %s but "
1506 "encryption support not compiled in\n",
1507 dev, wlan->essid );
1510 } else {
1513 }
1514 } else if ( rc != 0 ) {
1515 DBGC ( dev, "802.11 %p probe warning: network "
1516 "%s with unidentifiable security "
1517 "settings: %s\n", dev, wlan->essid,
1518 strerror ( rc ) );
1519 }
1520
1521 ctx->ticks_beacon = now;
1522
1523 DBGC2 ( dev, "802.11 %p probe: good beacon for %s (%s)\n",
1524 dev, wlan->essid, eth_ntoa ( wlan->bssid ) );
1525
1526 drop:
1527 free_iob ( iob );
1528 }
1529
1530 return 0;
1531}
1532
1533
1534/**
1535 * Finish probe of 802.11 networks, returning best-signal network found
1536 *
1537 * @v ctx Probe context
1538 * @ret wlan Best-signal network found, or @c NULL if none were found
1539 *
1540 * If net80211_probe_start() was called with a particular SSID
1541 * parameter as filter, only a network with that SSID (matching
1542 * case-sensitively) can be returned from this function.
1543 */
1544struct net80211_wlan *
1546{
1547 struct net80211_wlan *best = NULL, *wlan;
1548
1549 if ( ! ctx )
1550 return NULL;
1551
1552 list_for_each_entry ( wlan, ctx->beacons, list ) {
1553 if ( ! best || best->signal < wlan->signal )
1554 best = wlan;
1555 }
1556
1557 if ( best )
1558 list_del ( &best->list );
1559 else
1560 DBGC ( ctx->dev, "802.11 %p probe: found nothing for '%s'\n",
1561 ctx->dev, ctx->essid );
1562
1563 net80211_free_wlanlist ( ctx->beacons );
1564
1565 net80211_keep_mgmt ( ctx->dev, ctx->old_keep_mgmt );
1566
1567 if ( ctx->probe )
1568 free_iob ( ctx->probe );
1569
1570 free ( ctx );
1571
1572 return best;
1573}
1574
1575
1576/**
1577 * Finish probe of 802.11 networks, returning all networks found
1578 *
1579 * @v ctx Probe context
1580 * @ret list List of net80211_wlan detailing networks found
1581 *
1582 * If net80211_probe_start() was called with a particular SSID
1583 * parameter as filter, this will always return either an empty or a
1584 * one-element list.
1585 */
1587{
1588 struct list_head *beacons = ctx->beacons;
1589
1590 net80211_keep_mgmt ( ctx->dev, ctx->old_keep_mgmt );
1591
1592 if ( ctx->probe )
1593 free_iob ( ctx->probe );
1594
1595 free ( ctx );
1596
1597 return beacons;
1598}
1599
1600
1601/**
1602 * Free WLAN structure
1603 *
1604 * @v wlan WLAN structure to free
1605 */
1607{
1608 if ( wlan ) {
1609 free_iob ( wlan->beacon );
1610 free ( wlan );
1611 }
1612}
1613
1614
1615/**
1616 * Free list of WLAN structures
1617 *
1618 * @v list List of WLAN structures to free
1619 */
1621{
1622 struct net80211_wlan *wlan, *tmp;
1623
1624 if ( ! list )
1625 return;
1626
1628 list_del ( &wlan->list );
1629 net80211_free_wlan ( wlan );
1630 }
1631
1632 free ( list );
1633}
1634
1635
1636/** Number of ticks to wait for replies to association management frames */
1637#define ASSOC_TIMEOUT TICKS_PER_SEC
1638
1639/** Number of times to try sending a particular association management frame */
1640#define ASSOC_RETRIES 2
1641
1642/**
1643 * Step 802.11 association process
1644 *
1645 * @v dev 802.11 device
1646 */
1647static void net80211_step_associate ( struct net80211_device *dev )
1648{
1649 int rc = 0;
1650 int status = dev->state & NET80211_STATUS_MASK;
1651
1652 /*
1653 * We use a sort of state machine implemented using bits in
1654 * the dev->state variable. At each call, we take the
1655 * logically first step that has not yet succeeded; either it
1656 * has not been tried yet, it's being retried, or it failed.
1657 * If it failed, we return an error indication; otherwise we
1658 * perform the step. If it succeeds, RX handling code will set
1659 * the appropriate status bit for us.
1660 *
1661 * Probe works a bit differently, since we have to step it
1662 * on every call instead of waiting for a packet to arrive
1663 * that will set the completion bit for us.
1664 */
1665
1666 /* If we're waiting for a reply, check for timeout condition */
1667 if ( dev->state & NET80211_WAITING ) {
1668 /* Sanity check */
1669 if ( ! dev->associating )
1670 return;
1671
1672 if ( currticks() - dev->ctx.assoc->last_packet > ASSOC_TIMEOUT ) {
1673 /* Timed out - fail if too many retries, or retry */
1674 dev->ctx.assoc->times_tried++;
1675 if ( ++dev->ctx.assoc->times_tried > ASSOC_RETRIES ) {
1676 rc = -ETIMEDOUT;
1677 goto fail;
1678 }
1679 } else {
1680 /* Didn't time out - let it keep going */
1681 return;
1682 }
1683 } else {
1684 if ( dev->state & NET80211_PROBED )
1685 dev->ctx.assoc->times_tried = 0;
1686 }
1687
1688 if ( ! ( dev->state & NET80211_PROBED ) ) {
1689 /* state: probe */
1690
1691 if ( ! dev->ctx.probe ) {
1692 /* start probe */
1693 int active = fetch_intz_setting ( NULL,
1694 &net80211_active_setting );
1695 int band = dev->hw->bands;
1696
1697 if ( active )
1699
1700 rc = net80211_prepare_probe ( dev, band, active );
1701 if ( rc )
1702 goto fail;
1703
1704 dev->ctx.probe = net80211_probe_start ( dev, dev->essid,
1705 active );
1706 if ( ! dev->ctx.probe ) {
1707 dev->assoc_rc = -ENOMEM;
1708 goto fail;
1709 }
1710 }
1711
1712 rc = net80211_probe_step ( dev->ctx.probe );
1713 if ( ! rc ) {
1714 return; /* still going */
1715 }
1716
1718 dev->ctx.probe = NULL;
1719 if ( ! dev->associating ) {
1720 if ( rc > 0 ) /* "successful" probe found nothing */
1721 rc = -ETIMEDOUT;
1722 goto fail;
1723 }
1724
1725 /* If we probed using a broadcast SSID, record that
1726 fact for the settings applicator before we clobber
1727 it with the specific SSID we've chosen. */
1728 if ( ! dev->essid[0] )
1729 dev->state |= NET80211_AUTO_SSID;
1730
1731 DBGC ( dev, "802.11 %p found network %s (%s)\n", dev,
1732 dev->associating->essid,
1733 eth_ntoa ( dev->associating->bssid ) );
1734
1735 dev->ctx.assoc = zalloc ( sizeof ( *dev->ctx.assoc ) );
1736 if ( ! dev->ctx.assoc ) {
1737 rc = -ENOMEM;
1738 goto fail;
1739 }
1740
1741 dev->state |= NET80211_PROBED;
1743
1744 return;
1745 }
1746
1747 /* Record time of sending the packet we're about to send, for timeout */
1748 dev->ctx.assoc->last_packet = currticks();
1749
1750 if ( ! ( dev->state & NET80211_AUTHENTICATED ) ) {
1751 /* state: prepare and authenticate */
1752
1754 /* we tried authenticating already, but failed */
1755 int method = dev->ctx.assoc->method;
1756
1760 /* Maybe this network uses Shared Key? */
1761 dev->ctx.assoc->method =
1763 } else {
1764 goto fail;
1765 }
1766 }
1767
1768 DBGC ( dev, "802.11 %p authenticating with method %d\n", dev,
1769 dev->ctx.assoc->method );
1770
1771 rc = net80211_prepare_assoc ( dev, dev->associating );
1772 if ( rc )
1773 goto fail;
1774
1775 rc = net80211_send_auth ( dev, dev->associating,
1776 dev->ctx.assoc->method );
1777 if ( rc )
1778 goto fail;
1779
1780 return;
1781 }
1782
1783 if ( ! ( dev->state & NET80211_ASSOCIATED ) ) {
1784 /* state: associate */
1785
1787 goto fail;
1788
1789 DBGC ( dev, "802.11 %p associating\n", dev );
1790
1791 if ( dev->handshaker && dev->handshaker->start &&
1792 ! dev->handshaker->started ) {
1793 rc = dev->handshaker->start ( dev );
1794 if ( rc < 0 )
1795 goto fail;
1796 dev->handshaker->started = 1;
1797 }
1798
1799 rc = net80211_send_assoc ( dev, dev->associating );
1800 if ( rc )
1801 goto fail;
1802
1803 return;
1804 }
1805
1806 if ( ! ( dev->state & NET80211_CRYPTO_SYNCED ) ) {
1807 /* state: crypto sync */
1808 DBGC ( dev, "802.11 %p security handshaking\n", dev );
1809
1810 if ( ! dev->handshaker || ! dev->handshaker->step ) {
1812 return;
1813 }
1814
1815 rc = dev->handshaker->step ( dev );
1816
1817 if ( rc < 0 ) {
1818 /* Only record the returned error if we're
1819 still marked as associated, because an
1820 asynchronous error will have already been
1821 reported to net80211_deauthenticate() and
1822 assoc_rc thereby set. */
1823 if ( dev->state & NET80211_ASSOCIATED )
1824 dev->assoc_rc = rc;
1825 rc = 0;
1826 goto fail;
1827 }
1828
1829 if ( rc > 0 ) {
1830 dev->assoc_rc = 0;
1832 }
1833 return;
1834 }
1835
1836 /* state: done! */
1837 netdev_link_up ( dev->netdev );
1838 dev->assoc_rc = 0;
1839 dev->state &= ~NET80211_WORKING;
1840
1841 free ( dev->ctx.assoc );
1842 dev->ctx.assoc = NULL;
1843
1845 dev->associating = NULL;
1846
1847 dev->rctl = rc80211_init ( dev );
1848
1849 process_del ( &dev->proc_assoc );
1850
1851 DBGC ( dev, "802.11 %p associated with %s (%s)\n", dev,
1852 dev->essid, eth_ntoa ( dev->bssid ) );
1853
1854 return;
1855
1856 fail:
1858 if ( rc )
1859 dev->assoc_rc = rc;
1860
1861 netdev_link_err ( dev->netdev, dev->assoc_rc );
1862
1863 /* We never reach here from the middle of a probe, so we don't
1864 need to worry about freeing dev->ctx.probe. */
1865
1866 if ( dev->state & NET80211_PROBED ) {
1867 free ( dev->ctx.assoc );
1868 dev->ctx.assoc = NULL;
1869 }
1870
1872 dev->associating = NULL;
1873
1874 process_del ( &dev->proc_assoc );
1875
1876 DBGC ( dev, "802.11 %p association failed (state=%04x): "
1877 "%s\n", dev, dev->state, strerror ( dev->assoc_rc ) );
1878
1879 /* Try it again: */
1880 net80211_autoassociate ( dev );
1881}
1882
1883/**
1884 * Check for 802.11 SSID or key updates
1885 *
1886 * This acts as a settings applicator; if the user changes netX/ssid,
1887 * and netX is currently open, the association task will be invoked
1888 * again. If the user changes the encryption key, the current security
1889 * handshaker will be asked to update its state to match; if that is
1890 * impossible without reassociation, we reassociate.
1891 */
1893{
1894 struct net80211_device *dev;
1895 char ssid[IEEE80211_MAX_SSID_LEN + 1];
1896 int key_reassoc;
1897
1899 if ( ! netdev_is_open ( dev->netdev ) )
1900 continue;
1901
1902 key_reassoc = 0;
1903 if ( dev->handshaker && dev->handshaker->change_key &&
1904 dev->handshaker->change_key ( dev ) < 0 )
1905 key_reassoc = 1;
1906
1908 &net80211_ssid_setting, ssid,
1910
1911 if ( key_reassoc ||
1912 ( ! ( ! ssid[0] && ( dev->state & NET80211_AUTO_SSID ) ) &&
1913 strcmp ( ssid, dev->essid ) != 0 ) ) {
1914 DBGC ( dev, "802.11 %p updating association: "
1915 "%s -> %s\n", dev, dev->essid, ssid );
1916 net80211_autoassociate ( dev );
1917 }
1918 }
1919
1920 return 0;
1921}
1922
1923/**
1924 * Start 802.11 association process
1925 *
1926 * @v dev 802.11 device
1927 *
1928 * If the association process is running, it will be restarted.
1929 */
1931{
1932 if ( ! ( dev->state & NET80211_WORKING ) ) {
1933 DBGC2 ( dev, "802.11 %p spawning association process\n", dev );
1934 process_add ( &dev->proc_assoc );
1935 } else {
1936 DBGC2 ( dev, "802.11 %p restarting association\n", dev );
1937 }
1938
1939 /* Clean up everything an earlier association process might
1940 have been in the middle of using */
1941 if ( dev->associating )
1943
1944 if ( ! ( dev->state & NET80211_PROBED ) )
1947 else
1948 free ( dev->ctx.assoc );
1949
1950 /* Reset to a clean state */
1952 &net80211_ssid_setting, dev->essid,
1954 dev->ctx.probe = NULL;
1955 dev->associating = NULL;
1956 dev->assoc_rc = 0;
1958}
1959
1960/**
1961 * Pick TX rate for RTS/CTS packets based on data rate
1962 *
1963 * @v dev 802.11 device
1964 *
1965 * The RTS/CTS rate is the fastest TX rate marked as "basic" that is
1966 * not faster than the data rate.
1967 */
1969{
1970 u16 datarate = dev->rates[dev->rate];
1971 u16 rtsrate = 0;
1972 int rts_idx = -1;
1973 int i;
1974
1975 for ( i = 0; i < dev->nr_rates; i++ ) {
1976 u16 rate = dev->rates[i];
1977
1978 if ( ! ( dev->basic_rates & ( 1 << i ) ) || rate > datarate )
1979 continue;
1980
1981 if ( rate > rtsrate ) {
1982 rtsrate = rate;
1983 rts_idx = i;
1984 }
1985 }
1986
1987 /* If this is in initialization, we might not have any basic
1988 rates; just use the first data rate in that case. */
1989 if ( rts_idx < 0 )
1990 rts_idx = 0;
1991
1992 dev->rtscts_rate = rts_idx;
1993}
1994
1995/**
1996 * Set data transmission rate for 802.11 device
1997 *
1998 * @v dev 802.11 device
1999 * @v rate Rate to set, as index into @c dev->rates array
2000 */
2002{
2003 assert ( netdev_is_open ( dev->netdev ) );
2004
2005 if ( rate >= 0 && rate < dev->nr_rates && rate != dev->rate ) {
2006 DBGC2 ( dev, "802.11 %p changing rate from %d->%d Mbps\n",
2007 dev, dev->rates[dev->rate] / 10,
2008 dev->rates[rate] / 10 );
2009
2010 dev->rate = rate;
2012 dev->op->config ( dev, NET80211_CFG_RATE );
2013 }
2014}
2015
2016/**
2017 * Configure 802.11 device to transmit on a certain channel
2018 *
2019 * @v dev 802.11 device
2020 * @v channel Channel number (1-11 for 2.4GHz) to transmit on
2021 */
2023{
2024 int i, oldchan = dev->channel;
2025
2026 assert ( netdev_is_open ( dev->netdev ) );
2027
2028 for ( i = 0; i < dev->nr_channels; i++ ) {
2029 if ( dev->channels[i].channel_nr == channel ) {
2030 dev->channel = i;
2031 break;
2032 }
2033 }
2034
2035 if ( i == dev->nr_channels )
2036 return -ENOENT;
2037
2038 if ( i != oldchan )
2039 return dev->op->config ( dev, NET80211_CFG_CHANNEL );
2040
2041 return 0;
2042}
2043
2044/**
2045 * Prepare 802.11 device channel and rate set for scanning
2046 *
2047 * @v dev 802.11 device
2048 * @v band RF band(s) on which to prepare for scanning
2049 * @v active Whether the scanning will be active
2050 * @ret rc Return status code
2051 */
2052int net80211_prepare_probe ( struct net80211_device *dev, int band,
2053 int active )
2054{
2055 assert ( netdev_is_open ( dev->netdev ) );
2056
2057 if ( active && ( band & NET80211_BAND_BIT_5GHZ ) ) {
2058 DBGC ( dev, "802.11 %p cannot perform active scanning on "
2059 "5GHz band\n", dev );
2060 return -EINVAL_ACTIVE_SCAN;
2061 }
2062
2063 if ( band == 0 ) {
2064 /* This can happen for a 5GHz-only card with 5GHz
2065 scanning masked out by an active request. */
2066 DBGC ( dev, "802.11 %p asked to prepare for scanning nothing\n",
2067 dev );
2068 return -EINVAL_ACTIVE_SCAN;
2069 }
2070
2071 dev->nr_channels = 0;
2072
2073 if ( active )
2075 else {
2076 if ( band & NET80211_BAND_BIT_2GHZ )
2077 net80211_add_channels ( dev, 1, 14,
2079 if ( band & NET80211_BAND_BIT_5GHZ )
2080 net80211_add_channels ( dev, 36, 8,
2082 }
2083
2085
2086 /* Use channel 1 for now */
2087 dev->channel = 0;
2088 dev->op->config ( dev, NET80211_CFG_CHANNEL );
2089
2090 /* Always do active probes at lowest (presumably first) speed */
2091 dev->rate = 0;
2092 dev->nr_rates = 1;
2093 dev->rates[0] = dev->hw->rates[dev->channels[0].band][0];
2094 dev->op->config ( dev, NET80211_CFG_RATE );
2095
2096 return 0;
2097}
2098
2099/**
2100 * Prepare 802.11 device channel and rate set for communication
2101 *
2102 * @v dev 802.11 device
2103 * @v wlan WLAN to prepare for communication with
2104 * @ret rc Return status code
2105 */
2107 struct net80211_wlan *wlan )
2108{
2109 struct ieee80211_frame *hdr = wlan->beacon->data;
2110 struct ieee80211_beacon *beacon =
2111 ( struct ieee80211_beacon * ) hdr->data;
2112 struct net80211_handshaker *handshaker;
2113 int rc;
2114
2115 assert ( netdev_is_open ( dev->netdev ) );
2116
2118 memcpy ( dev->bssid, wlan->bssid, ETH_ALEN );
2119 strcpy ( dev->essid, wlan->essid );
2120
2121 free ( dev->rsn_ie );
2122 dev->rsn_ie = NULL;
2123
2124 dev->last_beacon_timestamp = beacon->timestamp;
2125 dev->tx_beacon_interval = 1024 * beacon->beacon_interval;
2126
2127 /* Barring an IE that tells us the channel outright, assume
2128 the channel we heard this AP best on is the channel it's
2129 communicating on. */
2130 net80211_change_channel ( dev, wlan->channel );
2131
2132 rc = net80211_process_capab ( dev, beacon->capability );
2133 if ( rc )
2134 return rc;
2135
2136 rc = net80211_process_ie ( dev, beacon->info_element,
2137 wlan->beacon->tail );
2138 if ( rc )
2139 return rc;
2140
2141 /* Associate at the lowest rate so we know it'll get through */
2142 dev->rate = 0;
2143 dev->op->config ( dev, NET80211_CFG_RATE );
2144
2145 /* Free old handshaker and crypto, if they exist */
2146 if ( dev->handshaker && dev->handshaker->stop &&
2147 dev->handshaker->started )
2148 dev->handshaker->stop ( dev );
2149 free ( dev->handshaker );
2150 dev->handshaker = NULL;
2151 free ( dev->crypto );
2152 free ( dev->gcrypto );
2153 dev->crypto = dev->gcrypto = NULL;
2154
2155 /* Find new security handshaker to use */
2157 if ( handshaker->protocol == wlan->handshaking ) {
2158 dev->handshaker = zalloc ( sizeof ( *handshaker ) +
2159 handshaker->priv_len );
2160 if ( ! dev->handshaker )
2161 return -ENOMEM;
2162
2163 memcpy ( dev->handshaker, handshaker,
2164 sizeof ( *handshaker ) );
2165 dev->handshaker->priv = ( ( void * ) dev->handshaker +
2166 sizeof ( *handshaker ) );
2167 break;
2168 }
2169 }
2170
2171 if ( ( wlan->handshaking != NET80211_SECPROT_NONE ) &&
2172 ! dev->handshaker ) {
2173 DBGC ( dev, "802.11 %p no support for handshaking scheme %d\n",
2174 dev, wlan->handshaking );
2175 return -( ENOTSUP | ( wlan->handshaking << 8 ) );
2176 }
2177
2178 /* Initialize security handshaker */
2179 if ( dev->handshaker ) {
2180 rc = dev->handshaker->init ( dev );
2181 if ( rc < 0 )
2182 return rc;
2183 }
2184
2185 return 0;
2186}
2187
2188/**
2189 * Send 802.11 initial authentication frame
2190 *
2191 * @v dev 802.11 device
2192 * @v wlan WLAN to authenticate with
2193 * @v method Authentication method
2194 * @ret rc Return status code
2195 *
2196 * @a method may be 0 for Open System authentication or 1 for Shared
2197 * Key authentication. Open System provides no security in association
2198 * whatsoever, relying on encryption for confidentiality, but Shared
2199 * Key actively introduces security problems and is very rarely used.
2200 */
2202 struct net80211_wlan *wlan, int method )
2203{
2204 struct io_buffer *iob = alloc_iob ( 64 );
2205 struct ieee80211_auth *auth;
2206
2207 net80211_set_state ( dev, 0, NET80211_WAITING, 0 );
2209 auth = iob_put ( iob, sizeof ( *auth ) );
2210 auth->algorithm = method;
2211 auth->tx_seq = 1;
2212 auth->status = 0;
2213
2214 return net80211_tx_mgmt ( dev, IEEE80211_STYPE_AUTH, wlan->bssid, iob );
2215}
2216
2217/**
2218 * Handle receipt of 802.11 authentication frame
2219 *
2220 * @v dev 802.11 device
2221 * @v iob I/O buffer
2222 *
2223 * If the authentication method being used is Shared Key, and the
2224 * frame that was received included challenge text, the frame is
2225 * encrypted using the cryptosystem currently in effect and sent back
2226 * to the AP to complete the authentication.
2227 */
2228static void net80211_handle_auth ( struct net80211_device *dev,
2229 struct io_buffer *iob )
2230{
2231 struct ieee80211_frame *hdr = iob->data;
2232 struct ieee80211_auth *auth =
2233 ( struct ieee80211_auth * ) hdr->data;
2234
2235 if ( auth->tx_seq & 1 ) {
2236 DBGC ( dev, "802.11 %p authentication received improperly "
2237 "directed frame (seq. %d)\n", dev, auth->tx_seq );
2240 return;
2241 }
2242
2243 if ( auth->status != IEEE80211_STATUS_SUCCESS ) {
2244 DBGC ( dev, "802.11 %p authentication failed: status %d\n",
2245 dev, auth->status );
2247 auth->status );
2248 return;
2249 }
2250
2251 if ( auth->algorithm == IEEE80211_AUTH_SHARED_KEY && ! dev->crypto ) {
2252 DBGC ( dev, "802.11 %p can't perform shared-key authentication "
2253 "without a cryptosystem\n", dev );
2256 return;
2257 }
2258
2259 if ( auth->algorithm == IEEE80211_AUTH_SHARED_KEY &&
2260 auth->tx_seq == 2 ) {
2261 /* Since the iob we got is going to be freed as soon
2262 as we return, we can do some in-place
2263 modification. */
2264 auth->tx_seq = 3;
2265 auth->status = 0;
2266
2267 memcpy ( hdr->addr2, hdr->addr1, ETH_ALEN );
2268 memcpy ( hdr->addr1, hdr->addr3, ETH_ALEN );
2269
2270 netdev_tx ( dev->netdev,
2271 dev->crypto->encrypt ( dev->crypto, iob ) );
2272 return;
2273 }
2274
2277
2278 return;
2279}
2280
2281/**
2282 * Send 802.11 association frame
2283 *
2284 * @v dev 802.11 device
2285 * @v wlan WLAN to associate with
2286 * @ret rc Return status code
2287 */
2289 struct net80211_wlan *wlan )
2290{
2291 struct io_buffer *iob = alloc_iob ( 128 );
2292 struct ieee80211_assoc_req *assoc;
2293 union ieee80211_ie *ie;
2294
2295 net80211_set_state ( dev, 0, NET80211_WAITING, 0 );
2296
2298 assoc = iob->data;
2299
2301 if ( ! ( dev->hw->flags & NET80211_HW_NO_SHORT_PREAMBLE ) )
2303 if ( ! ( dev->hw->flags & NET80211_HW_NO_SHORT_SLOT ) )
2305 if ( wlan->crypto )
2307
2308 assoc->listen_interval = 1;
2309
2310 ie = net80211_marshal_request_info ( dev, assoc->info_element );
2311
2312 DBGP ( "802.11 %p about to send association request:\n", dev );
2313 DBGP_HD ( iob->data, ( void * ) ie - iob->data );
2314
2315 iob_put ( iob, ( void * ) ie - iob->data );
2316
2318 wlan->bssid, iob );
2319}
2320
2321/**
2322 * Handle receipt of 802.11 association reply frame
2323 *
2324 * @v dev 802.11 device
2325 * @v iob I/O buffer
2326 */
2328 struct io_buffer *iob )
2329{
2330 struct ieee80211_frame *hdr = iob->data;
2331 struct ieee80211_assoc_resp *assoc =
2332 ( struct ieee80211_assoc_resp * ) hdr->data;
2333
2334 net80211_process_capab ( dev, assoc->capability );
2335 net80211_process_ie ( dev, assoc->info_element, iob->tail );
2336
2337 if ( assoc->status != IEEE80211_STATUS_SUCCESS ) {
2338 DBGC ( dev, "802.11 %p association failed: status %d\n",
2339 dev, assoc->status );
2341 assoc->status );
2342 return;
2343 }
2344
2345 /* ESSID was filled before the association request was sent */
2346 memcpy ( dev->bssid, hdr->addr3, ETH_ALEN );
2347 dev->aid = assoc->aid;
2348
2351}
2352
2353
2354/**
2355 * Send 802.11 disassociation frame
2356 *
2357 * @v dev 802.11 device
2358 * @v reason Reason for disassociation
2359 * @v deauth If TRUE, send deauthentication instead of disassociation
2360 * @ret rc Return status code
2361 */
2362static int net80211_send_disassoc ( struct net80211_device *dev, int reason,
2363 int deauth )
2364{
2365 struct io_buffer *iob = alloc_iob ( 64 );
2366 struct ieee80211_disassoc *disassoc;
2367
2368 if ( ! ( dev->state & NET80211_ASSOCIATED ) )
2369 return -EINVAL;
2370
2373 disassoc = iob_put ( iob, sizeof ( *disassoc ) );
2374 disassoc->reason = reason;
2375
2376 return net80211_tx_mgmt ( dev, deauth ? IEEE80211_STYPE_DEAUTH :
2377 IEEE80211_STYPE_DISASSOC, dev->bssid, iob );
2378}
2379
2380
2381/**
2382 * Deauthenticate from current network and try again
2383 *
2384 * @v dev 802.11 device
2385 * @v rc Return status code indicating reason
2386 *
2387 * The deauthentication will be sent using an 802.11 "unspecified
2388 * reason", as is common, but @a rc will be set as a link-up
2389 * error to aid the user in debugging.
2390 */
2392{
2394 dev->assoc_rc = rc;
2395 netdev_link_err ( dev->netdev, rc );
2396
2397 net80211_autoassociate ( dev );
2398}
2399
2400
2401/** Smoothing factor (1-7) for link quality calculation */
2402#define LQ_SMOOTH 7
2403
2404/**
2405 * Update link quality information based on received beacon
2406 *
2407 * @v dev 802.11 device
2408 * @v iob I/O buffer containing beacon
2409 * @ret rc Return status code
2410 */
2412 struct io_buffer *iob )
2413{
2414 struct ieee80211_frame *hdr = iob->data;
2415 struct ieee80211_beacon *beacon;
2416 u32 dt, rxi;
2417
2418 if ( ! ( dev->state & NET80211_ASSOCIATED ) )
2419 return;
2420
2421 beacon = ( struct ieee80211_beacon * ) hdr->data;
2422 dt = ( u32 ) ( beacon->timestamp - dev->last_beacon_timestamp );
2423 rxi = dev->rx_beacon_interval;
2424
2425 rxi = ( LQ_SMOOTH * rxi ) + ( ( 8 - LQ_SMOOTH ) * dt );
2426 dev->rx_beacon_interval = rxi >> 3;
2427
2428 dev->last_beacon_timestamp = beacon->timestamp;
2429}
2430
2431
2432/**
2433 * Handle receipt of 802.11 management frame
2434 *
2435 * @v dev 802.11 device
2436 * @v iob I/O buffer
2437 * @v signal Signal strength of received frame
2438 */
2439static void net80211_handle_mgmt ( struct net80211_device *dev,
2440 struct io_buffer *iob, int signal )
2441{
2442 struct ieee80211_frame *hdr = iob->data;
2443 struct ieee80211_disassoc *disassoc;
2444 u16 stype = hdr->fc & IEEE80211_FC_SUBTYPE;
2445 int keep = 0;
2446 int is_deauth = ( stype == IEEE80211_STYPE_DEAUTH );
2447
2448 if ( ( hdr->fc & IEEE80211_FC_TYPE ) != IEEE80211_TYPE_MGMT ) {
2449 free_iob ( iob );
2450 return; /* only handle management frames */
2451 }
2452
2453 switch ( stype ) {
2454 /* We reconnect on deauthentication and disassociation. */
2457 disassoc = ( struct ieee80211_disassoc * ) hdr->data;
2458 net80211_set_state ( dev, is_deauth ? NET80211_AUTHENTICATED :
2460 NET80211_IS_REASON | disassoc->reason );
2461 DBGC ( dev, "802.11 %p %s: reason %d\n",
2462 dev, is_deauth ? "deauthenticated" : "disassociated",
2463 disassoc->reason );
2464
2465 /* Try to reassociate, in case it's transient. */
2466 net80211_autoassociate ( dev );
2467
2468 break;
2469
2470 /* We handle authentication and association. */
2472 if ( ! ( dev->state & NET80211_AUTHENTICATED ) )
2473 net80211_handle_auth ( dev, iob );
2474 break;
2475
2478 if ( ! ( dev->state & NET80211_ASSOCIATED ) )
2479 net80211_handle_assoc_reply ( dev, iob );
2480 break;
2481
2482 /* We pass probes and beacons onto network scanning
2483 code. Pass actions for future extensibility. */
2485 net80211_update_link_quality ( dev, iob );
2486 /* fall through */
2489 if ( dev->keep_mgmt ) {
2490 struct net80211_rx_info *rxinf;
2491 rxinf = zalloc ( sizeof ( *rxinf ) );
2492 if ( ! rxinf ) {
2493 DBGC ( dev, "802.11 %p out of memory\n", dev );
2494 break;
2495 }
2496 rxinf->signal = signal;
2497 list_add_tail ( &iob->list, &dev->mgmt_queue );
2498 list_add_tail ( &rxinf->list, &dev->mgmt_info_queue );
2499 keep = 1;
2500 }
2501 break;
2502
2504 /* Some nodes send these broadcast. Ignore them. */
2505 break;
2506
2509 /* We should never receive these, only send them. */
2510 DBGC ( dev, "802.11 %p received strange management request "
2511 "(%04x)\n", dev, stype );
2512 break;
2513
2514 default:
2515 DBGC ( dev, "802.11 %p received unimplemented management "
2516 "packet (%04x)\n", dev, stype );
2517 break;
2518 }
2519
2520 if ( ! keep )
2521 free_iob ( iob );
2522}
2523
2524/* ---------- Packet handling functions ---------- */
2525
2526/**
2527 * Free buffers used by 802.11 fragment cache entry
2528 *
2529 * @v dev 802.11 device
2530 * @v fcid Fragment cache entry index
2531 *
2532 * After this function, the referenced entry will be marked unused.
2533 */
2534static void net80211_free_frags ( struct net80211_device *dev, int fcid )
2535{
2536 int j;
2537 struct net80211_frag_cache *frag = &dev->frags[fcid];
2538
2539 for ( j = 0; j < 16; j++ ) {
2540 if ( frag->iob[j] ) {
2541 free_iob ( frag->iob[j] );
2542 frag->iob[j] = NULL;
2543 }
2544 }
2545
2546 frag->seqnr = 0;
2547 frag->start_ticks = 0;
2548 frag->in_use = 0;
2549}
2550
2551/**
2552 * Accumulate 802.11 fragments into one I/O buffer
2553 *
2554 * @v dev 802.11 device
2555 * @v fcid Fragment cache entry index
2556 * @v nfrags Number of fragments received
2557 * @v size Sum of sizes of all fragments, including headers
2558 * @ret iob I/O buffer containing reassembled packet
2559 *
2560 * This function does not free the fragment buffers.
2561 */
2563 int fcid, int nfrags, int size )
2564{
2565 struct net80211_frag_cache *frag = &dev->frags[fcid];
2566 int hdrsize = IEEE80211_TYP_FRAME_HEADER_LEN;
2567 int nsize = size - hdrsize * ( nfrags - 1 );
2568 int i;
2569
2570 struct io_buffer *niob = alloc_iob ( nsize );
2571 struct ieee80211_frame *hdr;
2572
2573 /* Add the header from the first one... */
2574 memcpy ( iob_put ( niob, hdrsize ), frag->iob[0]->data, hdrsize );
2575
2576 /* ... and all the data from all of them. */
2577 for ( i = 0; i < nfrags; i++ ) {
2578 int len = iob_len ( frag->iob[i] ) - hdrsize;
2579 memcpy ( iob_put ( niob, len ),
2580 frag->iob[i]->data + hdrsize, len );
2581 }
2582
2583 /* Turn off the fragment bit. */
2584 hdr = niob->data;
2586
2587 return niob;
2588}
2589
2590/**
2591 * Handle receipt of 802.11 fragment
2592 *
2593 * @v dev 802.11 device
2594 * @v iob I/O buffer containing fragment
2595 * @v signal Signal strength with which fragment was received
2596 */
2597static void net80211_rx_frag ( struct net80211_device *dev,
2598 struct io_buffer *iob, int signal )
2599{
2600 struct ieee80211_frame *hdr = iob->data;
2601 int fragnr = IEEE80211_FRAG ( hdr->seq );
2602
2603 if ( fragnr == 0 && ( hdr->fc & IEEE80211_FC_MORE_FRAG ) ) {
2604 /* start a frag cache entry */
2605 int i, newest = -1;
2606 u32 curr_ticks = currticks(), newest_ticks = 0;
2608
2609 for ( i = 0; i < NET80211_NR_CONCURRENT_FRAGS; i++ ) {
2610 if ( dev->frags[i].in_use == 0 )
2611 break;
2612
2613 if ( dev->frags[i].start_ticks + timeout >=
2614 curr_ticks ) {
2615 net80211_free_frags ( dev, i );
2616 break;
2617 }
2618
2619 if ( dev->frags[i].start_ticks > newest_ticks ) {
2620 newest = i;
2621 newest_ticks = dev->frags[i].start_ticks;
2622 }
2623 }
2624
2625 /* If we're being sent more concurrent fragmented
2626 packets than we can handle, drop the newest so the
2627 older ones have time to complete. */
2628 if ( i == NET80211_NR_CONCURRENT_FRAGS ) {
2629 i = newest;
2630 net80211_free_frags ( dev, i );
2631 }
2632
2633 dev->frags[i].in_use = 1;
2634 dev->frags[i].seqnr = IEEE80211_SEQNR ( hdr->seq );
2635 dev->frags[i].start_ticks = currticks();
2636 dev->frags[i].iob[0] = iob;
2637 return;
2638 } else {
2639 int i;
2640 for ( i = 0; i < NET80211_NR_CONCURRENT_FRAGS; i++ ) {
2641 if ( dev->frags[i].in_use && dev->frags[i].seqnr ==
2642 IEEE80211_SEQNR ( hdr->seq ) )
2643 break;
2644 }
2645 if ( i == NET80211_NR_CONCURRENT_FRAGS ) {
2646 /* Drop non-first not-in-cache fragments */
2647 DBGC ( dev, "802.11 %p dropped fragment fc=%04x "
2648 "seq=%04x\n", dev, hdr->fc, hdr->seq );
2649 free_iob ( iob );
2650 return;
2651 }
2652
2653 dev->frags[i].iob[fragnr] = iob;
2654
2655 if ( ! ( hdr->fc & IEEE80211_FC_MORE_FRAG ) ) {
2656 int j, size = 0;
2657 for ( j = 0; j < fragnr; j++ ) {
2658 size += iob_len ( dev->frags[i].iob[j] );
2659 if ( dev->frags[i].iob[j] == NULL )
2660 break;
2661 }
2662 if ( j == fragnr ) {
2663 /* We've got everything */
2664 struct io_buffer *niob =
2665 net80211_accum_frags ( dev, i, fragnr,
2666 size );
2667 net80211_free_frags ( dev, i );
2668 net80211_rx ( dev, niob, signal, 0 );
2669 } else {
2670 DBGC ( dev, "802.11 %p dropping fragmented "
2671 "packet due to out-of-order arrival, "
2672 "fc=%04x seq=%04x\n", dev, hdr->fc,
2673 hdr->seq );
2674 net80211_free_frags ( dev, i );
2675 }
2676 }
2677 }
2678}
2679
2680/**
2681 * Handle receipt of 802.11 frame
2682 *
2683 * @v dev 802.11 device
2684 * @v iob I/O buffer
2685 * @v signal Received signal strength
2686 * @v rate Bitrate at which frame was received, in 100 kbps units
2687 *
2688 * If the rate or signal is unknown, 0 should be passed.
2689 */
2690void net80211_rx ( struct net80211_device *dev, struct io_buffer *iob,
2691 int signal, u16 rate )
2692{
2693 struct ieee80211_frame *hdr = iob->data;
2694 u16 type = hdr->fc & IEEE80211_FC_TYPE;
2696 goto drop; /* drop invalid-version packets */
2697
2698 if ( type == IEEE80211_TYPE_CTRL )
2699 goto drop; /* we don't handle control packets,
2700 the hardware does */
2701
2702 if ( dev->last_rx_seq == hdr->seq )
2703 goto drop; /* avoid duplicate packet */
2704 dev->last_rx_seq = hdr->seq;
2705
2706 if ( dev->hw->flags & NET80211_HW_RX_HAS_FCS ) {
2707 /* discard the FCS */
2708 iob_unput ( iob, 4 );
2709 }
2710
2711 /* Only decrypt packets from our BSSID, to avoid spurious errors */
2712 if ( ( hdr->fc & IEEE80211_FC_PROTECTED ) &&
2713 ! memcmp ( hdr->addr2, dev->bssid, ETH_ALEN ) ) {
2714 /* Decrypt packet; record and drop if it fails */
2715 struct io_buffer *niob;
2716 struct net80211_crypto *crypto = dev->crypto;
2717
2718 if ( ! dev->crypto ) {
2719 DBGC ( dev, "802.11 %p cannot decrypt packet "
2720 "without a cryptosystem\n", dev );
2721 goto drop_crypt;
2722 }
2723
2724 if ( ( hdr->addr1[0] & 1 ) && dev->gcrypto ) {
2725 /* Use group decryption if needed */
2726 crypto = dev->gcrypto;
2727 }
2728
2729 niob = crypto->decrypt ( crypto, iob );
2730 if ( ! niob ) {
2731 DBGC ( dev, "802.11 %p decryption error\n", dev );
2732 goto drop_crypt;
2733 }
2734 free_iob ( iob );
2735 iob = niob;
2736 hdr = iob->data;
2737 }
2738
2739 dev->last_signal = signal;
2740
2741 /* Fragments go into the frag cache or get dropped. */
2742 if ( IEEE80211_FRAG ( hdr->seq ) != 0
2743 || ( hdr->fc & IEEE80211_FC_MORE_FRAG ) ) {
2744 net80211_rx_frag ( dev, iob, signal );
2745 return;
2746 }
2747
2748 /* Management frames get handled, enqueued, or dropped. */
2749 if ( type == IEEE80211_TYPE_MGMT ) {
2750 net80211_handle_mgmt ( dev, iob, signal );
2751 return;
2752 }
2753
2754 /* Data frames get dropped or sent to the net_device. */
2756 goto drop; /* drop QoS, CFP, or null data packets */
2757
2758 /* Update rate-control algorithm */
2759 if ( dev->rctl )
2760 rc80211_update_rx ( dev, hdr->fc & IEEE80211_FC_RETRY, rate );
2761
2762 /* Pass packet onward */
2763 if ( dev->state & NET80211_ASSOCIATED ) {
2764 netdev_rx ( dev->netdev, iob );
2765 return;
2766 }
2767
2768 /* No association? Drop it. */
2769 goto drop;
2770
2771 drop_crypt:
2773 drop:
2774 DBGC2 ( dev, "802.11 %p dropped packet fc=%04x seq=%04x\n", dev,
2775 hdr->fc, hdr->seq );
2776 free_iob ( iob );
2777 return;
2778}
2779
2780/** Indicate an error in receiving a packet
2781 *
2782 * @v dev 802.11 device
2783 * @v iob I/O buffer with received packet, or NULL
2784 * @v rc Error code
2785 *
2786 * This logs the error with the wrapping net_device, and frees iob if
2787 * it is passed.
2788 */
2790 struct io_buffer *iob, int rc )
2791{
2792 netdev_rx_err ( dev->netdev, iob, rc );
2793}
2794
2795/** Indicate the completed transmission of a packet
2796 *
2797 * @v dev 802.11 device
2798 * @v iob I/O buffer of transmitted packet
2799 * @v retries Number of times this packet was retransmitted
2800 * @v rc Error code, or 0 for success
2801 *
2802 * This logs an error with the wrapping net_device if one occurred,
2803 * and removes and frees the I/O buffer from its TX queue. The
2804 * provided retry information is used to tune our transmission rate.
2805 *
2806 * If the packet did not need to be retransmitted because it was
2807 * properly ACKed the first time, @a retries should be 0.
2808 */
2810 struct io_buffer *iob, int retries, int rc )
2811{
2812 /* Update rate-control algorithm */
2813 if ( dev->rctl )
2814 rc80211_update_tx ( dev, retries, rc );
2815
2816 /* Pass completion onward */
2817 netdev_tx_complete_err ( dev->netdev, iob, rc );
2818}
2819
2820/** Common 802.11 errors */
2831
2832/* Drag in objects via net80211_ll_protocol */
2833REQUIRING_SYMBOL ( net80211_ll_protocol );
2834
2835/* Drag in 802.11 configuration */
2836REQUIRE_OBJECT ( config_net80211 );
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
union @162305117151260234136356364136041353210355154177 key
Sense key.
Definition scsi.h:3
struct golan_eq_context ctx
Definition CIB_PRM.h:0
struct golan_inbox_hdr hdr
Message header.
Definition CIB_PRM.h:0
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
unsigned short uint16_t
Definition stdint.h:11
static volatile void * bits
Definition bitops.h:28
static int fill
Definition string.h:209
if(len >=6 *4) __asm__ __volatile__("movsl" if(len >=5 *4) __asm__ __volatile__("movsl" if(len >=4 *4) __asm__ __volatile__("movsl" if(len >=3 *4) __asm__ __volatile__("movsl" if(len >=2 *4) __asm__ __volatile__("movsl" if(len >=1 *4) __asm__ __volatile__("movsl" if((len % 4) >=2) __asm__ __volatile__("movsw" if((len % 2) >=1) __asm__ __volatile__("movsb" retur dest)
Definition string.h:151
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
void timeout(int)
ring len
Length.
Definition dwmac.h:226
uint32_t type
Operating system type.
Definition ena.h:1
uint8_t flags
Flags.
Definition ena.h:7
uint8_t status
Status.
Definition ena.h:5
Error codes.
Error message tables.
#define __errortab
Definition errortab.h:22
#define __einfo_errortab(einfo)
Definition errortab.h:24
int eth_mc_hash(unsigned int af, const void *net_addr, void *ll_addr)
Hash multicast address.
Definition ethernet.c:194
void eth_init_addr(const void *hw_addr, void *ll_addr)
Initialise Ethernet address.
Definition ethernet.c:151
int eth_eui64(const void *ll_addr, void *eui64)
Generate EUI-64 address.
Definition ethernet.c:235
const char * eth_ntoa(const void *ll_addr)
Transcribe Ethernet address.
Definition ethernet.c:176
uint8_t eth_broadcast[ETH_ALEN]
Ethernet broadcast MAC address.
Definition ethernet.c:48
int eth_eth_addr(const void *ll_addr, void *eth_addr)
Generate Ethernet-compatible compressed link-layer address.
Definition ethernet.c:223
Ethernet protocol.
static int is_multicast_ether_addr(const void *addr)
Check if Ethernet address is a multicast address.
Definition ethernet.h:38
static int is_broadcast_ether_addr(const void *addr)
Check if Ethernet address is the broadcast address.
Definition ethernet.h:62
static struct net_device * netdev
Definition gdbudp.c:53
#define __unused
Declare a variable or data structure as unused.
Definition compiler.h:573
#define DBGP(...)
Definition compiler.h:532
#define DBGC2(...)
Definition compiler.h:522
#define DBGP_HD(...)
Definition compiler.h:534
#define DBGC(...)
Definition compiler.h:505
#define DBG(...)
Print a debugging message.
Definition compiler.h:498
#define IEEE80211_CAPAB_SHORT_SLOT
Set if PHY supports short slot time on 802.11g.
Definition ieee80211.h:419
#define IEEE80211_CAPAB_PRIVACY
Set if the network is encrypted (by any method)
Definition ieee80211.h:401
#define IEEE80211_CAPAB_MANAGED
Set if using an Access Point (managed mode)
Definition ieee80211.h:389
#define IEEE80211_CAPAB_SHORT_PMBL
Set if PHY supports short preambles on 802.11b.
Definition ieee80211.h:404
#define IEEE80211_CAPAB_ADHOC
Set if operating in IBSS (no-AP, "Ad-Hoc") mode.
Definition ieee80211.h:392
#define IEEE80211_STYPE_DISASSOC
Subtype value for disassociation management frames.
Definition ieee80211.h:178
#define IEEE80211_STYPE_ASSOC_REQ
Subtype value for association-request management frames.
Definition ieee80211.h:118
#define IEEE80211_FC_TODS
802.11 Frame Control field: To Data System flag
Definition ieee80211.h:229
#define IEEE80211_STYPE_ASSOC_RESP
Subtype value for association-response management frames.
Definition ieee80211.h:125
#define IEEE80211_FC_FROMDS
802.11 Frame Control field: From Data System flag
Definition ieee80211.h:237
#define IEEE80211_FC_SUBTYPE
802.11 Frame Control field, Frame Subtype bitmask
Definition ieee80211.h:110
#define IEEE80211_FC_PROTECTED
802.11 Frame Control field: Protected flag
Definition ieee80211.h:264
#define IEEE80211_TYPE_CTRL
Type value for control (layer-1, hardware-managed) frames.
Definition ieee80211.h:103
#define IEEE80211_TYPE_MGMT
Type value for management (layer-2) frames.
Definition ieee80211.h:100
#define IEEE80211_STYPE_PROBE_RESP
Subtype value for probe-response management frames.
Definition ieee80211.h:157
#define IEEE80211_STYPE_ACTION
Subtype value for action management frames.
Definition ieee80211.h:205
#define IEEE80211_FC_RETRY
802.11 Frame Control field: Retransmission flag
Definition ieee80211.h:243
#define IEEE80211_FC_TYPE
802.11 Frame Control field, Frame Type bitmask
Definition ieee80211.h:97
#define IEEE80211_STYPE_BEACON
Subtype value for beacon management frames.
Definition ieee80211.h:168
#define IEEE80211_TYPE_DATA
Type value for data frames.
Definition ieee80211.h:106
#define IEEE80211_STYPE_REASSOC_REQ
Subtype value for reassociation-request management frames.
Definition ieee80211.h:133
#define IEEE80211_STYPE_AUTH
Subtype value for authentication management frames.
Definition ieee80211.h:188
#define IEEE80211_FC_MORE_FRAG
802.11 Frame Control field: More Fragments flag
Definition ieee80211.h:240
#define IEEE80211_THIS_VERSION
Expected value of Version bits in Frame Control.
Definition ieee80211.h:93
#define IEEE80211_STYPE_PROBE_REQ
Subtype value for probe-request management frames.
Definition ieee80211.h:150
#define IEEE80211_STYPE_REASSOC_RESP
Subtype value for reassociation-response management frames.
Definition ieee80211.h:141
#define IEEE80211_FC_VERSION
802.11 Frame Control field, Version bitmask
Definition ieee80211.h:90
#define IEEE80211_STYPE_DEAUTH
Subtype value for deauthentication management frames.
Definition ieee80211.h:198
#define IEEE80211_STYPE_DATA
Subtype value for ordinary data frames, with no QoS or CF add-ons.
Definition ieee80211.h:219
#define IEEE80211_LLC_SSAP
Value for SSAP field in 802.2 LLC header for 802.11 frames: SNAP.
Definition ieee80211.h:340
#define IEEE80211_LLC_DSAP
Value for DSAP field in 802.2 LLC header for 802.11 frames: SNAP.
Definition ieee80211.h:337
#define IEEE80211_LLC_CTRL
Value for control field in 802.2 LLC header for 802.11 frames.
Definition ieee80211.h:346
#define IEEE80211_IE_SSID
Information element ID for SSID information element.
Definition ieee80211.h:582
static int ieee80211_ie_bound(union ieee80211_ie *ie, void *end)
Check that 802.11 information element is bounded by buffer.
Definition ieee80211.h:1012
#define IEEE80211_ERP_BARKER_LONG
ERP information element: Flag set if long preambles must be used.
Definition ieee80211.h:777
#define IEEE80211_IE_ERP_INFO
Information element ID for ERP Information information element.
Definition ieee80211.h:768
#define IEEE80211_IE_DS_PARAM
Information element ID for Direct Spectrum parameter information element.
Definition ieee80211.h:620
#define IEEE80211_IE_EXT_RATES
Information element ID for extended rates information element.
Definition ieee80211.h:603
#define IEEE80211_IE_VENDOR
Information element ID for Vendor Specific information element.
Definition ieee80211.h:960
#define IEEE80211_IE_COUNTRY
Information element ID for Country information element.
Definition ieee80211.h:668
static union ieee80211_ie * ieee80211_next_ie(union ieee80211_ie *ie, void *end)
Advance to next 802.11 information element.
Definition ieee80211.h:1028
#define IEEE80211_IE_RATES
Information element ID for rates information element.
Definition ieee80211.h:600
#define IEEE80211_ERP_USE_PROTECTION
ERP information element: Flag set if CTS protection must be used.
Definition ieee80211.h:774
#define IEEE80211_IE_RSN
Information element ID for Robust Security Network information element.
Definition ieee80211.h:834
#define IEEE80211_TYP_FRAME_HEADER_LEN
Frame header length for frames we might work with.
Definition ieee80211.h:60
#define IEEE80211_MAX_DATA_LEN
Maximum length of frame payload.
Definition ieee80211.h:28
#define IEEE80211_MAX_SSID_LEN
Maximum length of an ESSID.
Definition ieee80211.h:77
#define IEEE80211_LLC_HEADER_LEN
Length of LLC/SNAP headers on data frames.
Definition ieee80211.h:31
#define IEEE80211_AUTH_SHARED_KEY
Shared Key authentication algorithm.
Definition ieee80211.h:1157
#define ieee80211_beacon
Definition ieee80211.h:1069
#define IEEE80211_AUTH_OPEN_SYSTEM
Open System authentication algorithm.
Definition ieee80211.h:1154
#define ieee80211_disassoc
Definition ieee80211.h:1079
#define ieee80211_assoc_resp
Definition ieee80211.h:1111
#define IEEE80211_REASON_LEAVING
Definition ieee80211.h:514
#define IEEE80211_REASON_UNSPECIFIED
Definition ieee80211.h:512
#define IEEE80211_SEQNR(seq)
Extract sequence number from 802.11 Sequence Control field.
Definition ieee80211.h:280
#define IEEE80211_MAKESEQ(seqnr, frag)
Make 802.11 Sequence Control field from sequence and fragment numbers.
Definition ieee80211.h:286
#define IEEE80211_FRAG(seq)
Extract fragment number from 802.11 Sequence Control field.
Definition ieee80211.h:283
#define IEEE80211_STATUS_AUTH_ALGO_UNSUPP
Definition ieee80211.h:457
#define IEEE80211_STATUS_SUCCESS
Definition ieee80211.h:452
#define IEEE80211_STATUS_AUTH_CHALL_INVALID
Definition ieee80211.h:459
#define IEEE80211_STATUS_FAILURE
Definition ieee80211.h:453
uint32_t start
Starting offset.
Definition netvsc.h:1
uint16_t size
Buffer size.
Definition dwmac.h:3
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
static void net80211_step_associate(struct net80211_device *dev)
Step 802.11 association process.
Definition net80211.c:1647
static void net80211_handle_assoc_reply(struct net80211_device *dev, struct io_buffer *iob)
Handle receipt of 802.11 association reply frame.
Definition net80211.c:2327
static int net80211_send_disassoc(struct net80211_device *dev, int reason, int deauth)
Send 802.11 disassociation frame.
Definition net80211.c:2362
static void net80211_handle_auth(struct net80211_device *dev, struct io_buffer *iob)
Handle receipt of 802.11 authentication frame.
Definition net80211.c:2228
static void net80211_handle_mgmt(struct net80211_device *dev, struct io_buffer *iob, int signal)
Handle receipt of 802.11 management frame.
Definition net80211.c:2439
int net80211_prepare_assoc(struct net80211_device *dev, struct net80211_wlan *wlan)
Prepare 802.11 device channel and rate set for communication.
Definition net80211.c:2106
int net80211_send_auth(struct net80211_device *dev, struct net80211_wlan *wlan, int method)
Send 802.11 initial authentication frame.
Definition net80211.c:2201
int net80211_send_assoc(struct net80211_device *dev, struct net80211_wlan *wlan)
Send 802.11 association frame.
Definition net80211.c:2288
void net80211_deauthenticate(struct net80211_device *dev, int rc)
Deauthenticate from current network and try again.
Definition net80211.c:2391
#define NET80211_BAND_BIT_2GHZ
Bitmask for the 2GHz band.
Definition net80211.h:52
#define NET80211_BAND_2GHZ
The 2.4 GHz ISM band, unlicensed in most countries.
Definition net80211.h:45
#define NET80211_BAND_5GHZ
The band from 4.9 GHz to 5.7 GHz, which tends to be more restricted.
Definition net80211.h:47
#define NET80211_BAND_BIT_5GHZ
Bitmask for the 5GHz band.
Definition net80211.h:54
#define NET80211_CFG_ASSOC
Association has been established with a new BSS (dev->bssid)
Definition net80211.h:87
#define NET80211_CFG_CHANNEL
Channel choice (dev->channel) or regulatory parameters have changed.
Definition net80211.h:81
#define NET80211_CFG_RATE
Requested transmission rate (dev->rate) has changed.
Definition net80211.h:84
#define NET80211_CFG_PHY_PARAMS
Low-level link parameters (short preamble, protection, etc) have changed.
Definition net80211.h:90
struct net80211_device * net80211_alloc(size_t priv_size)
Allocate 802.11 device.
Definition net80211.c:755
void net80211_tx_complete(struct net80211_device *dev, struct io_buffer *iob, int retries, int rc)
Indicate the completed transmission of a packet.
Definition net80211.c:2809
int net80211_register(struct net80211_device *dev, struct net80211_device_operations *ops, struct net80211_hw_info *hw)
Register 802.11 device with network stack.
Definition net80211.c:792
void net80211_unregister(struct net80211_device *dev)
Unregister 802.11 device from network stack.
Definition net80211.c:825
void net80211_rx_err(struct net80211_device *dev, struct io_buffer *iob, int rc)
Indicate an error in receiving a packet.
Definition net80211.c:2789
u16 net80211_duration(struct net80211_device *dev, int bytes, u16 rate)
Calculate one frame's contribution to 802.11 duration field.
Definition net80211.c:442
void net80211_free(struct net80211_device *dev)
Free 802.11 device.
Definition net80211.c:839
void net80211_rx(struct net80211_device *dev, struct io_buffer *iob, int signal, u16 rate)
Handle receipt of 802.11 frame.
Definition net80211.c:2690
static void net80211_rx_frag(struct net80211_device *dev, struct io_buffer *iob, int signal)
Handle receipt of 802.11 fragment.
Definition net80211.c:2597
static struct io_buffer * net80211_accum_frags(struct net80211_device *dev, int fcid, int nfrags, int size)
Accumulate 802.11 fragments into one I/O buffer.
Definition net80211.c:2562
static void net80211_free_frags(struct net80211_device *dev, int fcid)
Free buffers used by 802.11 fragment cache entry.
Definition net80211.c:2534
static void net80211_set_rtscts_rate(struct net80211_device *dev)
Pick TX rate for RTS/CTS packets based on data rate.
Definition net80211.c:1968
static void net80211_add_channels(struct net80211_device *dev, int start, int len, int txpower)
Add channels to 802.11 device.
Definition net80211.c:918
static int net80211_process_capab(struct net80211_device *dev, u16 capab)
Update 802.11 device state to reflect received capabilities field.
Definition net80211.c:1011
static int net80211_process_ie(struct net80211_device *dev, union ieee80211_ie *ie, void *ie_end)
Update 802.11 device state to reflect received information elements.
Definition net80211.c:1045
static union ieee80211_ie * net80211_marshal_request_info(struct net80211_device *dev, union ieee80211_ie *ie)
Create information elements for outgoing probe or association packet.
Definition net80211.c:1203
static void net80211_filter_hw_channels(struct net80211_device *dev)
Filter 802.11 device channels for hardware capabilities.
Definition net80211.c:962
static int net80211_ll_pull(struct net_device *netdev, struct io_buffer *iobuf, const void **ll_dest, const void **ll_source, uint16_t *net_proto, unsigned int *flags)
static int net80211_ll_push(struct net_device *netdev, struct io_buffer *iobuf, const void *ll_dest, const void *ll_source, uint16_t net_proto)
Add 802.11 link-layer header.
Definition net80211.c:484
struct net80211_device * net80211_get(struct net_device *netdev)
Get 802.11 device from wrapping network device.
Definition net80211.c:625
void net80211_set_rate_idx(struct net80211_device *dev, int rate)
Set data transmission rate for 802.11 device.
Definition net80211.c:2001
int net80211_change_channel(struct net80211_device *dev, int channel)
Configure 802.11 device to transmit on a certain channel.
Definition net80211.c:2022
void net80211_autoassociate(struct net80211_device *dev)
Start 802.11 association process.
Definition net80211.c:1930
int net80211_keep_mgmt(struct net80211_device *dev, int enable)
Set state of 802.11 device keeping management frames.
Definition net80211.c:647
struct io_buffer * net80211_mgmt_dequeue(struct net80211_device *dev, int *signal)
Get 802.11 management frame.
Definition net80211.c:668
static void net80211_netdev_close(struct net_device *netdev)
Close 802.11 device.
Definition net80211.c:284
static int net80211_netdev_open(struct net_device *netdev)
Open 802.11 device and start association.
Definition net80211.c:257
static int net80211_netdev_transmit(struct net_device *netdev, struct io_buffer *iobuf)
Transmit packet on 802.11 device.
Definition net80211.c:321
static void net80211_netdev_irq(struct net_device *netdev, int enable)
Enable or disable interrupts for 802.11 device.
Definition net80211.c:371
static void net80211_netdev_poll(struct net_device *netdev)
Poll 802.11 device for received packets and completed transmissions.
Definition net80211.c:357
#define NET80211_PHY_USE_PROTECTION
Whether to use RTS/CTS or CTS-to-self protection for transmissions.
Definition net80211.h:251
#define NET80211_PHY_USE_SHORT_PREAMBLE
Whether to use 802.11b short preamble operation.
Definition net80211.h:260
#define NET80211_PHY_USE_SHORT_SLOT
Whether to use 802.11g short slot operation.
Definition net80211.h:266
void net80211_free_wlanlist(struct list_head *list)
Free list of WLAN structures.
Definition net80211.c:1620
struct net80211_wlan * net80211_probe_finish_best(struct net80211_probe_ctx *ctx)
Finish probe of 802.11 networks, returning best-signal network found.
Definition net80211.c:1545
void net80211_free_wlan(struct net80211_wlan *wlan)
Free WLAN structure.
Definition net80211.c:1606
struct list_head * net80211_probe_finish_all(struct net80211_probe_ctx *ctx)
Finish probe of 802.11 networks, returning all networks found.
Definition net80211.c:1586
int net80211_prepare_probe(struct net80211_device *dev, int band, int active)
Prepare 802.11 device channel and rate set for scanning.
Definition net80211.c:2052
struct net80211_probe_ctx * net80211_probe_start(struct net80211_device *dev, const char *essid, int active)
Begin probe of 802.11 networks.
Definition net80211.c:1291
int net80211_probe_step(struct net80211_probe_ctx *ctx)
Continue probe of 802.11 networks.
Definition net80211.c:1364
static int net80211_check_settings_update(void)
Check for 802.11 SSID or key updates.
Definition net80211.c:1892
#define NET80211_IS_REASON
Whether the error code provided is a "reason" code, not a "status" code.
Definition net80211.h:188
#define NET80211_PROBED
Whether we have found the network we will be associating with.
Definition net80211.h:191
#define NET80211_WORKING
Whether the auto-association task is running.
Definition net80211.h:212
#define NET80211_AUTHENTICATED
Whether we have successfully authenticated with the network.
Definition net80211.h:198
#define NET80211_NO_ASSOC
Whether the auto-association task should be suppressed.
Definition net80211.h:223
#define NET80211_CRYPTO_SYNCED
Whether we have completed security handshaking with the network.
Definition net80211.h:209
#define NET80211_WAITING
Whether the auto-association task is waiting for a reply from the AP.
Definition net80211.h:215
#define NET80211_AUTO_SSID
Whether this association was performed using a broadcast SSID.
Definition net80211.h:234
#define NET80211_STATUS_MASK
An error code indicating the failure mode, or 0 if successful.
Definition net80211.h:185
#define NET80211_ASSOCIATED
Whether we have successfully associated with the network.
Definition net80211.h:201
#define REQUIRE_OBJECT(object)
Require an object.
Definition compiler.h:202
#define ENOENT
No such file or directory.
Definition errno.h:515
#define EINVAL
Invalid argument.
Definition errno.h:429
#define EFAULT
Bad address.
Definition errno.h:394
#define ENETUNREACH
Network unreachable.
Definition errno.h:489
#define ENOSYS
Function not implemented.
Definition errno.h:565
#define ETIMEDOUT
Connection timed out.
Definition errno.h:670
#define ENOMEM
Not enough space.
Definition errno.h:535
#define ENOTSUP
Operation not supported.
Definition errno.h:590
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
#define SETTING_NETDEV_EXTRA
Network device additional settings.
Definition settings.h:65
#define REQUIRING_SYMBOL(symbol)
Specify the file's requiring symbol.
Definition compiler.h:140
uint16_t reason
Rejection reason.
Definition ib_mad.h:9
uint8_t method
Definition ib_mad.h:3
uint8_t bytes[64]
Definition ib_mad.h:5
Constants and data structures defined in IEEE 802.11, subsetted according to what iPXE knows how to u...
struct ieee80211_ie_channels_channel_band channels[0]
List of (start, length) channel bands we can use.
Definition ieee80211.h:4
char ssid[0]
SSID data, not NUL-terminated.
Definition ieee80211.h:2
u16 fc
802.11 Frame Control field
Definition ieee80211.h:0
Address Resolution Protocol constants and types.
#define ARPHRD_ETHER
Ethernet 10Mbps.
Definition if_arp.h:17
#define ETH_ALEN
Definition if_ether.h:9
#define u8
Definition igbvf_osdep.h:40
#define htons(value)
Definition byteswap.h:136
#define __weak
Declare a function as weak (use before the definition)
Definition compiler.h:219
CPU sleeping.
Configuration settings.
#define __setting(setting_order, name)
Declare a configuration setting.
Definition settings.h:57
#define __settings_applicator
Declare a settings applicator.
Definition settings.h:265
iPXE timers
#define TICKS_PER_SEC
Number of ticks per second.
Definition timer.h:16
String functions.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * memset(void *dest, int character, size_t len) __nonnull
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition iobuf.c:131
static size_t iob_headroom(struct io_buffer *iobuf)
Calculate available space at start of an I/O buffer.
Definition iobuf.h:170
#define iob_push(iobuf, len)
Definition iobuf.h:89
#define iob_put(iobuf, len)
Definition iobuf.h:125
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition iobuf.h:217
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
#define iob_reserve(iobuf, len)
Definition iobuf.h:72
#define iob_pull(iobuf, len)
Definition iobuf.h:107
#define iob_unput(iobuf, len)
Definition iobuf.h:140
unsigned long tmp
Definition linux_pci.h:65
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition list.h:334
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Definition list.h:31
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition list.h:459
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition list.h:94
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition list.h:432
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition list.h:46
#define list_empty(list)
Test whether a list is empty.
Definition list.h:137
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:662
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:621
static struct net80211_device_operations net80211_null_ops
Set of device operations that does nothing.
Definition net80211.c:51
int net80211_tx_mgmt(struct net80211_device *dev, u16 fc, u8 dest[6], struct io_buffer *iob)
Transmit 802.11 management frame.
Definition net80211.c:707
#define NET80211_PROBE_GATHER_ALL
Seconds to wait after finding a network, to possibly find other networks.
Definition net80211.c:1267
static struct net_device_operations net80211_netdev_ops
Network device operations for a wrapped 802.11 device.
Definition net80211.c:380
static void net80211_set_state(struct net80211_device *dev, short clear, short set, u16 status)
Set state of 802.11 device.
Definition net80211.c:867
static void net80211_update_link_quality(struct net80211_device *dev, struct io_buffer *iob)
Update link quality information based on received beacon.
Definition net80211.c:2411
#define ASSOC_RETRIES
Number of times to try sending a particular association management frame.
Definition net80211.c:1640
static int net80211_rate_is_erp(u16 rate)
Determine whether a transmission rate uses ERP/OFDM.
Definition net80211.c:400
static struct list_head net80211_devices
List of 802.11 devices.
Definition net80211.c:48
#define LQ_SMOOTH
Smoothing factor (1-7) for link quality calculation.
Definition net80211.c:2402
__weak int sec80211_detect(struct io_buffer *iob __unused, enum net80211_security_proto *secprot __unused, enum net80211_crypto_alg *crypt __unused)
Detect secure 802.11 network when security support is not available.
Definition net80211.c:113
static struct process_descriptor net80211_process_desc
802.11 association process descriptor
Definition net80211.c:739
#define ASSOC_TIMEOUT
Number of ticks to wait for replies to association management frames.
Definition net80211.c:1637
#define NET80211_PROBE_TIMEOUT
Seconds to allow a probe to take if no network has been found.
Definition net80211.c:1270
#define NET80211_PROBE_GATHER
Seconds to wait after finding a network, to possibly find better APs for it.
Definition net80211.c:1260
The iPXE 802.11 MAC layer.
net80211_security_proto
An 802.11 security handshaking protocol.
Definition net80211.h:96
@ NET80211_SECPROT_UNKNOWN
Dummy value used when the handshaking type can't be detected.
Definition net80211.h:124
@ NET80211_SECPROT_NONE
No security handshaking.
Definition net80211.h:102
net80211_crypto_alg
An 802.11 data encryption algorithm.
Definition net80211.h:129
@ NET80211_CRYPT_NONE
No security, an "Open" network.
Definition net80211.h:131
@ NET80211_CRYPT_UNKNOWN
Dummy value used when the cryptosystem can't be detected.
Definition net80211.h:177
#define NET80211_MAX_CHANNELS
The maximum number of channels we allow to be configured simultaneously.
Definition net80211.h:275
#define NET80211_NR_CONCURRENT_FRAGS
The number of fragments we can receive at once.
Definition net80211.h:284
#define NET80211_MAX_RATES
The maximum number of TX rates we allow to be configured simultaneously.
Definition net80211.h:272
#define NET80211_REG_TXPOWER
Maximum TX power to allow (dBm), if we don't get a regulatory hint.
Definition net80211.h:287
#define NET80211_FRAG_TIMEOUT
Seconds we'll wait to get all fragments of a packet.
Definition net80211.h:278
#define NET80211_HANDSHAKERS
Definition net80211.h:675
The iPXE 802.11 MAC layer errors.
#define E80211_REASON(reas)
Make return status code from 802.11 reason code.
#define EINFO_ECONNRESET_8021X_FAILURE
#define EINFO_ECONNREFUSED_AUTH_ALGO_UNSUPP
#define EINFO_EINVAL_CRYPTO_REQUEST
#define EINFO_ECONNRESET_UNSPECIFIED
#define EINVAL_PKT_NOT_DATA
#define EINVAL_PKT_TOO_SHORT
#define EINFO_ECONNRESET_4WAY_TIMEOUT
#define EINVAL_PKT_VERSION
#define E80211_STATUS(stat)
Make return status code from 802.11 status code.
#define EINVAL_CRYPTO_REQUEST
#define EINVAL_ACTIVE_SCAN
#define EINVAL_PKT_LLC_HEADER
#define EINVAL_PKT_NOT_FROMDS
#define EINFO_ECONNREFUSED_ASSOC_DENIED
#define EINFO_ECONNREFUSED_FAILURE
#define EINFO_ECONNRESET_INACTIVITY
void netdev_link_err(struct net_device *netdev, int rc)
Mark network device as having a specific link state.
Definition netdevice.c:208
void netdev_link_down(struct net_device *netdev)
Mark network device as having link down.
Definition netdevice.c:231
void netdev_rx(struct net_device *netdev, struct io_buffer *iobuf)
Add packet to receive queue.
Definition netdevice.c:549
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition netdevice.c:942
void netdev_tx_complete_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Complete network transmission.
Definition netdevice.c:471
struct net_device * alloc_netdev(size_t priv_len)
Allocate network device.
Definition netdevice.c:722
void netdev_rx_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Discard received packet.
Definition netdevice.c:587
int register_netdev(struct net_device *netdev)
Register network device.
Definition netdevice.c:760
int netdev_tx(struct net_device *netdev, struct io_buffer *iobuf)
Transmit raw packet via network device.
Definition netdevice.c:335
Network device management.
static int netdev_is_open(struct net_device *netdev)
Check whether or not network device is open.
Definition netdevice.h:662
static void netdev_link_up(struct net_device *netdev)
Mark network device as having link up.
Definition netdevice.h:789
#define LL_MULTICAST
Packet is a multicast (including broadcast) packet.
Definition netdevice.h:106
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
Definition netdevice.h:519
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
Definition netdevice.h:532
#define NETDEV_IRQ_UNSUPPORTED
Network device interrupts are unsupported.
Definition netdevice.h:453
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition netdevice.h:576
#define __ll_protocol
Declare a link-layer protocol.
Definition netdevice.h:468
#define LL_BROADCAST
Packet is a broadcast packet.
Definition netdevice.h:109
static void netdev_tx_complete(struct net_device *netdev, struct io_buffer *iobuf)
Complete network transmission.
Definition netdevice.h:767
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition netdevice.h:587
uint32_t channel
RNDIS channel.
Definition netvsc.h:3
struct option_descriptor set[0]
Definition nvo_cmd.c:112
struct option_descriptor clear[0]
Definition nvo_cmd.c:114
void process_del(struct process *process)
Remove process from process list.
Definition process.c:80
void process_add(struct process *process)
Add process to process list.
Definition process.c:60
static void process_init_stopped(struct process *process, struct process_descriptor *desc, struct refcnt *refcnt)
Initialise process without adding to process list.
Definition process.h:146
#define PROC_DESC(object_type, process, _step)
Define a process descriptor.
Definition process.h:83
void rc80211_update_tx(struct net80211_device *dev, int retries, int rc)
Update rate-control state for transmitted packet.
Definition rc80211.c:317
void rc80211_free(struct rc80211_ctx *ctx)
Free rate-control context.
Definition rc80211.c:370
struct rc80211_ctx * rc80211_init(struct net80211_device *dev __unused)
Initialize rate-control algorithm.
Definition rc80211.c:155
void rc80211_update_rx(struct net80211_device *dev, int retry, u16 rate)
Update rate-control state for received packet.
Definition rc80211.c:352
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
Definitions for general secured-network routines.
int fetch_string_setting(struct settings *settings, const struct setting *setting, char *data, size_t len)
Fetch value of string setting.
Definition settings.c:842
long fetch_intz_setting(struct settings *settings, const struct setting *setting)
Fetch value of signed integer setting, or zero.
Definition settings.c:1054
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
int strcmp(const char *first, const char *second)
Compare strings.
Definition string.c:174
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115
char * strcpy(char *dest, const char *src)
Copy string.
Definition string.c:347
size_t strlen(const char *src)
Get length of string.
Definition string.c:244
Definition hw.c:16
Association request frame data.
Definition ieee80211.h:1084
union ieee80211_ie info_element[0]
List of information elements.
Definition ieee80211.h:1092
u16 capability
Capability flags.
Definition ieee80211.h:1086
u16 listen_interval
Interval at which we wake up, in units of the beacon interval.
Definition ieee80211.h:1089
Authentication frame data.
Definition ieee80211.h:1139
u16 status
Status code.
Definition ieee80211.h:1147
u16 algorithm
Authentication algorithm (Open System or Shared Key)
Definition ieee80211.h:1141
u16 tx_seq
Sequence number of this frame; first from client to AP is 1.
Definition ieee80211.h:1144
An 802.11 data or management frame without QoS or WDS header fields.
Definition ieee80211.h:301
u8 max_txpower
Maximum TX power in dBm.
Definition ieee80211.h:634
u8 first_channel
Channel number for first channel in band.
Definition ieee80211.h:632
u8 nr_channels
Number of contiguous channels in band.
Definition ieee80211.h:633
union ieee80211_ie_country_triplet triplet[0]
List of regulatory triplets.
Definition ieee80211.h:664
char name[2]
ISO Alpha2 country code.
Definition ieee80211.h:660
u8 current_channel
Current channel number, 1-14.
Definition ieee80211.h:616
The 802.2 LLC/SNAP header sent before actual data in a data frame.
Definition ieee80211.h:325
u8 dsap
Destination SAP ID.
Definition ieee80211.h:327
u8 ctrl
Control information.
Definition ieee80211.h:329
u8 ssap
Source SAP ID.
Definition ieee80211.h:328
u16 ethertype
Ethernet Type field.
Definition ieee80211.h:333
u8 oui[3]
Organization code, usually 0.
Definition ieee80211.h:332
Probe request frame data.
Definition ieee80211.h:1132
union ieee80211_ie info_element[0]
List of information elements.
Definition ieee80211.h:1134
A persistent I/O buffer.
Definition iobuf.h:38
void * data
Start of data.
Definition iobuf.h:53
void * tail
End of data.
Definition iobuf.h:55
struct list_head list
List of which this buffer is a member.
Definition iobuf.h:45
void * head
Start of the buffer.
Definition iobuf.h:51
A doubly-linked list entry (or list head)
Definition list.h:19
A link-layer protocol.
Definition netdevice.h:115
Context for the association task.
Definition net80211.c:97
int method
Next authentication method to try using.
Definition net80211.c:99
int last_packet
Time (in ticks) of the last sent association-related packet.
Definition net80211.c:102
int times_tried
Number of times we have tried sending it.
Definition net80211.c:105
An 802.11 RF channel.
Definition net80211.h:386
u16 hw_value
Hardware channel value.
Definition net80211.h:414
u8 maxpower
Maximum allowable transmit power, in dBm.
Definition net80211.h:425
u16 center_freq
The center frequency for this channel.
Definition net80211.h:411
u8 band
The band with which this channel is associated.
Definition net80211.h:388
u8 channel_nr
A channel number interpreted according to the band.
Definition net80211.h:405
Interface to an 802.11 cryptosystem.
Definition net80211.h:690
struct io_buffer *(* decrypt)(struct net80211_crypto *crypto, struct io_buffer *iob)
Decrypt a frame using the cryptosystem.
Definition net80211.h:759
struct io_buffer *(* encrypt)(struct net80211_crypto *crypto, struct io_buffer *iob)
Encrypt a frame using the cryptosystem.
Definition net80211.h:733
Operations that must be implemented by an 802.11 driver.
Definition net80211.h:293
void(* poll)(struct net80211_device *dev)
Poll for completed and received packets.
Definition net80211.h:357
int(* transmit)(struct net80211_device *dev, struct io_buffer *iobuf)
Transmit packet on 802.11 network device.
Definition net80211.h:341
void(* irq)(struct net80211_device *dev, int enable)
Enable or disable interrupts.
Definition net80211.h:364
void(* close)(struct net80211_device *dev)
Close 802.11 network device.
Definition net80211.h:315
int(* config)(struct net80211_device *dev, int changed)
Update hardware state to match 802.11 layer state.
Definition net80211.h:381
int(* open)(struct net80211_device *dev)
Open 802.11 device.
Definition net80211.h:305
Structure encapsulating the complete state of an 802.11 device.
Definition net80211.h:787
struct net_device * netdev
The net_device that wraps us.
Definition net80211.h:789
u16 last_tx_seqnr
The sequence number of the last packet we sent.
Definition net80211.h:997
u16 rates[NET80211_MAX_RATES]
A list of all possible TX rates we might use.
Definition net80211.h:818
struct net80211_channel channels[NET80211_MAX_CHANNELS]
A list of all possible channels we might use.
Definition net80211.h:806
char essid[IEEE80211_MAX_SSID_LEN+1]
SSID of the access point we are or will be associated with.
Definition net80211.h:962
union net80211_device::@067175076122124030020270151142244371222356023347 ctx
Context for the association process.
struct net80211_device_operations * op
802.11 device operations
Definition net80211.h:795
int assoc_rc
Return status code associated with state.
Definition net80211.h:924
u32 tx_beacon_interval
Time between AP sending beacons, microseconds.
Definition net80211.h:971
u64 last_beacon_timestamp
TSFT value for last beacon received, microseconds.
Definition net80211.h:968
u8 rtscts_rate
The rate to use for RTS/CTS transmissions.
Definition net80211.h:831
int keep_mgmt
Whether to store management packets.
Definition net80211.h:1046
struct list_head mgmt_queue
RX management packet queue.
Definition net80211.h:1021
union ieee80211_ie * rsn_ie
RSN or WPA information element to include with association.
Definition net80211.h:932
u16 state
State of our association to the network.
Definition net80211.h:921
struct net80211_crypto * crypto
802.11 cryptosystem for our current network
Definition net80211.h:940
int last_signal
Signal strength of last received packet.
Definition net80211.h:986
struct list_head mgmt_info_queue
RX management packet info queue.
Definition net80211.h:1034
struct rc80211_ctx * rctl
Rate control state.
Definition net80211.h:989
u8 channel
The channel currently in use, as an index into the channels array.
Definition net80211.h:812
u32 rx_beacon_interval
Smoothed average time between beacons, microseconds.
Definition net80211.h:974
struct net80211_handshaker * handshaker
Security handshaker being used.
Definition net80211.h:879
int phy_flags
Physical layer options.
Definition net80211.h:983
u16 aid
Association ID given to us by the AP.
Definition net80211.h:965
struct net80211_wlan * associating
Network with which we are associating.
Definition net80211.h:866
struct net80211_crypto * gcrypto
802.11 cryptosystem for multicast and broadcast frames
Definition net80211.h:951
struct list_head list
List of 802.11 devices.
Definition net80211.h:792
u8 bssid[ETH_ALEN]
MAC address of the access point most recently associated.
Definition net80211.h:954
struct net80211_assoc_ctx * assoc
Definition net80211.h:875
u8 nr_channels
The number of channels in the channels array.
Definition net80211.h:809
struct net80211_probe_ctx * probe
Definition net80211.h:874
u8 rate
The rate currently in use, as an index into the rates array.
Definition net80211.h:824
struct process proc_assoc
The asynchronous association process.
Definition net80211.h:858
struct net80211_hw_info * hw
Information about the hardware, provided to net80211_register()
Definition net80211.h:801
u32 basic_rates
Bitmask of basic rates.
Definition net80211.h:843
struct net80211_frag_cache frags[NET80211_NR_CONCURRENT_FRAGS]
Fragment reassembly state.
Definition net80211.h:994
u16 last_rx_seq
Packet duplication elimination state.
Definition net80211.h:1008
u8 nr_rates
The number of transmission rates in the rates array.
Definition net80211.h:821
Structure tracking received fragments for a packet.
Definition net80211.h:534
u32 start_ticks
Timestamp from point at which first fragment was collected.
Definition net80211.h:542
u8 in_use
Whether this cache entry is in use.
Definition net80211.h:536
u16 seqnr
Sequence number of this MSDU (packet)
Definition net80211.h:539
struct io_buffer * iob[16]
Buffers for each fragment.
Definition net80211.h:545
Interface to an 802.11 security handshaking protocol.
Definition net80211.h:565
int(* init)(struct net80211_device *dev)
Initialize security handshaking protocol.
Definition net80211.h:585
int started
Whether start has been called.
Definition net80211.h:665
int(* start)(struct net80211_device *dev)
Start handshaking.
Definition net80211.h:598
int priv_len
Amount of private data requested.
Definition net80211.h:659
int(* change_key)(struct net80211_device *dev)
Change cryptographic key based on setting.
Definition net80211.h:639
void * priv
Pointer to private data.
Definition net80211.h:672
int(* step)(struct net80211_device *dev)
Process handshaking state.
Definition net80211.h:616
void(* stop)(struct net80211_device *dev)
Stop security handshaking handlers.
Definition net80211.h:650
enum net80211_security_proto protocol
The security handshaking protocol implemented.
Definition net80211.h:567
Information on the capabilities of an 802.11 hardware device.
Definition net80211.h:437
enum net80211_hw_info::@277203366166200071173154201003141076360026365126 flags
A set of flags indicating peculiarities of this device.
int nr_rates[NET80211_NR_BANDS]
Number of supported rates, indexed by band.
Definition net80211.h:511
int bands
A bitwise OR of the bands on which this device can communicate.
Definition net80211.h:453
unsigned channel_change_time
Estimate of the time required to change channels, in microseconds.
Definition net80211.h:518
struct net80211_channel channels[NET80211_MAX_CHANNELS]
List of RF channels supported by the card.
Definition net80211.h:498
int nr_channels
Number of supported channels.
Definition net80211.h:501
u16 rates[NET80211_NR_BANDS][NET80211_MAX_RATES]
List of transmission rates supported by the card, indexed by band.
Definition net80211.h:508
Context for a probe operation.
Definition net80211.c:64
u32 ticks_beacon
Time last useful beacon was received.
Definition net80211.c:81
struct io_buffer * probe
If scanning actively, pointer to probe packet to send.
Definition net80211.c:72
int old_keep_mgmt
Value of keep_mgmt before probe was started.
Definition net80211.c:69
const char * essid
If non-"", the ESSID to limit ourselves to.
Definition net80211.c:75
struct list_head * beacons
List of best beacons for each network found so far.
Definition net80211.c:93
struct net80211_device * dev
802.11 device to probe on
Definition net80211.c:66
u32 ticks_channel
Time channel was last changed.
Definition net80211.c:84
u32 hop_time
Time to stay on each channel.
Definition net80211.c:87
u32 ticks_start
Time probe was started.
Definition net80211.c:78
int hop_step
Channels to hop by when changing channel.
Definition net80211.c:90
Information associated with a received management packet.
Definition net80211.c:58
struct list_head list
Definition net80211.c:60
Structure representing a probed network.
Definition net80211.h:1057
struct list_head list
Link to allow chaining multiple structures into a list to be returned from net80211_probe_finish_all(...
Definition net80211.h:1091
struct io_buffer * beacon
The complete beacon or probe-response frame received.
Definition net80211.h:1081
u8 bssid[ETH_ALEN]
MAC address of the strongest-signal access point for this ESSID.
Definition net80211.h:1067
char essid[IEEE80211_MAX_SSID_LEN+1]
The human-readable ESSID (network name)
Definition net80211.h:1064
int channel
The channel on which that access point communicates.
Definition net80211.h:1078
enum net80211_crypto_alg crypto
Cryptographic algorithm used on the network.
Definition net80211.h:1087
int signal
Signal strength of beacon frame from that access point.
Definition net80211.h:1070
enum net80211_security_proto handshaking
Security handshaking method used on the network.
Definition net80211.h:1084
Network device operations.
Definition netdevice.h:214
A network device.
Definition netdevice.h:353
struct device * dev
Underlying hardware device.
Definition netdevice.h:365
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition netdevice.h:388
A process descriptor.
Definition process.h:32
A setting.
Definition settings.h:24
A settings applicator.
Definition settings.h:252
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition tables.h:386
#define ok(success)
Definition test.h:46
unsigned long currticks(void)
Get current system time in ticks.
Definition timer.c:43
void udelay(unsigned long usecs)
Delay for a fixed number of microseconds.
Definition timer.c:61
802.11 Country information element regulatory triplet
Definition ieee80211.h:642
u8 first
Differentiator between band and ext triplets.
Definition ieee80211.h:644
struct ieee80211_ie_country_band_triplet band
Information about a band of channels.
Definition ieee80211.h:647
Any 802.11 information element.
Definition ieee80211.h:973
u8 rates[0]
Rates data.
Definition ieee80211.h:980
char ssid[0]
SSID text.
Definition ieee80211.h:979
u8 len
Information element data length.
Definition ieee80211.h:977
struct ieee80211_ie_ds_param ds_param
DS parameter set.
Definition ieee80211.h:991
u8 erp_info
ERP information flags.
Definition ieee80211.h:984
struct ieee80211_ie_country country
Country information.
Definition ieee80211.h:994
u8 id
Information element ID.
Definition ieee80211.h:976
#define u16
Definition vga.h:20
#define u32
Definition vga.h:21