Changes in uspace/lib/ieee80211/src/ieee80211.c [1b20da0:a35b458] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/ieee80211/src/ieee80211.c
r1b20da0 ra35b458 72 72 { 73 73 frame_ctrl = uint16_t_le2host(frame_ctrl); 74 74 75 75 return (frame_ctrl & IEEE80211_FRAME_CTRL_FRAME_TYPE) == 76 76 IEEE80211_DATA_FRAME; … … 87 87 { 88 88 frame_ctrl = uint16_t_le2host(frame_ctrl); 89 89 90 90 return (frame_ctrl & IEEE80211_FRAME_CTRL_FRAME_TYPE) == 91 91 IEEE80211_MGMT_FRAME; … … 102 102 { 103 103 frame_ctrl = uint16_t_le2host(frame_ctrl); 104 104 105 105 return (frame_ctrl & IEEE80211_FRAME_CTRL_FRAME_SUBTYPE) == 106 106 IEEE80211_MGMT_BEACON_FRAME; … … 117 117 { 118 118 frame_ctrl = uint16_t_le2host(frame_ctrl); 119 119 120 120 return (frame_ctrl & IEEE80211_FRAME_CTRL_FRAME_SUBTYPE) == 121 121 IEEE80211_MGMT_PROBE_RESP_FRAME; … … 132 132 { 133 133 frame_ctrl = uint16_t_le2host(frame_ctrl); 134 134 135 135 return (frame_ctrl & IEEE80211_FRAME_CTRL_FRAME_SUBTYPE) == 136 136 IEEE80211_MGMT_AUTH_FRAME; … … 147 147 { 148 148 frame_ctrl = uint16_t_le2host(frame_ctrl); 149 149 150 150 return (frame_ctrl & IEEE80211_FRAME_CTRL_FRAME_SUBTYPE) == 151 151 IEEE80211_MGMT_ASSOC_RESP_FRAME; … … 162 162 { 163 163 frame_ctrl = uint16_t_le2host(frame_ctrl); 164 164 165 165 return (frame_ctrl & IEEE80211_FRAME_CTRL_TODS); 166 166 } … … 176 176 { 177 177 frame_ctrl = uint16_t_le2host(frame_ctrl); 178 178 179 179 return (frame_ctrl & IEEE80211_FRAME_CTRL_FROMDS); 180 180 } … … 190 190 { 191 191 frame_ctrl = uint16_t_le2host(frame_ctrl); 192 192 193 193 return (frame_ctrl & (IEEE80211_FRAME_CTRL_FRAME_TYPE | 0x40)) == 194 194 IEEE80211_DATA_FRAME; … … 205 205 { 206 206 frame_ctrl = uint16_t_le2host(frame_ctrl); 207 207 208 208 return (frame_ctrl & IEEE80211_FRAME_CTRL_PROTECTED); 209 209 } … … 233 233 uint16_t ret_val = ieee80211_dev->sequence_number; 234 234 ieee80211_dev->sequence_number += (1 << 4); 235 235 236 236 return ret_val; 237 237 } … … 286 286 ieee80211_operating_mode_t op_mode = ieee80211_dev->current_op_mode; 287 287 fibril_mutex_unlock(&ieee80211_dev->gen_mutex); 288 288 289 289 return op_mode; 290 290 } … … 302 302 uint16_t current_freq = ieee80211_dev->current_freq; 303 303 fibril_mutex_unlock(&ieee80211_dev->gen_mutex); 304 304 305 305 return current_freq; 306 306 } … … 318 318 { 319 319 fibril_mutex_lock(&ieee80211_dev->gen_mutex); 320 320 321 321 if (bssid) { 322 322 ieee80211_scan_result_link_t *res_link = 323 323 ieee80211_dev->bssid_info.res_link; 324 324 325 325 if (res_link) { 326 326 memcpy(bssid, &res_link->scan_result.bssid, … … 333 333 } 334 334 } 335 335 336 336 fibril_mutex_unlock(&ieee80211_dev->gen_mutex); 337 337 } … … 349 349 uint16_t aid = ieee80211_dev->bssid_info.aid; 350 350 fibril_mutex_unlock(&ieee80211_dev->gen_mutex); 351 351 352 352 return aid; 353 353 } … … 367 367 int suite = auth_link->scan_result.security.pair_alg; 368 368 fibril_mutex_unlock(&ieee80211_dev->gen_mutex); 369 369 370 370 return suite; 371 371 } … … 384 384 ieee80211_dev->current_auth_phase == IEEE80211_AUTH_CONNECTED; 385 385 fibril_mutex_unlock(&ieee80211_dev->gen_mutex); 386 386 387 387 return conn_state; 388 388 } … … 401 401 ieee80211_auth_phase_t conn_state = ieee80211_dev->current_auth_phase; 402 402 fibril_mutex_unlock(&ieee80211_dev->gen_mutex); 403 403 404 404 return conn_state; 405 405 } … … 418 418 ieee80211_dev->pending_conn_req = false; 419 419 fibril_mutex_unlock(&ieee80211_dev->gen_mutex); 420 420 421 421 return conn_request; 422 422 } … … 462 462 bool ready_state = ieee80211_dev->ready; 463 463 fibril_mutex_unlock(&ieee80211_dev->gen_mutex); 464 464 465 465 return ready_state; 466 466 } … … 484 484 bool using_key = ieee80211_dev->using_hw_key; 485 485 fibril_mutex_unlock(&ieee80211_dev->gen_mutex); 486 486 487 487 return using_key; 488 488 } … … 499 499 { 500 500 assert(arg); 501 501 502 502 ieee80211_dev_t *ieee80211_dev = (ieee80211_dev_t *) arg; 503 503 504 504 while (true) { 505 505 ieee80211_dev->ops->scan(ieee80211_dev); 506 506 async_usleep(SCAN_PERIOD_USEC); 507 507 } 508 508 509 509 return EOK; 510 510 } … … 521 521 nic_t *nic_data = nic_get_from_ddf_fun(fun); 522 522 ieee80211_dev_t *ieee80211_dev = nic_get_specific(nic_data); 523 523 524 524 if (ieee80211_dev->started) 525 525 return EOK; 526 526 527 527 ieee80211_dev->started = true; 528 528 529 529 errno_t rc = ieee80211_dev->ops->start(ieee80211_dev); 530 530 if (rc != EOK) 531 531 return rc; 532 532 533 533 /* Add scanning fibril. */ 534 534 fid_t fibril = fibril_create(ieee80211_scan, ieee80211_dev); 535 535 if (fibril == 0) 536 536 return ENOMEM; 537 537 538 538 fibril_add_ready(fibril); 539 539 540 540 return EOK; 541 541 } … … 552 552 ieee80211_dev_t *ieee80211_dev = (ieee80211_dev_t *) 553 553 nic_get_specific(nic); 554 554 555 555 ieee80211_auth_phase_t auth_phase = 556 556 ieee80211_get_auth_phase(ieee80211_dev); … … 558 558 (auth_phase != IEEE80211_AUTH_CONNECTED)) 559 559 return; 560 560 561 561 ieee80211_scan_result_t *auth_data = 562 562 &ieee80211_dev->bssid_info.res_link->scan_result; 563 563 564 564 /* We drop part of IEEE 802.3 ethernet header. */ 565 565 size_t drop_bytes = sizeof(eth_header_t) - 2; 566 566 567 567 size_t complete_size = (size - drop_bytes) + 568 568 sizeof(ieee80211_data_header_t) + 569 569 ARRAY_SIZE(rfc1042_header); 570 570 571 571 /* Init crypto data. */ 572 572 bool add_mic = false; … … 575 575 uint8_t head_data[head_space]; 576 576 memset(head_data, 0, head_space); 577 577 578 578 // TODO: Distinguish used key (pair/group) by dest address ? 579 579 if (ieee80211_query_using_key(ieee80211_dev)) { … … 592 592 break; 593 593 } 594 594 595 595 crypto = uint16_t_le2host(IEEE80211_FRAME_CTRL_PROTECTED); 596 596 } 597 597 598 598 complete_size += head_space + mic_space; 599 599 600 600 void *complete_buffer = malloc(complete_size); 601 601 if (!complete_buffer) 602 602 return; 603 603 604 604 memset(complete_buffer, 0, complete_size); 605 605 606 606 if (head_space) 607 607 memcpy(complete_buffer + sizeof(ieee80211_data_header_t), 608 608 head_data, head_space); 609 609 610 610 memcpy(complete_buffer + sizeof(ieee80211_data_header_t) + head_space, 611 611 rfc1042_header, ARRAY_SIZE(rfc1042_header)); 612 612 613 613 memcpy(complete_buffer + sizeof(ieee80211_data_header_t) + 614 614 ARRAY_SIZE(rfc1042_header) + head_space, 615 615 data + drop_bytes, size - drop_bytes); 616 616 617 617 ieee80211_data_header_t *data_header = 618 618 (ieee80211_data_header_t *) complete_buffer; … … 623 623 crypto; 624 624 data_header->seq_ctrl = ieee80211_get_sequence_number(ieee80211_dev); 625 625 626 626 /* BSSID, SA, DA. */ 627 627 memcpy(data_header->address1, auth_data->bssid.address, ETH_ADDR); 628 628 memcpy(data_header->address2, data + ETH_ADDR, ETH_ADDR); 629 629 memcpy(data_header->address3, data, ETH_ADDR); 630 630 631 631 if (add_mic) { 632 632 size_t size_wo_mic = complete_size - MIC_LENGTH; … … 636 636 complete_buffer + size_wo_mic); 637 637 } 638 638 639 639 ieee80211_dev->ops->tx_handler(ieee80211_dev, 640 640 complete_buffer, complete_size); 641 641 642 642 free(complete_buffer); 643 643 } … … 662 662 if (!ieee80211_ops->start) 663 663 ieee80211_ops->start = ieee80211_start_impl; 664 664 665 665 if (!ieee80211_ops->tx_handler) 666 666 ieee80211_ops->tx_handler = ieee80211_tx_handler_impl; 667 667 668 668 if (!ieee80211_ops->set_freq) 669 669 ieee80211_ops->set_freq = ieee80211_set_freq_impl; 670 670 671 671 if (!ieee80211_ops->bssid_change) 672 672 ieee80211_ops->bssid_change = ieee80211_bssid_change_impl; 673 673 674 674 if (!ieee80211_ops->key_config) 675 675 ieee80211_ops->key_config = ieee80211_key_config_impl; 676 676 677 677 if (!ieee80211_ops->scan) 678 678 ieee80211_ops->scan = ieee80211_scan_impl; 679 679 } else 680 680 return EINVAL; 681 681 682 682 ieee80211_dev->ops = ieee80211_ops; 683 683 684 684 if (ieee80211_iface) { 685 685 if (nic_dev_ops) … … 687 687 nic_dev_ops->interfaces[IEEE80211_DEV_IFACE] = 688 688 ieee80211_iface; 689 689 690 690 if (!ieee80211_iface->get_scan_results) 691 691 ieee80211_iface->get_scan_results = 692 692 ieee80211_get_scan_results_impl; 693 693 694 694 if (!ieee80211_iface->connect) 695 695 ieee80211_iface->connect = ieee80211_connect_impl; 696 696 697 697 if (!ieee80211_iface->disconnect) 698 698 ieee80211_iface->disconnect = ieee80211_disconnect_impl; 699 699 } else 700 700 return EINVAL; 701 701 702 702 if (nic_dev_ops) { 703 703 if (!nic_dev_ops->open) … … 705 705 } else 706 706 return EINVAL; 707 707 708 708 ieee80211_dev->iface = ieee80211_iface; 709 709 710 710 nic_driver_implement(NULL, nic_dev_ops, nic_iface); 711 711 712 712 return EOK; 713 713 } … … 740 740 ieee80211_dev->current_op_mode = IEEE80211_OPMODE_STATION; 741 741 ieee80211_dev->current_auth_phase = IEEE80211_AUTH_DISCONNECTED; 742 742 743 743 memcpy(ieee80211_dev->bssid_mask.address, ieee80211_broadcast_mac_addr, 744 744 ETH_ADDR); 745 745 746 746 ieee80211_scan_result_list_init(&ieee80211_dev->ap_list); 747 747 748 748 fibril_mutex_initialize(&ieee80211_dev->scan_mutex); 749 749 fibril_mutex_initialize(&ieee80211_dev->gen_mutex); 750 750 fibril_condvar_initialize(&ieee80211_dev->gen_cond); 751 751 752 752 /* Bind NIC to device */ 753 753 nic_t *nic = nic_create_and_bind(ddf_dev); 754 754 if (!nic) 755 755 return ENOMEM; 756 756 757 757 nic_set_specific(nic, ieee80211_dev); 758 758 759 759 return EOK; 760 760 } … … 780 780 if (rc != EOK) 781 781 return rc; 782 782 783 783 nic_t *nic = nic_get_from_ddf_dev(ieee80211_dev->ddf_dev); 784 784 785 785 /* TODO: Set NIC handlers here. */ 786 786 nic_set_send_frame_handler(nic, ieee80211_send_frame); 787 787 788 788 ddf_fun_t *fun = ddf_fun_create(ieee80211_dev->ddf_dev, fun_exposed, 789 789 "port0"); 790 790 if (fun == NULL) 791 791 return EINVAL; 792 792 793 793 nic_set_ddf_fun(nic, fun); 794 794 ddf_fun_set_ops(fun, ieee80211_nic_dev_ops); 795 795 796 796 rc = ddf_fun_bind(fun); 797 797 if (rc != EOK) { … … 799 799 return rc; 800 800 } 801 801 802 802 rc = ddf_fun_add_to_category(fun, DEVICE_CATEGORY_NIC); 803 803 if (rc != EOK) { … … 805 805 return rc; 806 806 } 807 807 808 808 rc = ddf_fun_add_to_category(fun, DEVICE_CATEGORY_IEEE80211); 809 809 if (rc != EOK) { … … 811 811 return rc; 812 812 } 813 813 814 814 return EOK; 815 815 } … … 832 832 ieee80211_ie_header_t *header = 833 833 (ieee80211_ie_header_t *) *ie_header; 834 834 835 835 header->element_id = id; 836 836 header->length = length; 837 837 838 838 memcpy(*ie_header + sizeof(ieee80211_ie_header_t), data, length); 839 839 840 840 *ie_header = (void *) ((void *) header + 841 841 sizeof(ieee80211_ie_header_t) + length); … … 855 855 nic_address_t nic_address; 856 856 nic_query_address(nic, &nic_address); 857 857 858 858 size_t ssid_data_size = (ssid != NULL) ? str_size(ssid) : 0; 859 859 size_t channel_data_size = 1; 860 860 861 861 uint8_t channel = 862 862 ieee80211_freq_to_channel(ieee80211_dev->current_freq); 863 863 864 864 /* 865 865 * 4 headers - (ssid, rates, ext rates, current channel) … … 871 871 IEEE80211_DATA_RATES_SIZE + IEEE80211_EXT_DATA_RATES_SIZE + 872 872 channel_data_size; 873 873 874 874 size_t buffer_size = sizeof(ieee80211_mgmt_header_t) + payload_size; 875 875 void *buffer = malloc(buffer_size); 876 876 if (!buffer) 877 877 return ENOMEM; 878 878 879 879 memset(buffer, 0, buffer_size); 880 880 881 881 ieee80211_mgmt_header_t *mgmt_header = 882 882 (ieee80211_mgmt_header_t *) buffer; 883 883 884 884 mgmt_header->frame_ctrl = 885 885 host2uint16_t_le(IEEE80211_MGMT_FRAME | … … 890 890 mgmt_header->seq_ctrl = 891 891 host2uint16_t_le(ieee80211_get_sequence_number(ieee80211_dev)); 892 892 893 893 /* Jump to payload. */ 894 894 void *it = (void *) buffer + sizeof(ieee80211_mgmt_header_t); … … 902 902 ieee80211_prepare_ie_header(&it, IEEE80211_CHANNEL_IE, 903 903 channel_data_size, (void *) &channel); 904 904 905 905 ieee80211_dev->ops->tx_handler(ieee80211_dev, buffer, buffer_size); 906 906 907 907 free(buffer); 908 908 909 909 return EOK; 910 910 } … … 922 922 nic_address_t nic_address; 923 923 nic_query_address(nic, &nic_address); 924 924 925 925 ieee80211_scan_result_t *auth_data = 926 926 &ieee80211_dev->bssid_info.res_link->scan_result; 927 927 928 928 size_t buffer_size = sizeof(ieee80211_mgmt_header_t) + 929 929 sizeof(ieee80211_auth_body_t); 930 930 931 931 void *buffer = malloc(buffer_size); 932 932 if (!buffer) 933 933 return ENOMEM; 934 934 935 935 memset(buffer, 0, buffer_size); 936 936 937 937 ieee80211_mgmt_header_t *mgmt_header = 938 938 (ieee80211_mgmt_header_t *) buffer; 939 939 940 940 mgmt_header->frame_ctrl = 941 941 host2uint16_t_le(IEEE80211_MGMT_FRAME | … … 944 944 memcpy(mgmt_header->src_addr, nic_address.address, ETH_ADDR); 945 945 memcpy(mgmt_header->bssid, auth_data->bssid.address, ETH_ADDR); 946 946 947 947 ieee80211_auth_body_t *auth_body = 948 948 (ieee80211_auth_body_t *) … … 950 950 auth_body->auth_alg = host2uint16_t_le(0); 951 951 auth_body->auth_trans_no = host2uint16_t_le(1); 952 952 953 953 ieee80211_dev->ops->tx_handler(ieee80211_dev, buffer, buffer_size); 954 954 955 955 free(buffer); 956 956 957 957 return EOK; 958 958 } … … 972 972 nic_address_t nic_address; 973 973 nic_query_address(nic, &nic_address); 974 974 975 975 ieee80211_scan_result_link_t *auth_link = 976 976 ieee80211_dev->bssid_info.res_link; 977 977 978 978 ieee80211_scan_result_t *auth_data = &auth_link->scan_result; 979 979 980 980 size_t ssid_data_size = str_size(auth_data->ssid); 981 981 982 982 size_t payload_size = 983 983 sizeof(ieee80211_ie_header_t) * 3 + … … 985 985 IEEE80211_DATA_RATES_SIZE + 986 986 IEEE80211_EXT_DATA_RATES_SIZE; 987 987 988 988 size_t buffer_size = 989 989 sizeof(ieee80211_mgmt_header_t) + 990 990 sizeof(ieee80211_assoc_req_body_t) + 991 991 payload_size; 992 992 993 993 if ((auth_data->security.type == IEEE80211_SECURITY_WPA) || 994 994 (auth_data->security.type == IEEE80211_SECURITY_WPA2)) 995 995 buffer_size += auth_link->auth_ie_len; 996 996 997 997 void *buffer = malloc(buffer_size); 998 998 if (!buffer) 999 999 return ENOMEM; 1000 1000 1001 1001 memset(buffer, 0, buffer_size); 1002 1002 1003 1003 ieee80211_mgmt_header_t *mgmt_header = 1004 1004 (ieee80211_mgmt_header_t *) buffer; 1005 1005 1006 1006 mgmt_header->frame_ctrl = 1007 1007 host2uint16_t_le(IEEE80211_MGMT_FRAME | … … 1010 1010 memcpy(mgmt_header->src_addr, nic_address.address, ETH_ADDR); 1011 1011 memcpy(mgmt_header->bssid, auth_data->bssid.address, ETH_ADDR); 1012 1012 1013 1013 ieee80211_assoc_req_body_t *assoc_body = 1014 1014 (ieee80211_assoc_req_body_t *) 1015 1015 (buffer + sizeof(ieee80211_mgmt_header_t)); 1016 1016 assoc_body->listen_interval = host2uint16_t_le(1); 1017 1017 1018 1018 /* Jump to payload. */ 1019 1019 void *it = buffer + sizeof(ieee80211_mgmt_header_t) + … … 1026 1026 IEEE80211_EXT_DATA_RATES_SIZE, 1027 1027 (void *) &ieee80211bg_data_rates[IEEE80211_DATA_RATES_SIZE]); 1028 1028 1029 1029 if (auth_data->security.type != IEEE80211_SECURITY_OPEN) 1030 1030 assoc_body->capability |= host2uint16_t_le(CAP_SECURITY); 1031 1031 1032 1032 if ((auth_data->security.type == IEEE80211_SECURITY_WPA) || 1033 1033 (auth_data->security.type == IEEE80211_SECURITY_WPA2)) 1034 1034 memcpy(it, auth_link->auth_ie, auth_link->auth_ie_len); 1035 1035 1036 1036 ieee80211_dev->ops->tx_handler(ieee80211_dev, buffer, buffer_size); 1037 1037 1038 1038 /* 1039 1039 * Save password to be used in eventual authentication handshake. … … 1042 1042 memcpy(ieee80211_dev->bssid_info.password, password, 1043 1043 str_size(password)); 1044 1044 1045 1045 free(buffer); 1046 1046 1047 1047 return EOK; 1048 1048 } … … 1061 1061 ieee80211_scan_result_t *auth_data = 1062 1062 &ieee80211_dev->bssid_info.res_link->scan_result; 1063 1063 1064 1064 nic_t *nic = nic_get_from_ddf_dev(ieee80211_dev->ddf_dev); 1065 1065 nic_address_t nic_address; 1066 1066 nic_query_address(nic, &nic_address); 1067 1067 1068 1068 size_t buffer_size = sizeof(ieee80211_mgmt_header_t) + 1069 1069 sizeof(ieee80211_deauth_body_t); 1070 1070 1071 1071 void *buffer = malloc(buffer_size); 1072 1072 if (!buffer) 1073 1073 return ENOMEM; 1074 1074 1075 1075 memset(buffer, 0, buffer_size); 1076 1076 1077 1077 ieee80211_mgmt_header_t *mgmt_header = 1078 1078 (ieee80211_mgmt_header_t *) buffer; 1079 1079 1080 1080 mgmt_header->frame_ctrl = 1081 1081 host2uint16_t_le(IEEE80211_MGMT_FRAME | … … 1084 1084 memcpy(mgmt_header->src_addr, nic_address.address, ETH_ADDR); 1085 1085 memcpy(mgmt_header->bssid, auth_data->bssid.address, ETH_ADDR); 1086 1086 1087 1087 ieee80211_dev->ops->tx_handler(ieee80211_dev, buffer, buffer_size); 1088 1088 1089 1089 free(buffer); 1090 1090 1091 1091 ieee80211_dev->bssid_info.res_link = NULL; 1092 1092 ieee80211_dev->ops->bssid_change(ieee80211_dev, false); 1093 1093 1094 1094 if (ieee80211_query_using_key(ieee80211_dev)) 1095 1095 ieee80211_dev->ops->key_config(ieee80211_dev, NULL, false); 1096 1096 1097 1097 ieee80211_set_auth_phase(ieee80211_dev, IEEE80211_AUTH_DISCONNECTED); 1098 1098 1099 1099 return EOK; 1100 1100 } … … 1104 1104 { 1105 1105 uint8_t *it = (uint8_t *) buffer; 1106 1106 1107 1107 uint16_t *version = (uint16_t *) it; 1108 1108 if (uint16_t_le2host(*version) != 0x1) { … … 1110 1110 return; 1111 1111 } 1112 1112 1113 1113 it += sizeof(uint16_t); 1114 1114 1115 1115 uint32_t group_cipher = *(it + 3); 1116 1116 switch (group_cipher) { … … 1126 1126 ap_data->scan_result.security.group_alg = -1; 1127 1127 } 1128 1128 1129 1129 it += 4 * sizeof(uint8_t); 1130 1130 1131 1131 uint16_t *pairwise_count = (uint16_t *) it; 1132 1132 uint32_t pairwise_cipher = *(it + sizeof(uint16_t) + 3); … … 1143 1143 ap_data->scan_result.security.pair_alg = -1; 1144 1144 } 1145 1145 1146 1146 it += 2 * sizeof(uint16_t) + 1147 1147 uint16_t_le2host(*pairwise_count) * sizeof(uint32_t); 1148 1148 1149 1149 uint32_t auth_suite = *(it + 3); 1150 1150 switch (auth_suite) { … … 1167 1167 ap_data->auth_ie_len = ie_header->length + 1168 1168 sizeof(ieee80211_ie_header_t); 1169 1169 1170 1170 memcpy(ap_data->auth_ie, it, ap_data->auth_ie_len); 1171 1171 } … … 1180 1180 uint8_t *channel; 1181 1181 uint32_t oui; 1182 1182 1183 1183 switch (ie_header->element_id) { 1184 1184 case IEEE80211_CHANNEL_IE: 1185 1185 if (!ap_data) 1186 1186 break; 1187 1187 1188 1188 channel = (uint8_t *) 1189 1189 (it + sizeof(ieee80211_ie_header_t)); … … 1193 1193 if (!ap_data) 1194 1194 break; 1195 1195 1196 1196 ap_data->scan_result.security.type = 1197 1197 IEEE80211_SECURITY_WPA2; … … 1203 1203 oui = uint32be_from_seq(it + 1204 1204 sizeof(ieee80211_ie_header_t)); 1205 1205 1206 1206 if (oui == WPA_OUI) { 1207 1207 if (!ap_data) 1208 1208 break; 1209 1209 1210 1210 /* Prefering WPA2. */ 1211 1211 if (ap_data->scan_result.security.type == 1212 1212 IEEE80211_SECURITY_WPA2) 1213 1213 break; 1214 1214 1215 1215 ap_data->scan_result.security.type = 1216 1216 IEEE80211_SECURITY_WPA; 1217 1217 1218 1218 ieee80211_process_auth_info(ap_data, 1219 1219 it + sizeof(ieee80211_ie_header_t) + … … 1226 1226 } 1227 1227 } 1228 1228 1229 1229 it += sizeof(ieee80211_ie_header_t) + ie_header->length; 1230 1230 } 1231 1231 1232 1232 return NULL; 1233 1233 } … … 1246 1246 ieee80211_beacon_start_t *beacon_body = (ieee80211_beacon_start_t *) 1247 1247 ((void *) mgmt_header + sizeof(ieee80211_mgmt_header_t)); 1248 1248 1249 1249 ieee80211_ie_header_t *ssid_ie_header = (ieee80211_ie_header_t *) 1250 1250 ((void *) beacon_body + sizeof(ieee80211_beacon_start_t)); 1251 1251 1252 1252 /* Not empty SSID. */ 1253 1253 if (ssid_ie_header->length > 0) { 1254 1254 ieee80211_scan_result_list_t *result_list = 1255 1255 &ieee80211_dev->ap_list; 1256 1256 1257 1257 uint8_t *ssid_start = (uint8_t *) ((void *) ssid_ie_header + 1258 1258 sizeof(ieee80211_ie_header_t)); 1259 1259 char ssid[IEEE80211_MAX_SSID_LENGTH]; 1260 1260 1261 1261 memcpy(ssid, ssid_start, ssid_ie_header->length); 1262 1262 ssid[ssid_ie_header->length] = '\0'; 1263 1263 1264 1264 /* Check whether SSID is already in results. */ 1265 1265 ieee80211_scan_result_list_foreach(*result_list, result) { … … 1269 1269 } 1270 1270 } 1271 1271 1272 1272 /* Results are full. */ 1273 1273 if (result_list->size == IEEE80211_MAX_RESULTS_LENGTH - 1) 1274 1274 return EOK; 1275 1275 1276 1276 ieee80211_scan_result_link_t *ap_data = 1277 1277 malloc(sizeof(ieee80211_scan_result_link_t)); 1278 1278 if (!ap_data) 1279 1279 return ENOMEM; 1280 1280 1281 1281 memset(ap_data, 0, sizeof(ieee80211_scan_result_link_t)); 1282 1282 link_initialize(&ap_data->link); 1283 1283 1284 1284 memcpy(ap_data->scan_result.bssid.address, 1285 1285 mgmt_header->bssid, ETH_ADDR); 1286 1286 memcpy(ap_data->scan_result.ssid, ssid, 1287 1287 ssid_ie_header->length + 1); 1288 1288 1289 1289 if (uint16_t_le2host(beacon_body->capability) & CAP_SECURITY) { 1290 1290 ap_data->scan_result.security.type = … … 1297 1297 ap_data->scan_result.security.group_alg = -1; 1298 1298 } 1299 1299 1300 1300 void *rest_ies_start = ssid_start + ssid_ie_header->length; 1301 1301 size_t rest_buffer_size = … … 1305 1305 sizeof(ieee80211_ie_header_t) - 1306 1306 ssid_ie_header->length; 1307 1307 1308 1308 ieee80211_process_ies(ieee80211_dev, ap_data, rest_ies_start, 1309 1309 rest_buffer_size); 1310 1310 1311 1311 ap_data->last_beacon = time(NULL); 1312 1312 1313 1313 fibril_mutex_lock(&ieee80211_dev->ap_list.results_mutex); 1314 1314 ieee80211_scan_result_list_append(result_list, ap_data); 1315 1315 fibril_mutex_unlock(&ieee80211_dev->ap_list.results_mutex); 1316 1316 } 1317 1317 1318 1318 return EOK; 1319 1319 } … … 1333 1333 (ieee80211_auth_body_t *) 1334 1334 ((void *) mgmt_header + sizeof(ieee80211_mgmt_header_t)); 1335 1335 1336 1336 if (auth_body->status != 0) 1337 1337 ieee80211_set_auth_phase(ieee80211_dev, … … 1340 1340 ieee80211_set_auth_phase(ieee80211_dev, 1341 1341 IEEE80211_AUTH_AUTHENTICATED); 1342 1342 1343 1343 fibril_mutex_lock(&ieee80211_dev->gen_mutex); 1344 1344 fibril_condvar_signal(&ieee80211_dev->gen_cond); 1345 1345 fibril_mutex_unlock(&ieee80211_dev->gen_mutex); 1346 1346 1347 1347 return EOK; 1348 1348 } … … 1362 1362 (ieee80211_assoc_resp_body_t *) ((void *) mgmt_header + 1363 1363 sizeof(ieee80211_mgmt_header_t)); 1364 1364 1365 1365 if (assoc_resp->status != 0) 1366 1366 ieee80211_set_auth_phase(ieee80211_dev, … … 1373 1373 ieee80211_dev->ops->bssid_change(ieee80211_dev, true); 1374 1374 } 1375 1375 1376 1376 fibril_mutex_lock(&ieee80211_dev->gen_mutex); 1377 1377 fibril_condvar_signal(&ieee80211_dev->gen_cond); 1378 1378 fibril_mutex_unlock(&ieee80211_dev->gen_mutex); 1379 1379 1380 1380 return EOK; 1381 1381 } … … 1386 1386 ieee80211_eapol_key_frame_t *key_frame = 1387 1387 (ieee80211_eapol_key_frame_t *) buffer; 1388 1388 1389 1389 ieee80211_scan_result_link_t *auth_link = 1390 1390 ieee80211_dev->bssid_info.res_link; 1391 1391 1392 1392 ieee80211_scan_result_t *auth_data = &auth_link->scan_result; 1393 1393 1394 1394 /* We don't support 802.1X authentication yet. */ 1395 1395 if (auth_data->security.auth == IEEE80211_AUTH_AKM_8021X) 1396 1396 return ENOTSUP; 1397 1397 1398 1398 uint8_t *ptk = ieee80211_dev->bssid_info.ptk; 1399 1399 uint8_t *gtk = ieee80211_dev->bssid_info.gtk; 1400 1400 uint8_t gtk_id = 1; 1401 1401 1402 1402 bool handshake_done = false; 1403 1403 1404 1404 bool old_wpa = 1405 1405 auth_data->security.type == IEEE80211_SECURITY_WPA; 1406 1406 1407 1407 bool key_phase = 1408 1408 uint16_t_be2host(key_frame->key_info) & 1409 1409 IEEE80211_EAPOL_KEY_KEYINFO_MIC; 1410 1410 1411 1411 bool final_phase = 1412 1412 uint16_t_be2host(key_frame->key_info) & 1413 1413 IEEE80211_EAPOL_KEY_KEYINFO_SECURE; 1414 1414 1415 1415 bool ccmp_used = 1416 1416 (auth_data->security.pair_alg == IEEE80211_SECURITY_SUITE_CCMP) || 1417 1417 (auth_data->security.group_alg == IEEE80211_SECURITY_SUITE_CCMP); 1418 1418 1419 1419 size_t ptk_key_length, gtk_key_length; 1420 1420 hash_func_t mic_hash; … … 1423 1423 else 1424 1424 mic_hash = HASH_MD5; 1425 1425 1426 1426 if (auth_data->security.pair_alg == IEEE80211_SECURITY_SUITE_CCMP) 1427 1427 ptk_key_length = IEEE80211_PTK_CCMP_LENGTH; 1428 1428 else 1429 1429 ptk_key_length = IEEE80211_PTK_TKIP_LENGTH; 1430 1430 1431 1431 if (auth_data->security.group_alg == IEEE80211_SECURITY_SUITE_CCMP) 1432 1432 gtk_key_length = IEEE80211_GTK_CCMP_LENGTH; 1433 1433 else 1434 1434 gtk_key_length = IEEE80211_GTK_TKIP_LENGTH; 1435 1435 1436 1436 size_t output_size = 1437 1437 sizeof(eth_header_t) + 1438 1438 sizeof(ieee80211_eapol_key_frame_t); 1439 1439 1440 1440 if (!(uint16_t_be2host(key_frame->key_info) & 1441 1441 IEEE80211_EAPOL_KEY_KEYINFO_MIC)) 1442 1442 output_size += auth_link->auth_ie_len; 1443 1443 1444 1444 nic_t *nic = nic_get_from_ddf_dev(ieee80211_dev->ddf_dev); 1445 1445 nic_address_t nic_address; 1446 1446 nic_query_address(nic, &nic_address); 1447 1447 1448 1448 void *output_buffer = malloc(output_size); 1449 1449 if (!output_buffer) 1450 1450 return ENOMEM; 1451 1451 1452 1452 memset(output_buffer, 0, output_size); 1453 1453 1454 1454 /* Setup ethernet header. */ 1455 1455 eth_header_t *eth_header = (eth_header_t *) output_buffer; … … 1457 1457 memcpy(eth_header->src_addr, nic_address.address, ETH_ADDR); 1458 1458 eth_header->proto = host2uint16_t_be(ETH_TYPE_PAE); 1459 1459 1460 1460 ieee80211_eapol_key_frame_t *output_key_frame = 1461 1461 (ieee80211_eapol_key_frame_t *) 1462 1462 (output_buffer + sizeof(eth_header_t)); 1463 1463 1464 1464 /* Copy content of incoming EAPOL-Key frame. */ 1465 1465 memcpy((void *) output_key_frame, buffer, 1466 1466 sizeof(ieee80211_eapol_key_frame_t)); 1467 1467 1468 1468 output_key_frame->proto_version = 0x1; 1469 1469 output_key_frame->body_length = … … 1471 1471 output_key_frame->key_info &= 1472 1472 ~host2uint16_t_be(IEEE80211_EAPOL_KEY_KEYINFO_ACK); 1473 1473 1474 1474 if (key_phase) { 1475 1475 output_key_frame->key_info &= … … 1482 1482 memset(output_key_frame->key_rsc, 0, 8); 1483 1483 memset(output_key_frame->eapol_key_iv, 0, 16); 1484 1484 1485 1485 /* Derive GTK and save it. */ 1486 1486 if (final_phase) { … … 1490 1490 uint8_t *data_ptr = (uint8_t *) 1491 1491 (buffer + sizeof(ieee80211_eapol_key_frame_t)); 1492 1492 1493 1493 errno_t rc; 1494 1494 uint8_t work_key[32]; 1495 1495 1496 1496 if (ccmp_used) { 1497 1497 rc = ieee80211_aes_key_unwrap(ptk + KEK_OFFSET, … … 1503 1503 data_ptr, key_data_length, key_data); 1504 1504 } 1505 1505 1506 1506 if (rc == EOK) { 1507 1507 uint8_t *key_data_ptr = old_wpa ? key_data : 1508 1508 ieee80211_process_ies(ieee80211_dev, 1509 1509 NULL, key_data, key_data_length); 1510 1510 1511 1511 if (key_data_ptr) { 1512 1512 uint8_t *key_ptr; 1513 1513 1514 1514 if (old_wpa) 1515 1515 key_ptr = key_data_ptr; … … 1518 1518 key_ptr = key_data_ptr + 2; 1519 1519 } 1520 1520 1521 1521 memcpy(gtk, key_ptr, gtk_key_length); 1522 1522 handshake_done = true; … … 1532 1532 sizeof(ieee80211_eapol_key_frame_t), 1533 1533 auth_link->auth_ie, auth_link->auth_ie_len); 1534 1534 1535 1535 /* Compute PMK. */ 1536 1536 uint8_t pmk[PBKDF2_KEY_LENGTH]; … … 1539 1539 (uint8_t *) auth_data->ssid, 1540 1540 str_size(auth_data->ssid), pmk); 1541 1541 1542 1542 uint8_t *anonce = key_frame->key_nonce; 1543 1543 1544 1544 /* Generate SNONCE. */ 1545 1545 uint8_t snonce[32]; 1546 1546 rnd_sequence(snonce, 32); 1547 1547 1548 1548 memcpy(output_key_frame->key_nonce, snonce, 32); 1549 1549 1550 1550 uint8_t *dest_addr = eth_header->dest_addr; 1551 1551 uint8_t *src_addr = eth_header->src_addr; 1552 1552 1553 1553 /* Derive PTK and save it. */ 1554 1554 uint8_t crypt_data[PRF_CRYPT_DATA_LENGTH]; … … 1563 1563 ieee80211_prf(pmk, crypt_data, ptk, ptk_key_length); 1564 1564 } 1565 1565 1566 1566 /* Compute MIC of key frame data from KCK part of PTK. */ 1567 1567 uint8_t mic[mic_hash]; 1568 1568 hmac(ptk, 16, (uint8_t *) output_key_frame, 1569 1569 output_size - sizeof(eth_header_t), mic, mic_hash); 1570 1570 1571 1571 memcpy(output_key_frame->key_mic, mic, 16); 1572 1572 1573 1573 ieee80211_send_frame(nic, output_buffer, output_size); 1574 1574 1575 1575 free(output_buffer); 1576 1576 1577 1577 ieee80211_key_config_t key_config; 1578 1578 1579 1579 /* Insert Pairwise key. */ 1580 1580 if ((key_phase && old_wpa) || (final_phase && !old_wpa)) { … … 1584 1584 memcpy(key_config.data, 1585 1585 ptk + TK_OFFSET, ptk_key_length - TK_OFFSET); 1586 1586 1587 1587 ieee80211_dev->ops->key_config(ieee80211_dev, 1588 1588 &key_config, true); 1589 1589 } 1590 1590 1591 1591 /* Insert Group key. */ 1592 1592 if (final_phase) { … … 1595 1595 key_config.flags = IEEE80211_KEY_FLAG_TYPE_GROUP; 1596 1596 memcpy(key_config.data, gtk, gtk_key_length); 1597 1597 1598 1598 ieee80211_dev->ops->key_config(ieee80211_dev, 1599 1599 &key_config, true); 1600 1600 } 1601 1601 1602 1602 /* Signal successful handshake completion. */ 1603 1603 if (handshake_done) { … … 1606 1606 fibril_mutex_unlock(&ieee80211_dev->gen_mutex); 1607 1607 } 1608 1608 1609 1609 return EOK; 1610 1610 } … … 1615 1615 ieee80211_eapol_key_frame_t *key_frame = 1616 1616 (ieee80211_eapol_key_frame_t *) buffer; 1617 1617 1618 1618 if (ieee80211_is_eapol_key_frame(key_frame)) 1619 1619 return ieee80211_process_4way_handshake(ieee80211_dev, buffer, 1620 1620 buffer_size); 1621 1621 1622 1622 return EOK; 1623 1623 } … … 1637 1637 ieee80211_data_header_t *data_header = 1638 1638 (ieee80211_data_header_t *) buffer; 1639 1639 1640 1640 if (ieee80211_has_data_frame(data_header->frame_ctrl)) { 1641 1641 nic_t *nic = nic_get_from_ddf_dev(ieee80211_dev->ddf_dev); 1642 1642 size_t strip_length = sizeof(ieee80211_data_header_t) + 1643 1643 ARRAY_SIZE(rfc1042_header); 1644 1644 1645 1645 /* TODO: Different by used security alg. */ 1646 1646 /* TODO: Trim frame by used security alg. */ … … 1648 1648 if (ieee80211_is_encrypted_frame(data_header->frame_ctrl)) 1649 1649 strip_length += 8; 1650 1650 1651 1651 /* Process 4-way authentication handshake. */ 1652 1652 uint16_t *proto = (uint16_t *) (buffer + strip_length); … … 1655 1655 buffer + strip_length + sizeof(uint16_t), 1656 1656 buffer_size - strip_length - sizeof(uint16_t)); 1657 1657 1658 1658 /* 1659 1659 * Note: ETH protocol ID is already there, so we don't create … … 1663 1663 buffer_size - strip_length + sizeof(eth_header_t) - 2; 1664 1664 nic_frame_t *frame = nic_alloc_frame(nic, frame_size); 1665 1665 1666 1666 if(frame == NULL) 1667 1667 return ENOMEM; 1668 1668 1669 1669 uint8_t *src_addr = 1670 1670 ieee80211_is_fromds_frame(data_header->frame_ctrl) ? … … 1673 1673 ieee80211_is_tods_frame(data_header->frame_ctrl) ? 1674 1674 data_header->address3 : data_header->address1; 1675 1675 1676 1676 eth_header_t *eth_header = (eth_header_t *) frame->data; 1677 1677 memcpy(eth_header->src_addr, src_addr, ETH_ADDR); 1678 1678 memcpy(eth_header->dest_addr, dest_addr, ETH_ADDR); 1679 1679 1680 1680 memcpy(frame->data + sizeof(eth_header_t) - 2, 1681 1681 buffer + strip_length, buffer_size - strip_length); 1682 1682 1683 1683 nic_received_frame(nic, frame); 1684 1684 } 1685 1685 1686 1686 return EOK; 1687 1687 } … … 1700 1700 { 1701 1701 uint16_t frame_ctrl = *((uint16_t *) buffer); 1702 1702 1703 1703 if (ieee80211_is_mgmt_frame(frame_ctrl)) { 1704 1704 ieee80211_mgmt_header_t *mgmt_header = 1705 1705 (ieee80211_mgmt_header_t *) buffer; 1706 1706 1707 1707 if ((ieee80211_is_probe_response_frame(mgmt_header->frame_ctrl)) || 1708 1708 (ieee80211_is_beacon_frame(mgmt_header->frame_ctrl))) 1709 1709 return ieee80211_process_probe_response(ieee80211_dev, 1710 1710 mgmt_header, buffer_size); 1711 1711 1712 1712 if (ieee80211_is_auth_frame(mgmt_header->frame_ctrl)) 1713 1713 return ieee80211_process_auth_response(ieee80211_dev, 1714 1714 mgmt_header); 1715 1715 1716 1716 if (ieee80211_is_assoc_response_frame(mgmt_header->frame_ctrl)) 1717 1717 return ieee80211_process_assoc_response(ieee80211_dev, … … 1720 1720 return ieee80211_process_data(ieee80211_dev, buffer, 1721 1721 buffer_size); 1722 1722 1723 1723 return EOK; 1724 1724 }
Note:
See TracChangeset
for help on using the changeset viewer.