aboutsummaryrefslogtreecommitdiffstats
path: root/net/ieee80211
diff options
context:
space:
mode:
Diffstat (limited to 'net/ieee80211')
-rw-r--r--net/ieee80211/ieee80211_rx.c314
1 files changed, 134 insertions, 180 deletions
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
index fcf05bf677b8..6b005cb0caa0 100644
--- a/net/ieee80211/ieee80211_rx.c
+++ b/net/ieee80211/ieee80211_rx.c
@@ -917,174 +917,24 @@ static int ieee80211_parse_qos_info_param_IE(struct ieee80211_info_element
917 return rc; 917 return rc;
918} 918}
919 919
920static int ieee80211_handle_assoc_resp(struct ieee80211_device *ieee, struct ieee80211_assoc_response 920static int ieee80211_parse_info_param(struct ieee80211_info_element
921 *frame, struct ieee80211_rx_stats *stats) 921 *info_element, u16 length,
922{ 922 struct ieee80211_network *network)
923 struct ieee80211_network network_resp;
924 struct ieee80211_network *network = &network_resp;
925 struct ieee80211_info_element *info_element;
926 struct net_device *dev = ieee->dev;
927 u16 left;
928
929 network->flags = 0;
930 network->qos_data.active = 0;
931 network->qos_data.supported = 0;
932 network->qos_data.param_count = 0;
933 network->qos_data.old_param_count = 0;
934
935 //network->atim_window = le16_to_cpu(frame->aid) & (0x3FFF);
936 network->atim_window = le16_to_cpu(frame->aid);
937 network->listen_interval = le16_to_cpu(frame->status);
938
939 info_element = frame->info_element;
940 left = stats->len - sizeof(*frame);
941
942 while (left >= sizeof(struct ieee80211_info_element)) {
943 if (sizeof(struct ieee80211_info_element) +
944 info_element->len > left) {
945 IEEE80211_DEBUG_QOS("ASSOC RESP: parse failed: "
946 "info_element->len + 2 > left : "
947 "info_element->len+2=%zd left=%d, id=%d.\n",
948 info_element->len +
949 sizeof(struct
950 ieee80211_info_element),
951 left, info_element->id);
952 return 1;
953 }
954
955 switch (info_element->id) {
956 case MFIE_TYPE_SSID:
957 if (ieee80211_is_empty_essid(info_element->data,
958 info_element->len)) {
959 network->flags |= NETWORK_EMPTY_ESSID;
960 break;
961 }
962
963 network->ssid_len = min(info_element->len,
964 (u8) IW_ESSID_MAX_SIZE);
965 memcpy(network->ssid, info_element->data,
966 network->ssid_len);
967 if (network->ssid_len < IW_ESSID_MAX_SIZE)
968 memset(network->ssid + network->ssid_len, 0,
969 IW_ESSID_MAX_SIZE - network->ssid_len);
970
971 IEEE80211_DEBUG_QOS("MFIE_TYPE_SSID: '%s' len=%d.\n",
972 network->ssid, network->ssid_len);
973 break;
974
975 case MFIE_TYPE_TIM:
976 IEEE80211_DEBUG_QOS("MFIE_TYPE_TIM: ignored\n");
977 break;
978
979 case MFIE_TYPE_IBSS_SET:
980 IEEE80211_DEBUG_QOS("MFIE_TYPE_IBSS_SET: ignored\n");
981 break;
982
983 case MFIE_TYPE_CHALLENGE:
984 IEEE80211_DEBUG_QOS("MFIE_TYPE_CHALLENGE: ignored\n");
985 break;
986
987 case MFIE_TYPE_GENERIC:
988 IEEE80211_DEBUG_QOS("MFIE_TYPE_GENERIC: %d bytes\n",
989 info_element->len);
990 ieee80211_parse_qos_info_param_IE(info_element,
991 network);
992 break;
993
994 case MFIE_TYPE_RSN:
995 IEEE80211_DEBUG_QOS("MFIE_TYPE_RSN: %d bytes\n",
996 info_element->len);
997 break;
998
999 case MFIE_TYPE_QOS_PARAMETER:
1000 printk("QoS Error need to parse QOS_PARAMETER IE\n");
1001 break;
1002
1003 default:
1004 IEEE80211_DEBUG_QOS("unsupported IE %d\n",
1005 info_element->id);
1006 break;
1007 }
1008
1009 left -= sizeof(struct ieee80211_info_element) +
1010 info_element->len;
1011 info_element = (struct ieee80211_info_element *)
1012 &info_element->data[info_element->len];
1013 }
1014
1015 if (ieee->handle_assoc_response != NULL)
1016 ieee->handle_assoc_response(dev, frame, network);
1017
1018 return 0;
1019}
1020
1021/***************************************************/
1022
1023static inline int ieee80211_is_ofdm_rate(u8 rate)
1024{
1025 switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
1026 case IEEE80211_OFDM_RATE_6MB:
1027 case IEEE80211_OFDM_RATE_9MB:
1028 case IEEE80211_OFDM_RATE_12MB:
1029 case IEEE80211_OFDM_RATE_18MB:
1030 case IEEE80211_OFDM_RATE_24MB:
1031 case IEEE80211_OFDM_RATE_36MB:
1032 case IEEE80211_OFDM_RATE_48MB:
1033 case IEEE80211_OFDM_RATE_54MB:
1034 return 1;
1035 }
1036 return 0;
1037}
1038
1039static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct ieee80211_probe_response
1040 *beacon,
1041 struct ieee80211_network *network,
1042 struct ieee80211_rx_stats *stats)
1043{ 923{
924 u8 i;
1044#ifdef CONFIG_IEEE80211_DEBUG 925#ifdef CONFIG_IEEE80211_DEBUG
1045 char rates_str[64]; 926 char rates_str[64];
1046 char *p; 927 char *p;
1047#endif 928#endif
1048 struct ieee80211_info_element *info_element;
1049 u16 left;
1050 u8 i;
1051 network->qos_data.active = 0;
1052 network->qos_data.supported = 0;
1053 network->qos_data.param_count = 0;
1054
1055 /* Pull out fixed field data */
1056 memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
1057 network->capability = le16_to_cpu(beacon->capability);
1058 network->last_scanned = jiffies;
1059 network->time_stamp[0] = le32_to_cpu(beacon->time_stamp[0]);
1060 network->time_stamp[1] = le32_to_cpu(beacon->time_stamp[1]);
1061 network->beacon_interval = le16_to_cpu(beacon->beacon_interval);
1062 /* Where to pull this? beacon->listen_interval; */
1063 network->listen_interval = 0x0A;
1064 network->rates_len = network->rates_ex_len = 0;
1065 network->last_associate = 0;
1066 network->ssid_len = 0;
1067 network->flags = 0;
1068 network->atim_window = 0;
1069 network->erp_value = (network->capability & WLAN_CAPABILITY_IBSS) ?
1070 0x3 : 0x0;
1071 929
1072 if (stats->freq == IEEE80211_52GHZ_BAND) { 930 while (length >= sizeof(*info_element)) {
1073 /* for A band (No DS info) */ 931 if (sizeof(*info_element) + info_element->len > length) {
1074 network->channel = stats->received_channel; 932 IEEE80211_DEBUG_MGMT("Info elem: parse failed: "
1075 } else 933 "info_element->len + 2 > left : "
1076 network->flags |= NETWORK_HAS_CCK; 934 "info_element->len+2=%zd left=%d, id=%d.\n",
1077 935 info_element->len +
1078 network->wpa_ie_len = 0; 936 sizeof(*info_element),
1079 network->rsn_ie_len = 0; 937 length, info_element->id);
1080
1081 info_element = beacon->info_element;
1082 left = stats->len - sizeof(*beacon);
1083 while (left >= sizeof(*info_element)) {
1084 if (sizeof(*info_element) + info_element->len > left) {
1085 IEEE80211_DEBUG_SCAN
1086 ("SCAN: parse failed: info_element->len + 2 > left : info_element->len+2=%Zd left=%d.\n",
1087 info_element->len + sizeof(*info_element), left);
1088 return 1; 938 return 1;
1089 } 939 }
1090 940
@@ -1104,7 +954,7 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct i
1104 memset(network->ssid + network->ssid_len, 0, 954 memset(network->ssid + network->ssid_len, 0,
1105 IW_ESSID_MAX_SIZE - network->ssid_len); 955 IW_ESSID_MAX_SIZE - network->ssid_len);
1106 956
1107 IEEE80211_DEBUG_SCAN("MFIE_TYPE_SSID: '%s' len=%d.\n", 957 IEEE80211_DEBUG_MGMT("MFIE_TYPE_SSID: '%s' len=%d.\n",
1108 network->ssid, network->ssid_len); 958 network->ssid, network->ssid_len);
1109 break; 959 break;
1110 960
@@ -1131,7 +981,7 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct i
1131 } 981 }
1132 } 982 }
1133 983
1134 IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES: '%s' (%d)\n", 984 IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES: '%s' (%d)\n",
1135 rates_str, network->rates_len); 985 rates_str, network->rates_len);
1136 break; 986 break;
1137 987
@@ -1158,47 +1008,46 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct i
1158 } 1008 }
1159 } 1009 }
1160 1010
1161 IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES_EX: '%s' (%d)\n", 1011 IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
1162 rates_str, network->rates_ex_len); 1012 rates_str, network->rates_ex_len);
1163 break; 1013 break;
1164 1014
1165 case MFIE_TYPE_DS_SET: 1015 case MFIE_TYPE_DS_SET:
1166 IEEE80211_DEBUG_SCAN("MFIE_TYPE_DS_SET: %d\n", 1016 IEEE80211_DEBUG_MGMT("MFIE_TYPE_DS_SET: %d\n",
1167 info_element->data[0]); 1017 info_element->data[0]);
1168 if (stats->freq == IEEE80211_24GHZ_BAND) 1018 network->channel = info_element->data[0];
1169 network->channel = info_element->data[0];
1170 break; 1019 break;
1171 1020
1172 case MFIE_TYPE_FH_SET: 1021 case MFIE_TYPE_FH_SET:
1173 IEEE80211_DEBUG_SCAN("MFIE_TYPE_FH_SET: ignored\n"); 1022 IEEE80211_DEBUG_MGMT("MFIE_TYPE_FH_SET: ignored\n");
1174 break; 1023 break;
1175 1024
1176 case MFIE_TYPE_CF_SET: 1025 case MFIE_TYPE_CF_SET:
1177 IEEE80211_DEBUG_SCAN("MFIE_TYPE_CF_SET: ignored\n"); 1026 IEEE80211_DEBUG_MGMT("MFIE_TYPE_CF_SET: ignored\n");
1178 break; 1027 break;
1179 1028
1180 case MFIE_TYPE_TIM: 1029 case MFIE_TYPE_TIM:
1181 IEEE80211_DEBUG_SCAN("MFIE_TYPE_TIM: ignored\n"); 1030 IEEE80211_DEBUG_MGMT("MFIE_TYPE_TIM: ignored\n");
1182 break; 1031 break;
1183 1032
1184 case MFIE_TYPE_ERP_INFO: 1033 case MFIE_TYPE_ERP_INFO:
1185 network->erp_value = info_element->data[0]; 1034 network->erp_value = info_element->data[0];
1186 IEEE80211_DEBUG_SCAN("MFIE_TYPE_ERP_SET: %d\n", 1035 IEEE80211_DEBUG_MGMT("MFIE_TYPE_ERP_SET: %d\n",
1187 network->erp_value); 1036 network->erp_value);
1188 break; 1037 break;
1189 1038
1190 case MFIE_TYPE_IBSS_SET: 1039 case MFIE_TYPE_IBSS_SET:
1191 network->atim_window = info_element->data[0]; 1040 network->atim_window = info_element->data[0];
1192 IEEE80211_DEBUG_SCAN("MFIE_TYPE_IBSS_SET: %d\n", 1041 IEEE80211_DEBUG_MGMT("MFIE_TYPE_IBSS_SET: %d\n",
1193 network->atim_window); 1042 network->atim_window);
1194 break; 1043 break;
1195 1044
1196 case MFIE_TYPE_CHALLENGE: 1045 case MFIE_TYPE_CHALLENGE:
1197 IEEE80211_DEBUG_SCAN("MFIE_TYPE_CHALLENGE: ignored\n"); 1046 IEEE80211_DEBUG_MGMT("MFIE_TYPE_CHALLENGE: ignored\n");
1198 break; 1047 break;
1199 1048
1200 case MFIE_TYPE_GENERIC: 1049 case MFIE_TYPE_GENERIC:
1201 IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n", 1050 IEEE80211_DEBUG_MGMT("MFIE_TYPE_GENERIC: %d bytes\n",
1202 info_element->len); 1051 info_element->len);
1203 if (!ieee80211_parse_qos_info_param_IE(info_element, 1052 if (!ieee80211_parse_qos_info_param_IE(info_element,
1204 network)) 1053 network))
@@ -1217,7 +1066,7 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct i
1217 break; 1066 break;
1218 1067
1219 case MFIE_TYPE_RSN: 1068 case MFIE_TYPE_RSN:
1220 IEEE80211_DEBUG_SCAN("MFIE_TYPE_RSN: %d bytes\n", 1069 IEEE80211_DEBUG_MGMT("MFIE_TYPE_RSN: %d bytes\n",
1221 info_element->len); 1070 info_element->len);
1222 network->rsn_ie_len = min(info_element->len + 2, 1071 network->rsn_ie_len = min(info_element->len + 2,
1223 MAX_WPA_IE_LEN); 1072 MAX_WPA_IE_LEN);
@@ -1231,16 +1080,121 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct i
1231 break; 1080 break;
1232 1081
1233 default: 1082 default:
1234 IEEE80211_DEBUG_SCAN("unsupported IE %d\n", 1083 IEEE80211_DEBUG_MGMT("unsupported IE %d\n",
1235 info_element->id); 1084 info_element->id);
1236 break; 1085 break;
1237 } 1086 }
1238 1087
1239 left -= sizeof(*info_element) + info_element->len; 1088 length -= sizeof(*info_element) + info_element->len;
1240 info_element = (struct ieee80211_info_element *) 1089 info_element =
1241 &info_element->data[info_element->len]; 1090 (struct ieee80211_info_element *)&info_element->
1091 data[info_element->len];
1092 }
1093
1094 return 0;
1095}
1096
1097static int ieee80211_handle_assoc_resp(struct ieee80211_device *ieee, struct ieee80211_assoc_response
1098 *frame, struct ieee80211_rx_stats *stats)
1099{
1100 struct ieee80211_network network_resp;
1101 struct ieee80211_network *network = &network_resp;
1102 struct net_device *dev = ieee->dev;
1103
1104 network->flags = 0;
1105 network->qos_data.active = 0;
1106 network->qos_data.supported = 0;
1107 network->qos_data.param_count = 0;
1108 network->qos_data.old_param_count = 0;
1109
1110 //network->atim_window = le16_to_cpu(frame->aid) & (0x3FFF);
1111 network->atim_window = le16_to_cpu(frame->aid);
1112 network->listen_interval = le16_to_cpu(frame->status);
1113 memcpy(network->bssid, frame->header.addr3, ETH_ALEN);
1114 network->capability = le16_to_cpu(frame->capability);
1115 network->last_scanned = jiffies;
1116 network->rates_len = network->rates_ex_len = 0;
1117 network->last_associate = 0;
1118 network->ssid_len = 0;
1119 network->erp_value =
1120 (network->capability & WLAN_CAPABILITY_IBSS) ? 0x3 : 0x0;
1121
1122 if (stats->freq == IEEE80211_52GHZ_BAND) {
1123 /* for A band (No DS info) */
1124 network->channel = stats->received_channel;
1125 } else
1126 network->flags |= NETWORK_HAS_CCK;
1127
1128 network->wpa_ie_len = 0;
1129 network->rsn_ie_len = 0;
1130
1131 if (ieee80211_parse_info_param
1132 (frame->info_element, stats->len - sizeof(*frame), network))
1133 return 1;
1134
1135 network->mode = 0;
1136 if (stats->freq == IEEE80211_52GHZ_BAND)
1137 network->mode = IEEE_A;
1138 else {
1139 if (network->flags & NETWORK_HAS_OFDM)
1140 network->mode |= IEEE_G;
1141 if (network->flags & NETWORK_HAS_CCK)
1142 network->mode |= IEEE_B;
1242 } 1143 }
1243 1144
1145 if (ieee80211_is_empty_essid(network->ssid, network->ssid_len))
1146 network->flags |= NETWORK_EMPTY_ESSID;
1147
1148 memcpy(&network->stats, stats, sizeof(network->stats));
1149
1150 if (ieee->handle_assoc_response != NULL)
1151 ieee->handle_assoc_response(dev, frame, network);
1152
1153 return 0;
1154}
1155
1156/***************************************************/
1157
1158static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct ieee80211_probe_response
1159 *beacon,
1160 struct ieee80211_network *network,
1161 struct ieee80211_rx_stats *stats)
1162{
1163 network->qos_data.active = 0;
1164 network->qos_data.supported = 0;
1165 network->qos_data.param_count = 0;
1166 network->qos_data.old_param_count = 0;
1167
1168 /* Pull out fixed field data */
1169 memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
1170 network->capability = le16_to_cpu(beacon->capability);
1171 network->last_scanned = jiffies;
1172 network->time_stamp[0] = le32_to_cpu(beacon->time_stamp[0]);
1173 network->time_stamp[1] = le32_to_cpu(beacon->time_stamp[1]);
1174 network->beacon_interval = le16_to_cpu(beacon->beacon_interval);
1175 /* Where to pull this? beacon->listen_interval; */
1176 network->listen_interval = 0x0A;
1177 network->rates_len = network->rates_ex_len = 0;
1178 network->last_associate = 0;
1179 network->ssid_len = 0;
1180 network->flags = 0;
1181 network->atim_window = 0;
1182 network->erp_value = (network->capability & WLAN_CAPABILITY_IBSS) ?
1183 0x3 : 0x0;
1184
1185 if (stats->freq == IEEE80211_52GHZ_BAND) {
1186 /* for A band (No DS info) */
1187 network->channel = stats->received_channel;
1188 } else
1189 network->flags |= NETWORK_HAS_CCK;
1190
1191 network->wpa_ie_len = 0;
1192 network->rsn_ie_len = 0;
1193
1194 if (ieee80211_parse_info_param
1195 (beacon->info_element, stats->len - sizeof(*beacon), network))
1196 return 1;
1197
1244 network->mode = 0; 1198 network->mode = 0;
1245 if (stats->freq == IEEE80211_52GHZ_BAND) 1199 if (stats->freq == IEEE80211_52GHZ_BAND)
1246 network->mode = IEEE_A; 1200 network->mode = IEEE_A;