00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "includes.h"
00016
00017 #include "common.h"
00018 #include "wpa.h"
00019 #include "pmksa_cache.h"
00020 #include "common/ieee802_11_defs.h"
00021 #include "wpa_i.h"
00022 #include "wpa_ie.h"
00023
00024
00025 static int wpa_selector_to_bitfield(const u8 *s)
00026 {
00027 if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_NONE)
00028 return WPA_CIPHER_NONE;
00029 if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_WEP40)
00030 return WPA_CIPHER_WEP40;
00031 if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_TKIP)
00032 return WPA_CIPHER_TKIP;
00033 if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_CCMP)
00034 return WPA_CIPHER_CCMP;
00035 if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_WEP104)
00036 return WPA_CIPHER_WEP104;
00037 return 0;
00038 }
00039
00040
00041 static int wpa_key_mgmt_to_bitfield(const u8 *s)
00042 {
00043 if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_UNSPEC_802_1X)
00044 return WPA_KEY_MGMT_IEEE8021X;
00045 if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X)
00046 return WPA_KEY_MGMT_PSK;
00047 if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_NONE)
00048 return WPA_KEY_MGMT_WPA_NONE;
00049 return 0;
00050 }
00051
00052
00053 static int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len,
00054 struct wpa_ie_data *data)
00055 {
00056 const struct wpa_ie_hdr *hdr;
00057 const u8 *pos;
00058 int left;
00059 int i, count;
00060
00061 os_memset(data, 0, sizeof(*data));
00062 data->proto = WPA_PROTO_WPA;
00063 data->pairwise_cipher = WPA_CIPHER_TKIP;
00064 data->group_cipher = WPA_CIPHER_TKIP;
00065 data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
00066 data->capabilities = 0;
00067 data->pmkid = NULL;
00068 data->num_pmkid = 0;
00069 data->mgmt_group_cipher = 0;
00070
00071 if (wpa_ie_len == 0) {
00072
00073 return -1;
00074 }
00075
00076 if (wpa_ie_len < sizeof(struct wpa_ie_hdr)) {
00077 wpa_printf(MSG_DEBUG, "%s: ie len too short %lu",
00078 __func__, (unsigned long) wpa_ie_len);
00079 return -1;
00080 }
00081
00082 hdr = (const struct wpa_ie_hdr *) wpa_ie;
00083
00084 if (hdr->elem_id != WLAN_EID_VENDOR_SPECIFIC ||
00085 hdr->len != wpa_ie_len - 2 ||
00086 RSN_SELECTOR_GET(hdr->oui) != WPA_OUI_TYPE ||
00087 WPA_GET_LE16(hdr->version) != WPA_VERSION) {
00088 wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",
00089 __func__);
00090 return -1;
00091 }
00092
00093 pos = (const u8 *) (hdr + 1);
00094 left = wpa_ie_len - sizeof(*hdr);
00095
00096 if (left >= WPA_SELECTOR_LEN) {
00097 data->group_cipher = wpa_selector_to_bitfield(pos);
00098 pos += WPA_SELECTOR_LEN;
00099 left -= WPA_SELECTOR_LEN;
00100 } else if (left > 0) {
00101 wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much",
00102 __func__, left);
00103 return -1;
00104 }
00105
00106 if (left >= 2) {
00107 data->pairwise_cipher = 0;
00108 count = WPA_GET_LE16(pos);
00109 pos += 2;
00110 left -= 2;
00111 if (count == 0 || left < count * WPA_SELECTOR_LEN) {
00112 wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), "
00113 "count %u left %u", __func__, count, left);
00114 return -1;
00115 }
00116 for (i = 0; i < count; i++) {
00117 data->pairwise_cipher |= wpa_selector_to_bitfield(pos);
00118 pos += WPA_SELECTOR_LEN;
00119 left -= WPA_SELECTOR_LEN;
00120 }
00121 } else if (left == 1) {
00122 wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)",
00123 __func__);
00124 return -1;
00125 }
00126
00127 if (left >= 2) {
00128 data->key_mgmt = 0;
00129 count = WPA_GET_LE16(pos);
00130 pos += 2;
00131 left -= 2;
00132 if (count == 0 || left < count * WPA_SELECTOR_LEN) {
00133 wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), "
00134 "count %u left %u", __func__, count, left);
00135 return -1;
00136 }
00137 for (i = 0; i < count; i++) {
00138 data->key_mgmt |= wpa_key_mgmt_to_bitfield(pos);
00139 pos += WPA_SELECTOR_LEN;
00140 left -= WPA_SELECTOR_LEN;
00141 }
00142 } else if (left == 1) {
00143 wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)",
00144 __func__);
00145 return -1;
00146 }
00147
00148 if (left >= 2) {
00149 data->capabilities = WPA_GET_LE16(pos);
00150 pos += 2;
00151 left -= 2;
00152 }
00153
00154 if (left > 0) {
00155 wpa_printf(MSG_DEBUG, "%s: ie has %u trailing bytes - ignored",
00156 __func__, left);
00157 }
00158
00159 return 0;
00160 }
00161
00162
00172 int wpa_parse_wpa_ie(const u8 *wpa_ie, size_t wpa_ie_len,
00173 struct wpa_ie_data *data)
00174 {
00175 if (wpa_ie_len >= 1 && wpa_ie[0] == WLAN_EID_RSN)
00176 return wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, data);
00177 else
00178 return wpa_parse_wpa_ie_wpa(wpa_ie, wpa_ie_len, data);
00179 }
00180
00181
00182 static int wpa_gen_wpa_ie_wpa(u8 *wpa_ie, size_t wpa_ie_len,
00183 int pairwise_cipher, int group_cipher,
00184 int key_mgmt)
00185 {
00186 u8 *pos;
00187 struct wpa_ie_hdr *hdr;
00188
00189 if (wpa_ie_len < sizeof(*hdr) + WPA_SELECTOR_LEN +
00190 2 + WPA_SELECTOR_LEN + 2 + WPA_SELECTOR_LEN)
00191 return -1;
00192
00193 hdr = (struct wpa_ie_hdr *) wpa_ie;
00194 hdr->elem_id = WLAN_EID_VENDOR_SPECIFIC;
00195 RSN_SELECTOR_PUT(hdr->oui, WPA_OUI_TYPE);
00196 WPA_PUT_LE16(hdr->version, WPA_VERSION);
00197 pos = (u8 *) (hdr + 1);
00198
00199 if (group_cipher == WPA_CIPHER_CCMP) {
00200 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_CCMP);
00201 } else if (group_cipher == WPA_CIPHER_TKIP) {
00202 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_TKIP);
00203 } else if (group_cipher == WPA_CIPHER_WEP104) {
00204 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_WEP104);
00205 } else if (group_cipher == WPA_CIPHER_WEP40) {
00206 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_WEP40);
00207 } else {
00208 wpa_printf(MSG_WARNING, "Invalid group cipher (%d).",
00209 group_cipher);
00210 return -1;
00211 }
00212 pos += WPA_SELECTOR_LEN;
00213
00214 *pos++ = 1;
00215 *pos++ = 0;
00216 if (pairwise_cipher == WPA_CIPHER_CCMP) {
00217 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_CCMP);
00218 } else if (pairwise_cipher == WPA_CIPHER_TKIP) {
00219 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_TKIP);
00220 } else if (pairwise_cipher == WPA_CIPHER_NONE) {
00221 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_NONE);
00222 } else {
00223 wpa_printf(MSG_WARNING, "Invalid pairwise cipher (%d).",
00224 pairwise_cipher);
00225 return -1;
00226 }
00227 pos += WPA_SELECTOR_LEN;
00228
00229 *pos++ = 1;
00230 *pos++ = 0;
00231 if (key_mgmt == WPA_KEY_MGMT_IEEE8021X) {
00232 RSN_SELECTOR_PUT(pos, WPA_AUTH_KEY_MGMT_UNSPEC_802_1X);
00233 } else if (key_mgmt == WPA_KEY_MGMT_PSK) {
00234 RSN_SELECTOR_PUT(pos, WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X);
00235 } else if (key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
00236 RSN_SELECTOR_PUT(pos, WPA_AUTH_KEY_MGMT_NONE);
00237 } else {
00238 wpa_printf(MSG_WARNING, "Invalid key management type (%d).",
00239 key_mgmt);
00240 return -1;
00241 }
00242 pos += WPA_SELECTOR_LEN;
00243
00244
00245
00246 hdr->len = (pos - wpa_ie) - 2;
00247
00248 WPA_ASSERT((size_t) (pos - wpa_ie) <= wpa_ie_len);
00249
00250 return pos - wpa_ie;
00251 }
00252
00253
00254 static int wpa_gen_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len,
00255 int pairwise_cipher, int group_cipher,
00256 int key_mgmt, int mgmt_group_cipher,
00257 struct wpa_sm *sm)
00258 {
00259 #ifndef CONFIG_NO_WPA2
00260 u8 *pos;
00261 struct rsn_ie_hdr *hdr;
00262 u16 capab;
00263
00264 if (rsn_ie_len < sizeof(*hdr) + RSN_SELECTOR_LEN +
00265 2 + RSN_SELECTOR_LEN + 2 + RSN_SELECTOR_LEN + 2 +
00266 (sm->cur_pmksa ? 2 + PMKID_LEN : 0)) {
00267 wpa_printf(MSG_DEBUG, "RSN: Too short IE buffer (%lu bytes)",
00268 (unsigned long) rsn_ie_len);
00269 return -1;
00270 }
00271
00272 hdr = (struct rsn_ie_hdr *) rsn_ie;
00273 hdr->elem_id = WLAN_EID_RSN;
00274 WPA_PUT_LE16(hdr->version, RSN_VERSION);
00275 pos = (u8 *) (hdr + 1);
00276
00277 if (group_cipher == WPA_CIPHER_CCMP) {
00278 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
00279 } else if (group_cipher == WPA_CIPHER_TKIP) {
00280 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP);
00281 } else if (group_cipher == WPA_CIPHER_WEP104) {
00282 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_WEP104);
00283 } else if (group_cipher == WPA_CIPHER_WEP40) {
00284 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_WEP40);
00285 } else {
00286 wpa_printf(MSG_WARNING, "Invalid group cipher (%d).",
00287 group_cipher);
00288 return -1;
00289 }
00290 pos += RSN_SELECTOR_LEN;
00291
00292 *pos++ = 1;
00293 *pos++ = 0;
00294 if (pairwise_cipher == WPA_CIPHER_CCMP) {
00295 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
00296 } else if (pairwise_cipher == WPA_CIPHER_TKIP) {
00297 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP);
00298 } else if (pairwise_cipher == WPA_CIPHER_NONE) {
00299 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NONE);
00300 } else {
00301 wpa_printf(MSG_WARNING, "Invalid pairwise cipher (%d).",
00302 pairwise_cipher);
00303 return -1;
00304 }
00305 pos += RSN_SELECTOR_LEN;
00306
00307 *pos++ = 1;
00308 *pos++ = 0;
00309 if (key_mgmt == WPA_KEY_MGMT_IEEE8021X) {
00310 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X);
00311 } else if (key_mgmt == WPA_KEY_MGMT_PSK) {
00312 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X);
00313 #ifdef CONFIG_IEEE80211R
00314 } else if (key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X) {
00315 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_802_1X);
00316 } else if (key_mgmt == WPA_KEY_MGMT_FT_PSK) {
00317 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_PSK);
00318 #endif
00319 #ifdef CONFIG_IEEE80211W
00320 } else if (key_mgmt == WPA_KEY_MGMT_IEEE8021X_SHA256) {
00321 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SHA256);
00322 } else if (key_mgmt == WPA_KEY_MGMT_PSK_SHA256) {
00323 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PSK_SHA256);
00324 #endif
00325 } else {
00326 wpa_printf(MSG_WARNING, "Invalid key management type (%d).",
00327 key_mgmt);
00328 return -1;
00329 }
00330 pos += RSN_SELECTOR_LEN;
00331
00332
00333 capab = 0;
00334 #ifdef CONFIG_IEEE80211W
00335 if (sm->mfp)
00336 capab |= WPA_CAPABILITY_MFPC;
00337 if (sm->mfp == 2)
00338 capab |= WPA_CAPABILITY_MFPR;
00339 #endif
00340 WPA_PUT_LE16(pos, capab);
00341 pos += 2;
00342
00343 if (sm->cur_pmksa) {
00344
00345 *pos++ = 1;
00346 *pos++ = 0;
00347
00348 os_memcpy(pos, sm->cur_pmksa->pmkid, PMKID_LEN);
00349 pos += PMKID_LEN;
00350 }
00351
00352 #ifdef CONFIG_IEEE80211W
00353 if (mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC) {
00354 if (!sm->cur_pmksa) {
00355
00356 WPA_PUT_LE16(pos, 0);
00357 pos += 2;
00358 }
00359
00360
00361 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC);
00362 pos += RSN_SELECTOR_LEN;
00363 }
00364 #endif
00365
00366 hdr->len = (pos - rsn_ie) - 2;
00367
00368 WPA_ASSERT((size_t) (pos - rsn_ie) <= rsn_ie_len);
00369
00370 return pos - rsn_ie;
00371 #else
00372 return -1;
00373 #endif
00374 }
00375
00376
00384 int wpa_gen_wpa_ie(struct wpa_sm *sm, u8 *wpa_ie, size_t wpa_ie_len)
00385 {
00386 if (sm->proto == WPA_PROTO_RSN)
00387 return wpa_gen_wpa_ie_rsn(wpa_ie, wpa_ie_len,
00388 sm->pairwise_cipher,
00389 sm->group_cipher,
00390 sm->key_mgmt, sm->mgmt_group_cipher,
00391 sm);
00392 else
00393 return wpa_gen_wpa_ie_wpa(wpa_ie, wpa_ie_len,
00394 sm->pairwise_cipher,
00395 sm->group_cipher,
00396 sm->key_mgmt);
00397 }
00398
00399
00407 static int wpa_parse_generic(const u8 *pos, const u8 *end,
00408 struct wpa_eapol_ie_parse *ie)
00409 {
00410 if (pos[1] == 0)
00411 return 1;
00412
00413 if (pos[1] >= 6 &&
00414 RSN_SELECTOR_GET(pos + 2) == WPA_OUI_TYPE &&
00415 pos[2 + WPA_SELECTOR_LEN] == 1 &&
00416 pos[2 + WPA_SELECTOR_LEN + 1] == 0) {
00417 ie->wpa_ie = pos;
00418 ie->wpa_ie_len = pos[1] + 2;
00419 wpa_hexdump(MSG_DEBUG, "WPA: WPA IE in EAPOL-Key",
00420 ie->wpa_ie, ie->wpa_ie_len);
00421 return 0;
00422 }
00423
00424 if (pos + 1 + RSN_SELECTOR_LEN < end &&
00425 pos[1] >= RSN_SELECTOR_LEN + PMKID_LEN &&
00426 RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_PMKID) {
00427 ie->pmkid = pos + 2 + RSN_SELECTOR_LEN;
00428 wpa_hexdump(MSG_DEBUG, "WPA: PMKID in EAPOL-Key",
00429 pos, pos[1] + 2);
00430 return 0;
00431 }
00432
00433 if (pos[1] > RSN_SELECTOR_LEN + 2 &&
00434 RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_GROUPKEY) {
00435 ie->gtk = pos + 2 + RSN_SELECTOR_LEN;
00436 ie->gtk_len = pos[1] - RSN_SELECTOR_LEN;
00437 wpa_hexdump_key(MSG_DEBUG, "WPA: GTK in EAPOL-Key",
00438 pos, pos[1] + 2);
00439 return 0;
00440 }
00441
00442 if (pos[1] > RSN_SELECTOR_LEN + 2 &&
00443 RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_MAC_ADDR) {
00444 ie->mac_addr = pos + 2 + RSN_SELECTOR_LEN;
00445 ie->mac_addr_len = pos[1] - RSN_SELECTOR_LEN;
00446 wpa_hexdump(MSG_DEBUG, "WPA: MAC Address in EAPOL-Key",
00447 pos, pos[1] + 2);
00448 return 0;
00449 }
00450
00451 #ifdef CONFIG_PEERKEY
00452 if (pos[1] > RSN_SELECTOR_LEN + 2 &&
00453 RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_SMK) {
00454 ie->smk = pos + 2 + RSN_SELECTOR_LEN;
00455 ie->smk_len = pos[1] - RSN_SELECTOR_LEN;
00456 wpa_hexdump_key(MSG_DEBUG, "WPA: SMK in EAPOL-Key",
00457 pos, pos[1] + 2);
00458 return 0;
00459 }
00460
00461 if (pos[1] > RSN_SELECTOR_LEN + 2 &&
00462 RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_NONCE) {
00463 ie->nonce = pos + 2 + RSN_SELECTOR_LEN;
00464 ie->nonce_len = pos[1] - RSN_SELECTOR_LEN;
00465 wpa_hexdump(MSG_DEBUG, "WPA: Nonce in EAPOL-Key",
00466 pos, pos[1] + 2);
00467 return 0;
00468 }
00469
00470 if (pos[1] > RSN_SELECTOR_LEN + 2 &&
00471 RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_LIFETIME) {
00472 ie->lifetime = pos + 2 + RSN_SELECTOR_LEN;
00473 ie->lifetime_len = pos[1] - RSN_SELECTOR_LEN;
00474 wpa_hexdump(MSG_DEBUG, "WPA: Lifetime in EAPOL-Key",
00475 pos, pos[1] + 2);
00476 return 0;
00477 }
00478
00479 if (pos[1] > RSN_SELECTOR_LEN + 2 &&
00480 RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_ERROR) {
00481 ie->error = pos + 2 + RSN_SELECTOR_LEN;
00482 ie->error_len = pos[1] - RSN_SELECTOR_LEN;
00483 wpa_hexdump(MSG_DEBUG, "WPA: Error in EAPOL-Key",
00484 pos, pos[1] + 2);
00485 return 0;
00486 }
00487 #endif
00488
00489 #ifdef CONFIG_IEEE80211W
00490 if (pos[1] > RSN_SELECTOR_LEN + 2 &&
00491 RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_IGTK) {
00492 ie->igtk = pos + 2 + RSN_SELECTOR_LEN;
00493 ie->igtk_len = pos[1] - RSN_SELECTOR_LEN;
00494 wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK in EAPOL-Key",
00495 pos, pos[1] + 2);
00496 return 0;
00497 }
00498 #endif
00499
00500 return 0;
00501 }
00502
00503
00511 int wpa_supplicant_parse_ies(const u8 *buf, size_t len,
00512 struct wpa_eapol_ie_parse *ie)
00513 {
00514 const u8 *pos, *end;
00515 int ret = 0;
00516
00517 os_memset(ie, 0, sizeof(*ie));
00518 for (pos = buf, end = pos + len; pos + 1 < end; pos += 2 + pos[1]) {
00519 if (pos[0] == 0xdd &&
00520 ((pos == buf + len - 1) || pos[1] == 0)) {
00521
00522 break;
00523 }
00524 if (pos + 2 + pos[1] > end) {
00525 wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key Key Data "
00526 "underflow (ie=%d len=%d pos=%d)",
00527 pos[0], pos[1], (int) (pos - buf));
00528 wpa_hexdump_key(MSG_DEBUG, "WPA: Key Data",
00529 buf, len);
00530 ret = -1;
00531 break;
00532 }
00533 if (*pos == WLAN_EID_RSN) {
00534 ie->rsn_ie = pos;
00535 ie->rsn_ie_len = pos[1] + 2;
00536 wpa_hexdump(MSG_DEBUG, "WPA: RSN IE in EAPOL-Key",
00537 ie->rsn_ie, ie->rsn_ie_len);
00538 #ifdef CONFIG_IEEE80211R
00539 } else if (*pos == WLAN_EID_MOBILITY_DOMAIN) {
00540 ie->mdie = pos;
00541 ie->mdie_len = pos[1] + 2;
00542 wpa_hexdump(MSG_DEBUG, "WPA: MDIE in EAPOL-Key",
00543 ie->mdie, ie->mdie_len);
00544 } else if (*pos == WLAN_EID_FAST_BSS_TRANSITION) {
00545 ie->ftie = pos;
00546 ie->ftie_len = pos[1] + 2;
00547 wpa_hexdump(MSG_DEBUG, "WPA: FTIE in EAPOL-Key",
00548 ie->ftie, ie->ftie_len);
00549 } else if (*pos == WLAN_EID_TIMEOUT_INTERVAL && pos[1] >= 5) {
00550 if (pos[2] == WLAN_TIMEOUT_REASSOC_DEADLINE) {
00551 ie->reassoc_deadline = pos;
00552 wpa_hexdump(MSG_DEBUG, "WPA: Reassoc Deadline "
00553 "in EAPOL-Key",
00554 ie->reassoc_deadline, pos[1] + 2);
00555 } else if (pos[2] == WLAN_TIMEOUT_KEY_LIFETIME) {
00556 ie->key_lifetime = pos;
00557 wpa_hexdump(MSG_DEBUG, "WPA: KeyLifetime "
00558 "in EAPOL-Key",
00559 ie->key_lifetime, pos[1] + 2);
00560 } else {
00561 wpa_hexdump(MSG_DEBUG, "WPA: Unrecognized "
00562 "EAPOL-Key Key Data IE",
00563 pos, 2 + pos[1]);
00564 }
00565 #endif
00566 } else if (*pos == WLAN_EID_VENDOR_SPECIFIC) {
00567 ret = wpa_parse_generic(pos, end, ie);
00568 if (ret < 0)
00569 break;
00570 if (ret > 0) {
00571 ret = 0;
00572 break;
00573 }
00574 } else {
00575 wpa_hexdump(MSG_DEBUG, "WPA: Unrecognized EAPOL-Key "
00576 "Key Data IE", pos, 2 + pos[1]);
00577 }
00578 }
00579
00580 return ret;
00581 }