Changeset 1dcc0b9 in mainline for uspace/lib/ieee80211/src/ieee80211.c
- Timestamp:
- 2015-04-06T10:47:51Z (10 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- d7dadcb4
- Parents:
- 59fa7ab
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/ieee80211/src/ieee80211.c
r59fa7ab r1dcc0b9 36 36 */ 37 37 38 #include <stdio.h> 39 #include <crypto.h> 40 #include <str.h> 38 41 #include <macros.h> 39 42 #include <errno.h> … … 45 48 #include <ops/ieee80211.h> 46 49 50 #define IEEE80211_DATA_RATES_SIZE 8 51 #define IEEE80211_EXT_DATA_RATES_SIZE 4 52 53 /** Frame encapsulation used in IEEE 802.11. */ 54 static const uint8_t rfc1042_header[] = { 55 0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00 56 }; 57 47 58 /** Broadcast MAC address used to spread probe request through channel. */ 48 59 static const uint8_t ieee80211_broadcast_mac_addr[] = { … … 50 61 }; 51 62 52 /** IEEE 802.11 b/g supported data rates in units of 500 kb/s. */ 53 static const uint8_t ieee80211bg_data_rates[] = { 54 2, 4, 11, 12, 18, 22, 24, 36 55 }; 56 57 /** IEEE 802.11 b/g extended supported data rates in units of 500 kb/s. 58 * 59 * These are defined separately, because probe request message can 60 * only handle up to 8 data rates in supported rates IE. 61 */ 62 static const uint8_t ieee80211bg_ext_data_rates[] = { 63 48, 72, 96, 108 64 }; 65 63 /** 64 * Check data frame. 65 * 66 * @param frame_ctrl Frame control field in little endian (!). 67 * 68 * @return True if it is data frame, otherwise false. 69 */ 66 70 inline bool ieee80211_is_data_frame(uint16_t frame_ctrl) 67 71 { … … 72 76 } 73 77 78 /** 79 * Check management frame. 80 * 81 * @param frame_ctrl Frame control field in little endian (!). 82 * 83 * @return True if it is management frame, otherwise false. 84 */ 74 85 inline bool ieee80211_is_mgmt_frame(uint16_t frame_ctrl) 75 86 { … … 80 91 } 81 92 93 /** 94 * Check management beacon frame. 95 * 96 * @param frame_ctrl Frame control field in little endian (!). 97 * 98 * @return True if it is beacon frame, otherwise false. 99 */ 82 100 inline bool ieee80211_is_beacon_frame(uint16_t frame_ctrl) 83 101 { … … 88 106 } 89 107 108 /** 109 * Check management probe response frame. 110 * 111 * @param frame_ctrl Frame control field in little endian (!). 112 * 113 * @return True if it is probe resp frame, otherwise false. 114 */ 90 115 inline bool ieee80211_is_probe_response_frame(uint16_t frame_ctrl) 91 116 { … … 97 122 98 123 /** 124 * Check management authentication frame. 125 * 126 * @param frame_ctrl Frame control field in little endian (!). 127 * 128 * @return True if it is auth frame, otherwise false. 129 */ 130 inline bool ieee80211_is_auth_frame(uint16_t frame_ctrl) 131 { 132 frame_ctrl = uint16_t_le2host(frame_ctrl); 133 134 return (frame_ctrl & IEEE80211_FRAME_CTRL_FRAME_SUBTYPE) 135 == IEEE80211_MGMT_AUTH_FRAME; 136 } 137 138 /** 139 * Check management association response frame. 140 * 141 * @param frame_ctrl Frame control field in little endian (!). 142 * 143 * @return True if it is assoc resp frame, otherwise false. 144 */ 145 inline bool ieee80211_is_assoc_response_frame(uint16_t frame_ctrl) 146 { 147 frame_ctrl = uint16_t_le2host(frame_ctrl); 148 149 return (frame_ctrl & IEEE80211_FRAME_CTRL_FRAME_SUBTYPE) 150 == IEEE80211_MGMT_ASSOC_RESP_FRAME; 151 } 152 153 /** 154 * Check data frame "to distribution system" direction. 155 * 156 * @param frame_ctrl Frame control field in little endian (!). 157 * 158 * @return True if it is TODS frame, otherwise false. 159 */ 160 static inline bool ieee80211_is_tods_frame(uint16_t frame_ctrl) 161 { 162 frame_ctrl = uint16_t_le2host(frame_ctrl); 163 164 return (frame_ctrl & IEEE80211_FRAME_CTRL_TODS); 165 } 166 167 /** 168 * Check data frame "from distribution system" direction. 169 * 170 * @param frame_ctrl Frame control field in little endian (!). 171 * 172 * @return True if it is FROMDS frame, otherwise false. 173 */ 174 static inline bool ieee80211_is_fromds_frame(uint16_t frame_ctrl) 175 { 176 frame_ctrl = uint16_t_le2host(frame_ctrl); 177 178 return (frame_ctrl & IEEE80211_FRAME_CTRL_FROMDS); 179 } 180 181 /** 182 * Check if it is data frame containing payload data. 183 * 184 * @param frame_ctrl Frame control field in little endian (!). 185 * 186 * @return True if it has payload data, otherwise false. 187 */ 188 static inline bool ieee80211_has_data_frame(uint16_t frame_ctrl) 189 { 190 frame_ctrl = uint16_t_le2host(frame_ctrl); 191 192 return (frame_ctrl & (IEEE80211_FRAME_CTRL_FRAME_TYPE | 0x40)) 193 == IEEE80211_DATA_FRAME; 194 } 195 196 /** 197 * Check if it is encrypted frame. 198 * 199 * @param frame_ctrl Frame control field in little endian (!). 200 * 201 * @return True if the frame is encrypted, otherwise false. 202 */ 203 static inline bool ieee80211_is_encrypted_frame(uint16_t frame_ctrl) 204 { 205 frame_ctrl = uint16_t_le2host(frame_ctrl); 206 207 return (frame_ctrl & IEEE80211_FRAME_CTRL_PROTECTED) != 0; 208 } 209 210 /** 211 * Check if PAE packet is EAPOL-Key frame. 212 * 213 * @param key_frame Pointer to start of EAPOL frame. 214 * 215 * @return True if it is EAPOL-Key frame, otherwise false. 216 */ 217 static inline bool ieee80211_is_eapol_key_frame(ieee80211_eapol_key_frame_t 218 *key_frame) 219 { 220 return (key_frame->packet_type == IEEE80211_EAPOL_KEY); 221 } 222 223 224 /** 225 * Generate packet sequence number. 226 * 227 * @param ieee80211_dev IEEE 802.11 device. 228 * 229 * @return True if it has payload data, otherwise false. 230 */ 231 static uint16_t ieee80211_get_sequence_number(ieee80211_dev_t *ieee80211_dev) 232 { 233 uint16_t ret_val = ieee80211_dev->sequence_number; 234 ieee80211_dev->sequence_number += (1 << 4); 235 return ret_val; 236 } 237 238 /** 99 239 * Get driver-specific structure for IEEE 802.11 device. 100 240 * … … 139 279 * @return Current IEEE 802.11 operating mode. 140 280 */ 141 ieee80211_operating_mode_t ieee80211_query_current_op_mode(ieee80211_dev_t* ieee80211_dev) 281 ieee80211_operating_mode_t ieee80211_query_current_op_mode(ieee80211_dev_t* 282 ieee80211_dev) 142 283 { 143 284 return ieee80211_dev->current_op_mode; … … 154 295 { 155 296 return ieee80211_dev->current_freq; 297 } 298 299 /** 300 * Query BSSID the device is connected to. 301 * 302 * @param ieee80211_dev IEEE 802.11 device. 303 * @param bssid Pointer to structure where should be stored BSSID. 304 */ 305 void ieee80211_query_bssid(ieee80211_dev_t* ieee80211_dev, 306 nic_address_t *bssid) 307 { 308 if(bssid) { 309 ieee80211_scan_result_t *auth_data = 310 &ieee80211_dev->bssid_info.res_link->scan_result; 311 312 memcpy(bssid, (void *)&auth_data->bssid, sizeof(nic_address_t)); 313 } 314 } 315 316 /** 317 * Get AID of network we are connected to. 318 * 319 * @param ieee80211_dev IEEE 802.11 device. 320 * 321 * @return AID. 322 */ 323 uint16_t ieee80211_get_aid(ieee80211_dev_t* ieee80211_dev) 324 { 325 return ieee80211_dev->bssid_info.aid; 326 } 327 328 /** 329 * Get security suite used for HW encryption. 330 * 331 * @param ieee80211_dev IEEE 802.11 device. 332 * 333 * @return Security suite indicator. 334 */ 335 int ieee80211_get_security_suite(ieee80211_dev_t* ieee80211_dev) 336 { 337 ieee80211_scan_result_link_t *auth_link = 338 ieee80211_dev->bssid_info.res_link; 339 340 return auth_link->scan_result.security.pair_alg; 341 } 342 343 /** 344 * Check if IEEE 802.11 device is connected to network. 345 * 346 * @param ieee80211_dev IEEE 802.11 device. 347 * 348 * @return True if device is connected to network, otherwise false. 349 */ 350 bool ieee80211_is_connected(ieee80211_dev_t* ieee80211_dev) 351 { 352 return ieee80211_dev->current_auth_phase == IEEE80211_AUTH_ASSOCIATED; 156 353 } 157 354 … … 178 375 { 179 376 ieee80211_dev->current_freq = freq; 377 } 378 379 /** 380 * Check if IEEE 802.11 device is ready (fully initialized). 381 * 382 * @param ieee80211_dev IEEE 802.11 device. 383 * 384 * @return True if device is ready to work, otherwise false. 385 */ 386 bool ieee80211_is_ready(ieee80211_dev_t* ieee80211_dev) 387 { 388 fibril_mutex_lock(&ieee80211_dev->gen_mutex); 389 bool ready_state = ieee80211_dev->ready; 390 fibril_mutex_unlock(&ieee80211_dev->gen_mutex); 391 392 return ready_state; 393 } 394 395 /** 396 * Set IEEE 802.11 device to ready state. 397 * 398 * @param ieee80211_dev IEEE 802.11 device. 399 * @param ready Ready state to be set. 400 */ 401 void ieee80211_set_ready(ieee80211_dev_t* ieee80211_dev, bool ready) 402 { 403 fibril_mutex_lock(&ieee80211_dev->gen_mutex); 404 ieee80211_dev->ready = ready; 405 fibril_mutex_unlock(&ieee80211_dev->gen_mutex); 406 } 407 408 extern bool ieee80211_query_using_key(ieee80211_dev_t* ieee80211_dev) 409 { 410 return ieee80211_dev->using_hw_key; 411 } 412 413 void ieee80211_setup_key_confirm(ieee80211_dev_t* ieee80211_dev, 414 bool using_key) 415 { 416 ieee80211_dev->using_hw_key = using_key; 180 417 } 181 418 … … 209 446 } 210 447 211 /** 448 /** 212 449 * Send frame handler. 450 * 451 * @param nic Pointer to NIC device. 452 * @param data Data buffer. 453 * @param size Data buffer size. 213 454 */ 214 455 static void ieee80211_send_frame(nic_t *nic, void *data, size_t size) … … 217 458 nic_get_specific(nic); 218 459 219 ieee80211_dev->ops->tx_handler(ieee80211_dev, data, size); 460 if(!ieee80211_is_connected(ieee80211_dev)) { 461 return; 462 } 463 464 ieee80211_scan_result_t *auth_data = 465 &ieee80211_dev->bssid_info.res_link->scan_result; 466 467 /* We drop part of IEEE 802.3 ethernet header. */ 468 size_t drop_bytes = sizeof(eth_header_t) - 2; 469 470 size_t complete_size = (size - drop_bytes) + 471 sizeof(ieee80211_data_header_t) + 472 ARRAY_SIZE(rfc1042_header); 473 474 /* Init crypto data. */ 475 size_t add_size = 0; 476 uint16_t crypto = 0; 477 uint8_t add_data[8]; 478 memset(add_data, 0, 8); 479 480 if(ieee80211_dev->using_hw_key) { 481 int sec_suite = auth_data->security.pair_alg; 482 switch(sec_suite) { 483 case IEEE80211_SECURITY_SUITE_CCMP: 484 add_size = IEEE80211_CCMP_HEADER_LENGTH; 485 add_data[3] = 0x20; 486 break; 487 default: 488 break; 489 } 490 491 crypto = uint16_t_le2host(IEEE80211_FRAME_CTRL_PROTECTED); 492 } 493 494 complete_size += add_size; 495 496 void *complete_buffer = malloc(complete_size); 497 memset(complete_buffer, 0, complete_size); 498 499 if(add_size) { 500 memcpy(complete_buffer + sizeof(ieee80211_data_header_t), 501 add_data, add_size); 502 } 503 504 memcpy(complete_buffer + sizeof(ieee80211_data_header_t) + add_size, 505 rfc1042_header, 506 ARRAY_SIZE(rfc1042_header)); 507 508 memcpy(complete_buffer + 509 sizeof(ieee80211_data_header_t) + 510 ARRAY_SIZE(rfc1042_header) + add_size, 511 data + drop_bytes, size - drop_bytes); 512 513 ieee80211_data_header_t *data_header = 514 (ieee80211_data_header_t *) complete_buffer; 515 data_header->frame_ctrl = 516 uint16_t_le2host(IEEE80211_DATA_FRAME) | 517 uint16_t_le2host(IEEE80211_DATA_DATA_FRAME) | 518 uint16_t_le2host(IEEE80211_FRAME_CTRL_TODS) | 519 crypto; 520 data_header->seq_ctrl = ieee80211_get_sequence_number(ieee80211_dev); 521 522 /* BSSID, SA, DA. */ 523 memcpy(data_header->address1, auth_data->bssid.address, ETH_ADDR); 524 memcpy(data_header->address2, data + ETH_ADDR, ETH_ADDR); 525 memcpy(data_header->address3, data, ETH_ADDR); 526 527 ieee80211_dev->ops->tx_handler(ieee80211_dev, 528 complete_buffer, 529 complete_size); 530 531 free(complete_buffer); 220 532 } 221 533 … … 246 558 ieee80211_ops->set_freq = ieee80211_set_freq_impl; 247 559 560 if(!ieee80211_ops->bssid_change) 561 ieee80211_ops->bssid_change = 562 ieee80211_bssid_change_impl; 563 564 if(!ieee80211_ops->key_config) 565 ieee80211_ops->key_config = ieee80211_key_config_impl; 566 248 567 if(!ieee80211_ops->scan) 249 568 ieee80211_ops->scan = ieee80211_scan_impl; … … 257 576 if(nic_dev_ops) 258 577 if (!nic_dev_ops->interfaces[IEEE80211_DEV_IFACE]) 259 nic_dev_ops->interfaces[IEEE80211_DEV_IFACE] = ieee80211_iface; 578 nic_dev_ops->interfaces[IEEE80211_DEV_IFACE] = 579 ieee80211_iface; 260 580 261 581 if(!ieee80211_iface->get_scan_results) 262 ieee80211_iface->get_scan_results = ieee80211_get_scan_results_impl; 582 ieee80211_iface->get_scan_results = 583 ieee80211_get_scan_results_impl; 263 584 264 585 if(!ieee80211_iface->connect) 265 586 ieee80211_iface->connect = ieee80211_connect_impl; 587 588 if(!ieee80211_iface->disconnect) 589 ieee80211_iface->disconnect = ieee80211_disconnect_impl; 266 590 } else { 267 591 return EINVAL; … … 304 628 ieee80211_dev->ddf_dev = ddf_dev; 305 629 ieee80211_dev->started = false; 630 ieee80211_dev->ready = false; 631 ieee80211_dev->using_hw_key = false; 306 632 ieee80211_dev->current_op_mode = IEEE80211_OPMODE_STATION; 633 ieee80211_dev->current_auth_phase = IEEE80211_AUTH_DISCONNECTED; 307 634 memcpy(ieee80211_dev->bssid_mask.address, ieee80211_broadcast_mac_addr, 308 635 ETH_ADDR); 636 637 ieee80211_scan_result_list_init(&ieee80211_dev->ap_list); 638 639 fibril_mutex_initialize(&ieee80211_dev->gen_mutex); 640 fibril_condvar_initialize(&ieee80211_dev->gen_cond); 309 641 310 642 /* Bind NIC to device */ … … 373 705 } 374 706 707 /** 708 * Convert frequency value to channel number. 709 * 710 * @param freq IEEE 802.11 operating frequency. 711 * 712 * @return Operating channel number. 713 */ 375 714 static uint8_t ieee80211_freq_to_channel(uint16_t freq) 376 715 { … … 378 717 } 379 718 719 static void ieee80211_prepare_ie_header(void **ie_header, 720 uint8_t id, uint8_t length, void *data) 721 { 722 ieee80211_ie_header_t *header = 723 (ieee80211_ie_header_t *) *ie_header; 724 725 header->element_id = id; 726 header->length = length; 727 728 memcpy(*ie_header + sizeof(ieee80211_ie_header_t), data, length); 729 730 *ie_header = (void *) ((void *) header + 731 sizeof(ieee80211_ie_header_t) + length); 732 } 733 380 734 /** 381 735 * Probe request implementation. 382 736 * 383 737 * @param ieee80211_dev Pointer to IEEE 802.11 device structure. 738 * @param ssid Probing SSID or NULL if broadcast. 384 739 * 385 740 * @return EOK if succeed, negative error code otherwise. 386 741 */ 387 int ieee80211_probe_request(ieee80211_dev_t *ieee80211_dev )742 int ieee80211_probe_request(ieee80211_dev_t *ieee80211_dev, char *ssid) 388 743 { 389 744 nic_t *nic = nic_get_from_ddf_dev(ieee80211_dev->ddf_dev); … … 391 746 nic_query_address(nic, &nic_address); 392 747 393 size_t data_rates_size = ARRAY_SIZE(ieee80211bg_data_rates); 394 size_t ext_data_rates_size = ARRAY_SIZE(ieee80211bg_ext_data_rates); 395 396 /* 3 headers - (rates, ext rates, current channel) and their data 397 * lengths + pad. 748 size_t ssid_data_size = (ssid != NULL) ? str_size(ssid) : 0; 749 size_t channel_data_size = 1; 750 751 uint8_t channel = 752 ieee80211_freq_to_channel(ieee80211_dev->current_freq); 753 754 /* 4 headers - (ssid, rates, ext rates, current channel) and their data 755 * lengths. 398 756 */ 399 757 size_t payload_size = 400 sizeof(ieee80211_ie_header_t) * 3 + 401 data_rates_size + ext_data_rates_size + sizeof(uint8_t) + 2; 758 sizeof(ieee80211_ie_header_t) * 4 + 759 ssid_data_size + 760 IEEE80211_DATA_RATES_SIZE + IEEE80211_EXT_DATA_RATES_SIZE + 761 channel_data_size; 402 762 403 763 size_t buffer_size = sizeof(ieee80211_mgmt_header_t) + payload_size; … … 415 775 memcpy(mgmt_header->src_addr, nic_address.address, ETH_ADDR); 416 776 memcpy(mgmt_header->bssid, ieee80211_broadcast_mac_addr, ETH_ADDR); 417 418 /* Jump to payload -> header + padding. */ 419 ieee80211_ie_header_t *rates_ie_header = (ieee80211_ie_header_t *) 420 ((void *)buffer + sizeof(ieee80211_mgmt_header_t) + 2); 421 rates_ie_header->element_id = IEEE80211_RATES_IE; 422 rates_ie_header->length = data_rates_size; 423 memcpy(rates_ie_header + sizeof(ieee80211_ie_header_t), 424 ieee80211bg_data_rates, 425 data_rates_size); 426 427 ieee80211_ie_header_t *ext_rates_ie_header = (ieee80211_ie_header_t *) 428 ((void *)rates_ie_header + sizeof(ieee80211_ie_header_t) + 429 data_rates_size); 430 ext_rates_ie_header->element_id = IEEE80211_EXT_RATES_IE; 431 ext_rates_ie_header->length = ext_data_rates_size; 432 memcpy(ext_rates_ie_header + sizeof(ieee80211_ie_header_t), 433 ieee80211bg_ext_data_rates, 434 ext_data_rates_size); 435 436 ieee80211_ie_header_t *chan_ie_header = (ieee80211_ie_header_t *) 437 ((void *)ext_rates_ie_header + sizeof(ieee80211_ie_header_t) + 438 ext_data_rates_size); 439 chan_ie_header->element_id = IEEE80211_CHANNEL_IE; 440 chan_ie_header->length = 1; 441 uint8_t *it = (uint8_t *) ((void *)chan_ie_header + 442 sizeof(ieee80211_ie_header_t)); 443 *it = ieee80211_freq_to_channel(ieee80211_dev->current_freq); 777 mgmt_header->seq_ctrl = 778 host2uint16_t_le(ieee80211_get_sequence_number(ieee80211_dev)); 779 780 /* Jump to payload. */ 781 void *it = (void *) buffer + sizeof(ieee80211_mgmt_header_t); 782 ieee80211_prepare_ie_header(&it, IEEE80211_SSID_IE, ssid_data_size, 783 (void *) ssid); 784 ieee80211_prepare_ie_header(&it, IEEE80211_RATES_IE, 785 IEEE80211_DATA_RATES_SIZE, 786 (void *) &ieee80211bg_data_rates); 787 ieee80211_prepare_ie_header(&it, IEEE80211_EXT_RATES_IE, 788 IEEE80211_EXT_DATA_RATES_SIZE, 789 (void *) &ieee80211bg_data_rates[IEEE80211_DATA_RATES_SIZE]); 790 ieee80211_prepare_ie_header(&it, IEEE80211_CHANNEL_IE, 791 channel_data_size, (void *) &channel); 444 792 445 793 ieee80211_dev->ops->tx_handler(ieee80211_dev, buffer, buffer_size); … … 451 799 452 800 /** 453 * Probeauthentication implementation.801 * IEEE 802.11 authentication implementation. 454 802 * 455 803 * @param ieee80211_dev Pointer to IEEE 802.11 device structure. … … 457 805 * @return EOK if succeed, negative error code otherwise. 458 806 */ 459 int ieee80211_probe_auth(ieee80211_dev_t *ieee80211_dev) 460 { 461 uint8_t test_bssid[] = {0x14, 0xF6, 0x5A, 0xAF, 0x5E, 0xB7}; 462 807 int ieee80211_authenticate(ieee80211_dev_t *ieee80211_dev) 808 { 463 809 nic_t *nic = nic_get_from_ddf_dev(ieee80211_dev->ddf_dev); 464 810 nic_address_t nic_address; 465 811 nic_query_address(nic, &nic_address); 466 812 813 ieee80211_scan_result_t *auth_data = 814 &ieee80211_dev->bssid_info.res_link->scan_result; 815 467 816 size_t buffer_size = sizeof(ieee80211_mgmt_header_t) + 468 817 sizeof(ieee80211_auth_body_t); 818 469 819 void *buffer = malloc(buffer_size); 470 820 memset(buffer, 0, buffer_size); … … 477 827 IEEE80211_MGMT_AUTH_FRAME 478 828 ); 479 memcpy(mgmt_header->dest_addr, test_bssid, ETH_ADDR);829 memcpy(mgmt_header->dest_addr, auth_data->bssid.address, ETH_ADDR); 480 830 memcpy(mgmt_header->src_addr, nic_address.address, ETH_ADDR); 481 memcpy(mgmt_header->bssid, test_bssid, ETH_ADDR);831 memcpy(mgmt_header->bssid, auth_data->bssid.address, ETH_ADDR); 482 832 483 833 ieee80211_auth_body_t *auth_body = … … 485 835 (buffer + sizeof(ieee80211_mgmt_header_t)); 486 836 auth_body->auth_alg = host2uint16_t_le(0); 487 auth_body->auth_trans_no = host2uint16_t_le( 0);837 auth_body->auth_trans_no = host2uint16_t_le(1); 488 838 489 839 ieee80211_dev->ops->tx_handler(ieee80211_dev, buffer, buffer_size); … … 494 844 } 495 845 846 /** 847 * IEEE 802.11 association implementation. 848 * 849 * @param ieee80211_dev Pointer to IEEE 802.11 device structure. 850 * @param password Passphrase to be used in encrypted communication or NULL 851 * for open networks. 852 * 853 * @return EOK if succeed, negative error code otherwise. 854 */ 855 int ieee80211_associate(ieee80211_dev_t *ieee80211_dev, char *password) 856 { 857 nic_t *nic = nic_get_from_ddf_dev(ieee80211_dev->ddf_dev); 858 nic_address_t nic_address; 859 nic_query_address(nic, &nic_address); 860 861 ieee80211_scan_result_link_t *auth_link = 862 ieee80211_dev->bssid_info.res_link; 863 864 ieee80211_scan_result_t *auth_data = &auth_link->scan_result; 865 866 size_t ssid_data_size = str_size(auth_data->ssid); 867 868 size_t payload_size = 869 sizeof(ieee80211_ie_header_t) * 3 + 870 ssid_data_size + 871 IEEE80211_DATA_RATES_SIZE + 872 IEEE80211_EXT_DATA_RATES_SIZE; 873 874 size_t buffer_size = 875 sizeof(ieee80211_mgmt_header_t) + 876 sizeof(ieee80211_assoc_req_body_t) + 877 payload_size; 878 879 if(auth_data->security.type == IEEE80211_SECURITY_WPA2) { 880 buffer_size += auth_link->rsn_copy_len; 881 } 882 883 void *buffer = malloc(buffer_size); 884 memset(buffer, 0, buffer_size); 885 886 ieee80211_mgmt_header_t *mgmt_header = 887 (ieee80211_mgmt_header_t *) buffer; 888 889 mgmt_header->frame_ctrl = host2uint16_t_le( 890 IEEE80211_MGMT_FRAME | 891 IEEE80211_MGMT_ASSOC_REQ_FRAME 892 ); 893 memcpy(mgmt_header->dest_addr, auth_data->bssid.address, ETH_ADDR); 894 memcpy(mgmt_header->src_addr, nic_address.address, ETH_ADDR); 895 memcpy(mgmt_header->bssid, auth_data->bssid.address, ETH_ADDR); 896 897 ieee80211_assoc_req_body_t *assoc_body = 898 (ieee80211_assoc_req_body_t *) 899 (buffer + sizeof(ieee80211_mgmt_header_t)); 900 assoc_body->listen_interval = host2uint16_t_le(1); 901 902 /* Jump to payload. */ 903 void *it = buffer + sizeof(ieee80211_mgmt_header_t) + 904 sizeof(ieee80211_assoc_req_body_t); 905 ieee80211_prepare_ie_header(&it, IEEE80211_SSID_IE, 906 ssid_data_size, (void *) auth_data->ssid); 907 ieee80211_prepare_ie_header(&it, IEEE80211_RATES_IE, 908 IEEE80211_DATA_RATES_SIZE, 909 (void *) &ieee80211bg_data_rates); 910 ieee80211_prepare_ie_header(&it, IEEE80211_EXT_RATES_IE, 911 IEEE80211_EXT_DATA_RATES_SIZE, 912 (void *) &ieee80211bg_data_rates[IEEE80211_DATA_RATES_SIZE]); 913 914 if(auth_data->security.type != IEEE80211_SECURITY_OPEN) { 915 assoc_body->capability |= host2uint16_t_le(CAP_SECURITY); 916 } 917 918 if(auth_data->security.type == IEEE80211_SECURITY_WPA2) { 919 memcpy(it, auth_link->rsn_copy, auth_link->rsn_copy_len); 920 } 921 922 ieee80211_dev->ops->tx_handler(ieee80211_dev, buffer, buffer_size); 923 924 /* 925 * Save password and SSID to be used in eventual authentication 926 * handshake. 927 */ 928 memcpy(ieee80211_dev->bssid_info.password, password, 929 str_size(password)); 930 931 free(buffer); 932 933 return EOK; 934 } 935 936 /** 937 * IEEE 802.11 deauthentication implementation. 938 * 939 * @param ieee80211_dev Pointer to IEEE 802.11 device structure. 940 * 941 * @return EOK if succeed, negative error code otherwise. 942 */ 943 int ieee80211_deauthenticate(ieee80211_dev_t *ieee80211_dev) 944 { 945 ieee80211_scan_result_t *auth_data = 946 &ieee80211_dev->bssid_info.res_link->scan_result; 947 948 ieee80211_dev->current_auth_phase = IEEE80211_AUTH_DISCONNECTED; 949 ieee80211_dev->bssid_info.aid = (uint16_t) -1; 950 memcpy(auth_data->bssid.address, ieee80211_broadcast_mac_addr, 951 ETH_ADDR); 952 953 nic_t *nic = nic_get_from_ddf_dev(ieee80211_dev->ddf_dev); 954 nic_address_t nic_address; 955 nic_query_address(nic, &nic_address); 956 957 size_t buffer_size = sizeof(ieee80211_mgmt_header_t) + 958 sizeof(ieee80211_deauth_body_t); 959 void *buffer = malloc(buffer_size); 960 memset(buffer, 0, buffer_size); 961 962 ieee80211_mgmt_header_t *mgmt_header = 963 (ieee80211_mgmt_header_t *) buffer; 964 965 mgmt_header->frame_ctrl = host2uint16_t_le( 966 IEEE80211_MGMT_FRAME | 967 IEEE80211_MGMT_DEAUTH_FRAME 968 ); 969 memcpy(mgmt_header->dest_addr, auth_data->bssid.address, ETH_ADDR); 970 memcpy(mgmt_header->src_addr, nic_address.address, ETH_ADDR); 971 memcpy(mgmt_header->bssid, auth_data->bssid.address, ETH_ADDR); 972 973 ieee80211_dev->ops->tx_handler(ieee80211_dev, buffer, buffer_size); 974 975 free(buffer); 976 977 ieee80211_dev->ops->bssid_change(ieee80211_dev); 978 979 return EOK; 980 } 981 982 static void ieee80211_process_auth_info(ieee80211_scan_result_link_t *ap_data, 983 void *buffer) 984 { 985 uint8_t *it = (uint8_t *) buffer; 986 987 uint16_t *version = (uint16_t *) it; 988 if(uint16_t_le2host(*version) != 0x1) { 989 ap_data->scan_result.security.type = -1; 990 return; 991 } 992 993 it += sizeof(uint16_t); 994 995 uint32_t group_cipher = *(it+3); 996 switch(group_cipher) { 997 case IEEE80211_AUTH_CIPHER_TKIP: 998 ap_data->scan_result.security.group_alg = 999 IEEE80211_SECURITY_SUITE_TKIP; 1000 break; 1001 case IEEE80211_AUTH_CIPHER_CCMP: 1002 ap_data->scan_result.security.group_alg = 1003 IEEE80211_SECURITY_SUITE_CCMP; 1004 break; 1005 default: 1006 ap_data->scan_result.security.group_alg = -1; 1007 } 1008 1009 it += 4*sizeof(uint8_t); 1010 1011 uint16_t *pairwise_count = (uint16_t *) it; 1012 uint32_t pairwise_cipher = *(it+sizeof(uint16_t)+3); 1013 switch(pairwise_cipher) { 1014 case IEEE80211_AUTH_CIPHER_TKIP: 1015 ap_data->scan_result.security.pair_alg = 1016 IEEE80211_SECURITY_SUITE_TKIP; 1017 break; 1018 case IEEE80211_AUTH_CIPHER_CCMP: 1019 ap_data->scan_result.security.pair_alg = 1020 IEEE80211_SECURITY_SUITE_CCMP; 1021 break; 1022 default: 1023 ap_data->scan_result.security.pair_alg = -1; 1024 } 1025 1026 it += 2*sizeof(uint16_t) + 1027 uint16_t_le2host(*pairwise_count)*sizeof(uint32_t); 1028 1029 uint32_t auth_suite = *(it+3); 1030 switch(auth_suite) { 1031 case IEEE80211_AUTH_AKM_PSK: 1032 ap_data->scan_result.security.auth = 1033 IEEE80211_SECURITY_AUTH_PSK; 1034 break; 1035 case IEEE80211_AUTH_AKM_8021X: 1036 ap_data->scan_result.security.auth = 1037 IEEE80211_SECURITY_AUTH_8021X; 1038 break; 1039 default: 1040 ap_data->scan_result.security.auth = -1; 1041 } 1042 } 1043 1044 static uint32_t uint32_from_uint8_seq(uint8_t *seq) 1045 { 1046 return (*seq << 24) + (*(seq+1) << 16) + (*(seq+2) << 8) + *(seq+3); 1047 } 1048 1049 static uint8_t *ieee80211_process_ies(ieee80211_dev_t *ieee80211_dev, 1050 ieee80211_scan_result_link_t *ap_data, void *buffer, size_t buffer_size) 1051 { 1052 void *it = buffer; 1053 while((it + sizeof(ieee80211_ie_header_t)) < buffer + buffer_size) { 1054 ieee80211_ie_header_t *ie_header = 1055 (ieee80211_ie_header_t *) it; 1056 uint8_t *channel; 1057 switch(ie_header->element_id) { 1058 case IEEE80211_CHANNEL_IE: 1059 channel = (uint8_t *) 1060 (it + sizeof(ieee80211_ie_header_t)); 1061 ap_data->scan_result.channel = *channel; 1062 break; 1063 case IEEE80211_RSN_IE: 1064 if(!ap_data) 1065 break; 1066 ap_data->scan_result.security.type = 1067 IEEE80211_SECURITY_WPA2; 1068 ieee80211_process_auth_info(ap_data, 1069 it + sizeof(ieee80211_ie_header_t)); 1070 ap_data->rsn_copy_len = ie_header->length + 1071 sizeof(ieee80211_ie_header_t); 1072 memcpy(ap_data->rsn_copy, 1073 it, 1074 ap_data->rsn_copy_len); 1075 break; 1076 case IEEE80211_VENDOR_IE: 1077 if(uint32_from_uint8_seq(it + 1078 sizeof(ieee80211_ie_header_t)) == 1079 WPA_OUI) { 1080 if(ap_data->scan_result.security.type == 1081 IEEE80211_SECURITY_WPA2) { 1082 break; 1083 } 1084 ap_data->scan_result.security.type = 1085 IEEE80211_SECURITY_WPA; 1086 ieee80211_process_auth_info(ap_data, 1087 it + 1088 sizeof(ieee80211_ie_header_t) + 1089 sizeof(uint32_t)); 1090 } else if(uint32_from_uint8_seq(it + 1091 sizeof(ieee80211_ie_header_t)) == 1092 GTK_OUI) { 1093 return it + 1094 sizeof(ieee80211_ie_header_t) + 1095 sizeof(uint32_t) + 2; 1096 } 1097 } 1098 it += sizeof(ieee80211_ie_header_t) + ie_header->length; 1099 } 1100 1101 return NULL; 1102 } 1103 496 1104 /** 497 1105 * Process probe response and store results. 498 1106 * 499 1107 * @param ieee80211_dev Pointer to IEEE 802.11 device structure. 1108 * @param mgmt_header Pointer to start of management frame header. 500 1109 * 501 1110 * @return EOK if succeed, negative error code otherwise. 502 1111 */ 503 1112 static int ieee80211_process_probe_response(ieee80211_dev_t *ieee80211_dev, 1113 ieee80211_mgmt_header_t *mgmt_header, size_t buffer_size) 1114 { 1115 ieee80211_beacon_start_t *beacon_body = (ieee80211_beacon_start_t *) 1116 ((void *)mgmt_header + sizeof(ieee80211_mgmt_header_t)); 1117 1118 ieee80211_ie_header_t *ssid_ie_header = (ieee80211_ie_header_t *) 1119 ((void *)beacon_body + sizeof(ieee80211_beacon_start_t)); 1120 1121 /* Not empty SSID. */ 1122 if(ssid_ie_header->length > 0) { 1123 fibril_mutex_t *scan_mutex = &ieee80211_dev->ap_list.scan_mutex; 1124 1125 fibril_mutex_lock(scan_mutex); 1126 1127 ieee80211_scan_result_list_t *result_list = 1128 &ieee80211_dev->ap_list; 1129 1130 uint8_t *ssid_start = (uint8_t *) ((void *)ssid_ie_header + 1131 sizeof(ieee80211_ie_header_t)); 1132 char ssid[IEEE80211_MAX_SSID_LENGTH]; 1133 memcpy(ssid, ssid_start, ssid_ie_header->length); 1134 ssid[ssid_ie_header->length] = '\0'; 1135 1136 /* Check whether SSID is already in results. */ 1137 ieee80211_scan_result_list_foreach(*result_list, result) { 1138 if(!str_cmp(ssid, result->scan_result.ssid)) { 1139 result->last_beacon = time(NULL); 1140 fibril_mutex_unlock(scan_mutex); 1141 return EOK; 1142 } 1143 } 1144 1145 /* Results are full. */ 1146 if(result_list->size == IEEE80211_MAX_RESULTS_LENGTH - 1) { 1147 fibril_mutex_unlock(scan_mutex); 1148 return EOK; 1149 } 1150 1151 ieee80211_scan_result_link_t *ap_data = 1152 malloc(sizeof(ieee80211_scan_result_link_t)); 1153 memset(ap_data, 0, sizeof(ieee80211_scan_result_link_t)); 1154 link_initialize(&ap_data->link); 1155 1156 memcpy(ap_data->scan_result.bssid.address, 1157 mgmt_header->bssid, ETH_ADDR); 1158 memcpy(ap_data->scan_result.ssid, ssid, 1159 ssid_ie_header->length + 1); 1160 1161 if(uint16_t_le2host(beacon_body->capability) & CAP_SECURITY) { 1162 ap_data->scan_result.security.type = 1163 IEEE80211_SECURITY_WEP; 1164 } else { 1165 ap_data->scan_result.security.type = 1166 IEEE80211_SECURITY_OPEN; 1167 ap_data->scan_result.security.auth = -1; 1168 ap_data->scan_result.security.pair_alg = -1; 1169 ap_data->scan_result.security.group_alg = -1; 1170 } 1171 1172 void *rest_ies_start = ssid_start + ssid_ie_header->length; 1173 size_t rest_buffer_size = 1174 buffer_size - 1175 sizeof(ieee80211_mgmt_header_t) - 1176 sizeof(ieee80211_beacon_start_t) - 1177 sizeof(ieee80211_ie_header_t) - 1178 ssid_ie_header->length; 1179 1180 ieee80211_process_ies(ieee80211_dev, ap_data, rest_ies_start, 1181 rest_buffer_size); 1182 1183 ap_data->last_beacon = time(NULL); 1184 1185 ieee80211_scan_result_list_append(result_list, ap_data); 1186 1187 fibril_mutex_unlock(scan_mutex); 1188 } 1189 1190 return EOK; 1191 } 1192 1193 /** 1194 * Process authentication response. 1195 * 1196 * @param ieee80211_dev Pointer to IEEE 802.11 device structure. 1197 * @param mgmt_header Pointer to start of management frame header. 1198 * 1199 * @return EOK if succeed, negative error code otherwise. 1200 */ 1201 static int ieee80211_process_auth_response(ieee80211_dev_t *ieee80211_dev, 504 1202 ieee80211_mgmt_header_t *mgmt_header) 505 1203 { 506 ieee80211_ie_header_t *ssid_ie_header = (ieee80211_ie_header_t *) 507 ((void *)mgmt_header + sizeof(ieee80211_mgmt_header_t) + 508 sizeof(ieee80211_beacon_start_t)); 509 510 if(ssid_ie_header->length > 0) { 511 uint8_t *results_length = &ieee80211_dev->ap_list.length; 512 513 ieee80211_scan_result_t *ap_data = 514 &ieee80211_dev->ap_list.results[(*results_length)++]; 515 516 memset(ap_data, 0, sizeof(ieee80211_scan_result_t)); 517 518 uint8_t *ssid_start = (uint8_t *) 519 ((void *)ssid_ie_header + 520 sizeof(ieee80211_ie_header_t)); 521 522 memcpy(ap_data->bssid.address, mgmt_header->bssid, ETH_ADDR); 523 memcpy(ap_data->ssid, ssid_start, ssid_ie_header->length); 524 ap_data->ssid[ssid_ie_header->length] = '\0'; 1204 fibril_mutex_lock(&ieee80211_dev->gen_mutex); 1205 1206 ieee80211_dev->current_auth_phase = IEEE80211_AUTH_AUTHENTICATED; 1207 1208 fibril_condvar_signal(&ieee80211_dev->gen_cond); 1209 fibril_mutex_unlock(&ieee80211_dev->gen_mutex); 1210 1211 return EOK; 1212 } 1213 1214 /** 1215 * Process association response. 1216 * 1217 * @param ieee80211_dev Pointer to IEEE 802.11 device structure. 1218 * @param mgmt_header Pointer to start of management frame header. 1219 * 1220 * @return EOK if succeed, negative error code otherwise. 1221 */ 1222 static int ieee80211_process_assoc_response(ieee80211_dev_t *ieee80211_dev, 1223 ieee80211_mgmt_header_t *mgmt_header) 1224 { 1225 ieee80211_scan_result_t *auth_data = 1226 &ieee80211_dev->bssid_info.res_link->scan_result; 1227 1228 fibril_mutex_lock(&ieee80211_dev->gen_mutex); 1229 1230 ieee80211_assoc_resp_body_t *assoc_resp = 1231 (ieee80211_assoc_resp_body_t *) ((void *)mgmt_header + 1232 sizeof(ieee80211_mgmt_header_t)); 1233 1234 ieee80211_dev->bssid_info.aid = uint16_t_le2host(assoc_resp->aid); 1235 memcpy(auth_data->bssid.address, mgmt_header->bssid, ETH_ADDR); 1236 1237 ieee80211_dev->current_auth_phase = IEEE80211_AUTH_ASSOCIATED; 1238 1239 ieee80211_dev->ops->bssid_change(ieee80211_dev); 1240 1241 fibril_condvar_signal(&ieee80211_dev->gen_cond); 1242 fibril_mutex_unlock(&ieee80211_dev->gen_mutex); 1243 1244 return EOK; 1245 } 1246 1247 static int ieee80211_process_4way_handshake(ieee80211_dev_t *ieee80211_dev, 1248 void *buffer, size_t buffer_size) 1249 { 1250 ieee80211_eapol_key_frame_t *key_frame = 1251 (ieee80211_eapol_key_frame_t *) buffer; 1252 1253 bool handshake_done = false; 1254 1255 ieee80211_scan_result_link_t *auth_link = 1256 ieee80211_dev->bssid_info.res_link; 1257 1258 ieee80211_scan_result_t *auth_data = &auth_link->scan_result; 1259 uint8_t *ptk = ieee80211_dev->bssid_info.ptk; 1260 uint8_t *gtk = ieee80211_dev->bssid_info.gtk; 1261 1262 size_t ptk_key_length, gtk_key_length; 1263 hash_func_t hash_sel; 1264 switch(auth_data->security.pair_alg) { 1265 case IEEE80211_SECURITY_SUITE_CCMP: 1266 ptk_key_length = IEEE80211_PTK_CCMP_LENGTH; 1267 hash_sel = HASH_SHA1; 1268 break; 1269 default: 1270 return ENOTSUP; 1271 } 1272 1273 switch(auth_data->security.group_alg) { 1274 case IEEE80211_SECURITY_SUITE_CCMP: 1275 gtk_key_length = IEEE80211_GTK_CCMP_LENGTH; 1276 break; 1277 default: 1278 return ENOTSUP; 1279 } 1280 1281 size_t output_size = 1282 sizeof(eth_header_t) + 1283 sizeof(ieee80211_eapol_key_frame_t); 1284 1285 if(!(uint16_t_be2host(key_frame->key_info) & 1286 IEEE80211_EAPOL_KEY_KEYINFO_SECURE)) { 1287 output_size += auth_link->rsn_copy_len; 1288 } 1289 1290 nic_t *nic = nic_get_from_ddf_dev(ieee80211_dev->ddf_dev); 1291 nic_address_t nic_address; 1292 nic_query_address(nic, &nic_address); 1293 1294 void *output_buffer = malloc(output_size); 1295 memset(output_buffer, 0, output_size); 1296 1297 /* Setup ethernet header. */ 1298 eth_header_t *eth_header = (eth_header_t *) output_buffer; 1299 memcpy(eth_header->dest_addr, auth_data->bssid.address, ETH_ADDR); 1300 memcpy(eth_header->src_addr, nic_address.address, ETH_ADDR); 1301 eth_header->proto = host2uint16_t_be(ETH_TYPE_PAE); 1302 1303 ieee80211_eapol_key_frame_t *output_key_frame = 1304 (ieee80211_eapol_key_frame_t *) 1305 (output_buffer + sizeof(eth_header_t)); 1306 1307 /* Copy content of incoming EAPOL-Key frame. */ 1308 memcpy((void *) output_key_frame, buffer, 1309 sizeof(ieee80211_eapol_key_frame_t)); 1310 1311 output_key_frame->proto_version = 0x1; 1312 output_key_frame->key_length = 0; 1313 output_key_frame->body_length = 1314 host2uint16_t_be(output_size - sizeof(eth_header_t)-4); 1315 output_key_frame->key_info &= 1316 ~host2uint16_t_be( 1317 IEEE80211_EAPOL_KEY_KEYINFO_ACK 1318 ); 1319 1320 /* 1321 * Check if it is last or first incoming message in 4-way 1322 * handshake. 1323 */ 1324 if(uint16_t_be2host(key_frame->key_info) & 1325 IEEE80211_EAPOL_KEY_KEYINFO_SECURE) { 1326 output_key_frame->key_info &= 1327 ~host2uint16_t_be( 1328 IEEE80211_EAPOL_KEY_KEYINFO_ENCDATA 1329 ); 1330 output_key_frame->key_info &= 1331 ~host2uint16_t_be( 1332 IEEE80211_EAPOL_KEY_KEYINFO_INSTALL 1333 ); 1334 output_key_frame->key_data_length = 0; 1335 output_key_frame->key_length = 0; 1336 memset(output_key_frame->key_nonce, 0, 32); 1337 memset(output_key_frame->key_mic, 0, 16); 1338 memset(output_key_frame->key_rsc, 0, 8); 1339 memset(output_key_frame->eapol_key_iv, 0, 16); 1340 1341 /* Derive GTK and save it. */ 1342 uint16_t key_data_length = 1343 uint16_t_be2host(key_frame->key_data_length); 1344 uint16_t decrypt_len = key_data_length - 8; 1345 uint8_t key_data[decrypt_len]; 1346 uint8_t *data_ptr = (uint8_t *) (buffer + 1347 sizeof(ieee80211_eapol_key_frame_t)); 1348 if(ieee80211_aes_key_unwrap(ptk + KEK_OFFSET, data_ptr, 1349 key_data_length, key_data) == EOK) { 1350 1351 uint8_t *key_ptr = ieee80211_process_ies(ieee80211_dev, 1352 NULL, key_data, decrypt_len); 1353 1354 if(key_ptr) { 1355 memcpy(gtk, key_ptr, gtk_key_length); 1356 handshake_done = true; 1357 } 1358 } 1359 } else { 1360 output_key_frame->key_info |= 1361 host2uint16_t_be( 1362 IEEE80211_EAPOL_KEY_KEYINFO_MIC 1363 ); 1364 output_key_frame->key_data_length = 1365 host2uint16_t_be(auth_link->rsn_copy_len); 1366 memcpy((void *)output_key_frame + 1367 sizeof(ieee80211_eapol_key_frame_t), 1368 auth_link->rsn_copy, 1369 auth_link->rsn_copy_len); 1370 1371 /* Compute PMK. */ 1372 uint8_t pmk[PBKDF2_KEY_LENGTH]; 1373 pbkdf2((uint8_t *) ieee80211_dev->bssid_info.password, 1374 str_size(ieee80211_dev->bssid_info.password), 1375 (uint8_t *) auth_data->ssid, 1376 str_size(auth_data->ssid), pmk, hash_sel); 1377 1378 uint8_t *anonce = key_frame->key_nonce; 1379 1380 /* Generate SNONCE. */ 1381 uint8_t snonce[32]; 1382 rnd_sequence(snonce, 32); 1383 1384 memcpy(output_key_frame->key_nonce, snonce, 32); 1385 1386 uint8_t *dest_addr = eth_header->dest_addr; 1387 uint8_t *src_addr = eth_header->src_addr; 1388 1389 /* Derive PTK and save it. */ 1390 uint8_t prf_result[ptk_key_length]; 1391 uint8_t crypt_data[PRF_CRYPT_DATA_LENGTH]; 1392 memcpy(crypt_data, 1393 min_sequence(dest_addr, src_addr, ETH_ADDR), 1394 ETH_ADDR); 1395 memcpy(crypt_data + ETH_ADDR, 1396 max_sequence(dest_addr, src_addr, ETH_ADDR), 1397 ETH_ADDR); 1398 memcpy(crypt_data + 2*ETH_ADDR, 1399 min_sequence(anonce, snonce, 32), 1400 32); 1401 memcpy(crypt_data + 2*ETH_ADDR + 32, 1402 max_sequence(anonce, snonce, 32), 1403 32); 1404 ieee80211_prf(pmk, crypt_data, prf_result, hash_sel); 1405 memcpy(ptk, prf_result, ptk_key_length); 1406 } 1407 1408 /* Compute MIC of key frame data from KCK part of PTK. */ 1409 uint8_t mic[SHA1_HASH_LENGTH]; 1410 hmac(ptk, 16, (uint8_t *) output_key_frame, 1411 output_size - sizeof(eth_header_t), mic, hash_sel); 1412 1413 memcpy(output_key_frame->key_mic, mic, 16); 1414 1415 ieee80211_send_frame(nic, output_buffer, output_size); 1416 1417 free(output_buffer); 1418 1419 if(handshake_done) { 1420 /* Insert keys into device. */ 1421 1422 /* Pairwise key. */ 1423 ieee80211_key_config_t key_config; 1424 key_config.suite = auth_data->security.pair_alg; 1425 key_config.flags = 1426 IEEE80211_KEY_FLAG_TYPE_PAIRWISE; 1427 memcpy(key_config.data, 1428 ptk + TK_OFFSET, 1429 ptk_key_length - TK_OFFSET); 1430 1431 ieee80211_dev->ops->key_config(ieee80211_dev, 1432 &key_config, true); 1433 1434 /* Group key. */ 1435 key_config.suite = auth_data->security.group_alg; 1436 key_config.flags = 1437 IEEE80211_KEY_FLAG_TYPE_GROUP; 1438 memcpy(key_config.data, gtk, gtk_key_length); 1439 1440 ieee80211_dev->ops->key_config(ieee80211_dev, 1441 &key_config, true); 1442 1443 /* Signal successful handshake completion. */ 1444 fibril_mutex_lock(&ieee80211_dev->gen_mutex); 1445 fibril_condvar_signal(&ieee80211_dev->gen_cond); 1446 fibril_mutex_unlock(&ieee80211_dev->gen_mutex); 1447 } 1448 1449 return EOK; 1450 } 1451 1452 static int ieee80211_process_eapol_frame(ieee80211_dev_t *ieee80211_dev, 1453 void *buffer, size_t buffer_size) 1454 { 1455 ieee80211_eapol_key_frame_t *key_frame = 1456 (ieee80211_eapol_key_frame_t *) buffer; 1457 if(ieee80211_is_eapol_key_frame(key_frame)) { 1458 return ieee80211_process_4way_handshake(ieee80211_dev, buffer, 1459 buffer_size); 1460 } 1461 1462 return EOK; 1463 } 1464 1465 /** 1466 * Process data frame. 1467 * 1468 * @param ieee80211_dev Pointer to IEEE 802.11 device structure. 1469 * @param buffer Data buffer starting with IEEE 802.11 data header. 1470 * @param buffer_size Size of buffer. 1471 * 1472 * @return EOK if succeed, negative error code otherwise. 1473 */ 1474 static int ieee80211_process_data(ieee80211_dev_t *ieee80211_dev, 1475 void *buffer, size_t buffer_size) 1476 { 1477 ieee80211_data_header_t *data_header = 1478 (ieee80211_data_header_t *) buffer; 1479 1480 if(ieee80211_has_data_frame(data_header->frame_ctrl)) { 1481 nic_t *nic = nic_get_from_ddf_dev(ieee80211_dev->ddf_dev); 1482 size_t strip_length = sizeof(ieee80211_data_header_t) + 1483 ARRAY_SIZE(rfc1042_header); 1484 1485 /* TODO: Probably different by used security alg. */ 1486 if(ieee80211_is_encrypted_frame(data_header->frame_ctrl)) { 1487 strip_length += 8; 1488 } 1489 1490 /* Process 4-way authentication handshake. */ 1491 uint16_t *proto = (uint16_t *) (buffer + strip_length); 1492 if(uint16_t_be2host(*proto) == ETH_TYPE_PAE) { 1493 return ieee80211_process_eapol_frame(ieee80211_dev, 1494 buffer + strip_length + sizeof(uint16_t), 1495 buffer_size - strip_length - sizeof(uint16_t)); 1496 } 1497 1498 /* Note: ETH protocol ID is already there, so we don't create 1499 * whole ETH header. */ 1500 size_t frame_size = 1501 buffer_size - strip_length + sizeof(eth_header_t)-2; 1502 nic_frame_t *frame = nic_alloc_frame(nic, frame_size); 1503 1504 if(frame == NULL) { 1505 return ENOMEM; 1506 } 1507 1508 uint8_t *src_addr = 1509 ieee80211_is_fromds_frame(data_header->frame_ctrl) ? 1510 data_header->address3 : data_header->address2; 1511 uint8_t *dest_addr = 1512 ieee80211_is_tods_frame(data_header->frame_ctrl) ? 1513 data_header->address3 : data_header->address1; 1514 1515 eth_header_t *eth_header = 1516 (eth_header_t *) frame->data; 1517 memcpy(eth_header->src_addr, src_addr, ETH_ADDR); 1518 memcpy(eth_header->dest_addr, dest_addr, ETH_ADDR); 1519 1520 memcpy(frame->data + sizeof(eth_header_t)-2, 1521 buffer + strip_length, 1522 buffer_size - strip_length); 1523 1524 nic_received_frame(nic, frame); 525 1525 } 526 1526 … … 548 1548 ieee80211_is_beacon_frame(mgmt_header->frame_ctrl)) { 549 1549 return ieee80211_process_probe_response(ieee80211_dev, 1550 mgmt_header, buffer_size); 1551 } 1552 1553 if(ieee80211_is_auth_frame(mgmt_header->frame_ctrl)) { 1554 return ieee80211_process_auth_response(ieee80211_dev, 550 1555 mgmt_header); 551 1556 } 552 // TODO 1557 1558 if(ieee80211_is_assoc_response_frame(mgmt_header->frame_ctrl)) { 1559 return ieee80211_process_assoc_response(ieee80211_dev, 1560 mgmt_header); 1561 } 553 1562 } else if(ieee80211_is_data_frame(frame_ctrl)) { 554 nic_t *nic = nic_get_from_ddf_dev(ieee80211_dev->ddf_dev); 555 size_t frame_size = buffer_size - sizeof(ieee80211_data_header_t); 556 nic_frame_t *frame = nic_alloc_frame(nic, frame_size); 557 if (frame != NULL) { 558 memcpy(frame->data, 559 buffer + sizeof(ieee80211_data_header_t), 560 frame_size); 561 nic_received_frame(nic, frame); 562 } 563 } else { 564 // TODO 1563 return ieee80211_process_data(ieee80211_dev, buffer, 1564 buffer_size); 565 1565 } 566 1566
Note:
See TracChangeset
for help on using the changeset viewer.