aboutsummaryrefslogtreecommitdiffstats
path: root/net/ieee80211/ieee80211_rx.c
diff options
context:
space:
mode:
authorIvo van Doorn <IvDoorn@gmail.com>2005-10-03 11:19:25 -0400
committerJames Ketrenos <jketreno@linux.intel.com>2005-10-03 11:19:25 -0400
commitff9e00f1b09d594004f91700a371870f729ffc02 (patch)
tree44977fc59711d89871d69e3169f8bc2b2cc2b55e /net/ieee80211/ieee80211_rx.c
parente846cbb11245e648983b50349a1c715202d5ccf0 (diff)
Currently the info_element is parsed by 2 seperate functions, this
results in a lot of duplicate code. This will move the parsing stage into a seperate function. Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: James Ketrenos <jketreno@linux.intel.com>
Diffstat (limited to 'net/ieee80211/ieee80211_rx.c')
-rw-r--r--net/ieee80211/ieee80211_rx.c267
1 files changed, 99 insertions, 168 deletions
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
index 2f4b16c1c14..3bf04d6d2b1 100644
--- a/net/ieee80211/ieee80211_rx.c
+++ b/net/ieee80211/ieee80211_rx.c
@@ -917,158 +917,23 @@ 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 *info_element,
921 *frame, struct ieee80211_rx_stats *stats) 921 u16 length, struct ieee80211_network *network)
922{
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_network_init(struct ieee80211_device *ieee, struct ieee80211_probe_response
1024 *beacon,
1025 struct ieee80211_network *network,
1026 struct ieee80211_rx_stats *stats)
1027{ 922{
923 u8 i;
1028#ifdef CONFIG_IEEE80211_DEBUG 924#ifdef CONFIG_IEEE80211_DEBUG
1029 char rates_str[64]; 925 char rates_str[64];
1030 char *p; 926 char *p;
1031#endif 927#endif
1032 struct ieee80211_info_element *info_element;
1033 u16 left;
1034 u8 i;
1035 network->qos_data.active = 0;
1036 network->qos_data.supported = 0;
1037 network->qos_data.param_count = 0;
1038 928
1039 /* Pull out fixed field data */ 929 while (length >= sizeof(*info_element)) {
1040 memcpy(network->bssid, beacon->header.addr3, ETH_ALEN); 930 if (sizeof(*info_element) + info_element->len > length) {
1041 network->capability = le16_to_cpu(beacon->capability); 931 IEEE80211_DEBUG_MGMT("Info elem: parse failed: "
1042 network->last_scanned = jiffies; 932 "info_element->len + 2 > left : "
1043 network->time_stamp[0] = le32_to_cpu(beacon->time_stamp[0]); 933 "info_element->len+2=%zd left=%d, id=%d.\n",
1044 network->time_stamp[1] = le32_to_cpu(beacon->time_stamp[1]); 934 info_element->len +
1045 network->beacon_interval = le16_to_cpu(beacon->beacon_interval); 935 sizeof(*info_element),
1046 /* Where to pull this? beacon->listen_interval; */ 936 length, info_element->id);
1047 network->listen_interval = 0x0A;
1048 network->rates_len = network->rates_ex_len = 0;
1049 network->last_associate = 0;
1050 network->ssid_len = 0;
1051 network->flags = 0;
1052 network->atim_window = 0;
1053 network->erp_value = (network->capability & WLAN_CAPABILITY_IBSS) ?
1054 0x3 : 0x0;
1055
1056 if (stats->freq == IEEE80211_52GHZ_BAND) {
1057 /* for A band (No DS info) */
1058 network->channel = stats->received_channel;
1059 } else
1060 network->flags |= NETWORK_HAS_CCK;
1061
1062 network->wpa_ie_len = 0;
1063 network->rsn_ie_len = 0;
1064
1065 info_element = beacon->info_element;
1066 left = stats->len - sizeof(*beacon);
1067 while (left >= sizeof(*info_element)) {
1068 if (sizeof(*info_element) + info_element->len > left) {
1069 IEEE80211_DEBUG_SCAN
1070 ("SCAN: parse failed: info_element->len + 2 > left : info_element->len+2=%Zd left=%d.\n",
1071 info_element->len + sizeof(*info_element), left);
1072 return 1; 937 return 1;
1073 } 938 }
1074 939
@@ -1088,8 +953,8 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct i
1088 memset(network->ssid + network->ssid_len, 0, 953 memset(network->ssid + network->ssid_len, 0,
1089 IW_ESSID_MAX_SIZE - network->ssid_len); 954 IW_ESSID_MAX_SIZE - network->ssid_len);
1090 955
1091 IEEE80211_DEBUG_SCAN("MFIE_TYPE_SSID: '%s' len=%d.\n", 956 IEEE80211_DEBUG_MGMT("MFIE_TYPE_SSID: '%s' len=%d.\n",
1092 network->ssid, network->ssid_len); 957 network->ssid, network->ssid_len);
1093 break; 958 break;
1094 959
1095 case MFIE_TYPE_RATES: 960 case MFIE_TYPE_RATES:
@@ -1115,7 +980,7 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct i
1115 } 980 }
1116 } 981 }
1117 982
1118 IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES: '%s' (%d)\n", 983 IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES: '%s' (%d)\n",
1119 rates_str, network->rates_len); 984 rates_str, network->rates_len);
1120 break; 985 break;
1121 986
@@ -1142,47 +1007,46 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct i
1142 } 1007 }
1143 } 1008 }
1144 1009
1145 IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES_EX: '%s' (%d)\n", 1010 IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
1146 rates_str, network->rates_ex_len); 1011 rates_str, network->rates_ex_len);
1147 break; 1012 break;
1148 1013
1149 case MFIE_TYPE_DS_SET: 1014 case MFIE_TYPE_DS_SET:
1150 IEEE80211_DEBUG_SCAN("MFIE_TYPE_DS_SET: %d\n", 1015 IEEE80211_DEBUG_MGMT("MFIE_TYPE_DS_SET: %d\n",
1151 info_element->data[0]); 1016 info_element->data[0]);
1152 if (stats->freq == IEEE80211_24GHZ_BAND) 1017 network->channel = info_element->data[0];
1153 network->channel = info_element->data[0];
1154 break; 1018 break;
1155 1019
1156 case MFIE_TYPE_FH_SET: 1020 case MFIE_TYPE_FH_SET:
1157 IEEE80211_DEBUG_SCAN("MFIE_TYPE_FH_SET: ignored\n"); 1021 IEEE80211_DEBUG_MGMT("MFIE_TYPE_FH_SET: ignored\n");
1158 break; 1022 break;
1159 1023
1160 case MFIE_TYPE_CF_SET: 1024 case MFIE_TYPE_CF_SET:
1161 IEEE80211_DEBUG_SCAN("MFIE_TYPE_CF_SET: ignored\n"); 1025 IEEE80211_DEBUG_MGMT("MFIE_TYPE_CF_SET: ignored\n");
1162 break; 1026 break;
1163 1027
1164 case MFIE_TYPE_TIM: 1028 case MFIE_TYPE_TIM:
1165 IEEE80211_DEBUG_SCAN("MFIE_TYPE_TIM: ignored\n"); 1029 IEEE80211_DEBUG_MGMT("MFIE_TYPE_TIM: ignored\n");
1166 break; 1030 break;
1167 1031
1168 case MFIE_TYPE_ERP_INFO: 1032 case MFIE_TYPE_ERP_INFO:
1169 network->erp_value = info_element->data[0]; 1033 network->erp_value = info_element->data[0];
1170 IEEE80211_DEBUG_SCAN("MFIE_TYPE_ERP_SET: %d\n", 1034 IEEE80211_DEBUG_MGMT("MFIE_TYPE_ERP_SET: %d\n",
1171 network->erp_value); 1035 network->erp_value);
1172 break; 1036 break;
1173 1037
1174 case MFIE_TYPE_IBSS_SET: 1038 case MFIE_TYPE_IBSS_SET:
1175 network->atim_window = info_element->data[0]; 1039 network->atim_window = info_element->data[0];
1176 IEEE80211_DEBUG_SCAN("MFIE_TYPE_IBSS_SET: %d\n", 1040 IEEE80211_DEBUG_MGMT("MFIE_TYPE_IBSS_SET: %d\n",
1177 network->atim_window); 1041 network->atim_window);
1178 break; 1042 break;
1179 1043
1180 case MFIE_TYPE_CHALLENGE: 1044 case MFIE_TYPE_CHALLENGE:
1181 IEEE80211_DEBUG_SCAN("MFIE_TYPE_CHALLENGE: ignored\n"); 1045 IEEE80211_DEBUG_MGMT("MFIE_TYPE_CHALLENGE: ignored\n");
1182 break; 1046 break;
1183 1047
1184 case MFIE_TYPE_GENERIC: 1048 case MFIE_TYPE_GENERIC:
1185 IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n", 1049 IEEE80211_DEBUG_MGMT("MFIE_TYPE_GENERIC: %d bytes\n",
1186 info_element->len); 1050 info_element->len);
1187 if (!ieee80211_parse_qos_info_param_IE(info_element, 1051 if (!ieee80211_parse_qos_info_param_IE(info_element,
1188 network)) 1052 network))
@@ -1201,7 +1065,7 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct i
1201 break; 1065 break;
1202 1066
1203 case MFIE_TYPE_RSN: 1067 case MFIE_TYPE_RSN:
1204 IEEE80211_DEBUG_SCAN("MFIE_TYPE_RSN: %d bytes\n", 1068 IEEE80211_DEBUG_MGMT("MFIE_TYPE_RSN: %d bytes\n",
1205 info_element->len); 1069 info_element->len);
1206 network->rsn_ie_len = min(info_element->len + 2, 1070 network->rsn_ie_len = min(info_element->len + 2,
1207 MAX_WPA_IE_LEN); 1071 MAX_WPA_IE_LEN);
@@ -1210,21 +1074,88 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct i
1210 break; 1074 break;
1211 1075
1212 case MFIE_TYPE_QOS_PARAMETER: 1076 case MFIE_TYPE_QOS_PARAMETER:
1213 printk(KERN_ERR 1077 printk(KERN_ERR "QoS Error need to parse QOS_PARAMETER IE\n");
1214 "QoS Error need to parse QOS_PARAMETER IE\n");
1215 break; 1078 break;
1216 1079
1217 default: 1080 default:
1218 IEEE80211_DEBUG_SCAN("unsupported IE %d\n", 1081 IEEE80211_DEBUG_MGMT("unsupported IE %d\n",
1219 info_element->id); 1082 info_element->id);
1220 break; 1083 break;
1221 } 1084 }
1222 1085
1223 left -= sizeof(*info_element) + info_element->len; 1086 length -= sizeof(*info_element) + info_element->len;
1224 info_element = (struct ieee80211_info_element *) 1087 info_element = (struct ieee80211_info_element *) &info_element->data[info_element->len];
1225 &info_element->data[info_element->len];
1226 } 1088 }
1227 1089
1090 return 0;
1091}
1092
1093static int ieee80211_handle_assoc_resp(struct ieee80211_device *ieee, struct ieee80211_assoc_response
1094 *frame, struct ieee80211_rx_stats *stats)
1095{
1096 struct ieee80211_network network_resp;
1097 struct ieee80211_network *network = &network_resp;
1098 struct net_device *dev = ieee->dev;
1099
1100 network->flags = 0;
1101 network->qos_data.active = 0;
1102 network->qos_data.supported = 0;
1103 network->qos_data.param_count = 0;
1104 network->qos_data.old_param_count = 0;
1105
1106 //network->atim_window = le16_to_cpu(frame->aid) & (0x3FFF);
1107 network->atim_window = le16_to_cpu(frame->aid);
1108 network->listen_interval = le16_to_cpu(frame->status);
1109
1110 if(ieee80211_parse_info_param(frame->info_element, stats->len - sizeof(*frame), network))
1111 return 1;
1112
1113 if (ieee->handle_assoc_response != NULL)
1114 ieee->handle_assoc_response(dev, frame, network);
1115
1116 return 0;
1117}
1118
1119/***************************************************/
1120
1121static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct ieee80211_probe_response
1122 *beacon,
1123 struct ieee80211_network *network,
1124 struct ieee80211_rx_stats *stats)
1125{
1126 network->qos_data.active = 0;
1127 network->qos_data.supported = 0;
1128 network->qos_data.param_count = 0;
1129
1130 /* Pull out fixed field data */
1131 memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
1132 network->capability = le16_to_cpu(beacon->capability);
1133 network->last_scanned = jiffies;
1134 network->time_stamp[0] = le32_to_cpu(beacon->time_stamp[0]);
1135 network->time_stamp[1] = le32_to_cpu(beacon->time_stamp[1]);
1136 network->beacon_interval = le16_to_cpu(beacon->beacon_interval);
1137 /* Where to pull this? beacon->listen_interval; */
1138 network->listen_interval = 0x0A;
1139 network->rates_len = network->rates_ex_len = 0;
1140 network->last_associate = 0;
1141 network->ssid_len = 0;
1142 network->flags = 0;
1143 network->atim_window = 0;
1144 network->erp_value = (network->capability & WLAN_CAPABILITY_IBSS) ?
1145 0x3 : 0x0;
1146
1147 if (stats->freq == IEEE80211_52GHZ_BAND) {
1148 /* for A band (No DS info) */
1149 network->channel = stats->received_channel;
1150 } else
1151 network->flags |= NETWORK_HAS_CCK;
1152
1153 network->wpa_ie_len = 0;
1154 network->rsn_ie_len = 0;
1155
1156 if(ieee80211_parse_info_param(beacon->info_element, stats->len - sizeof(*beacon), network))
1157 return 1;
1158
1228 network->mode = 0; 1159 network->mode = 0;
1229 if (stats->freq == IEEE80211_52GHZ_BAND) 1160 if (stats->freq == IEEE80211_52GHZ_BAND)
1230 network->mode = IEEE_A; 1161 network->mode = IEEE_A;