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