1f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle/* 2f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * Copyright (C) 2008 The Android Open Source Project 3f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 4f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * Licensed under the Apache License, Version 2.0 (the "License"); 5f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * you may not use this file except in compliance with the License. 6f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * You may obtain a copy of the License at 7f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 8f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * http://www.apache.org/licenses/LICENSE-2.0 9f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 10f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * Unless required by applicable law or agreed to in writing, software 11f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * distributed under the License is distributed on an "AS IS" BASIS, 12f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * See the License for the specific language governing permissions and 14f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * limitations under the License. 15f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle */ 16f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 17647207cce53bad5ef911e16278d5a2c910cdab92Jeff Davidsonpackage com.android.server.wifi; 18f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 19f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport android.os.Parcelable; 20f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport android.os.Parcel; 21f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 22f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport java.util.BitSet; 23f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 24f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport java.nio.ByteBuffer; 25f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 26f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport java.util.Date; 27f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 28f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle/** 29f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * Describes information about a detected access point. In addition 30f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * to the attributes described here, the supplicant keeps track of 31f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * {@code quality}, {@code noise}, and {@code maxbitrate} attributes, 32f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * but does not currently report them to external clients. 33f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle */ 34f22d23092ab37286a5ef9d257d5bb32c421d2669vandwallepublic class WifiParser { 35f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 36f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle public WifiParser() {} 37f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 38f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 39f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle /* 40f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * {@hide} 41f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle */ 42f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle class IE { 43f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int id; 44f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle byte data[]; 45f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 46f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 47f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private static final int VENDOR_SPECIFIC_IE = 221; 48f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private static final int IEEE_RSN_IE = 48; //IEEE 2012 8.4.2.27 49f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 50f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 51f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private static final int WPA_IE_VENDOR_TYPE = 0x0050f201; //WFA WPA vendor IE OUI/type 52f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 53f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle /* 54f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * parse beacon or probe response frame and build the capabilities 55f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * {@hide} 56f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 57f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * This function is called so as to build the capabilities string of the scan result, hence it is called 58f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * by AutoJoin controller when handling scan results that are coming from WifiScanner. 59f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 60f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * It parses the ieee beacon's capability field, WPA and RSNE IE as per spec, but build the 61f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * ScanResult.capabilities String in a way that mirror the values returned by wpa_supplicant. 62f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 63f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * Once the capabilities string is build, the ScanResult can be used be the system as if it was coming from supplicant. 64f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle */ 65f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle /* @hide 66f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * */ 67f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle static public String parse_akm(IE full_IE[], BitSet ieee_cap) { 68f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle boolean privacy = false; 69f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle boolean error = false; 70f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (ieee_cap == null) 71f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return null; 72f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 73f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (full_IE == null) 74f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return null; 75f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 76f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle privacy = ieee_cap.get(4); 77f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 78f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle String capabilities = ""; 79f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle boolean rsne_found = false; 80f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle boolean wpa_found = false; 81f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 82f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle for (IE ie : full_IE) { 83f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle String security = ""; 84f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (ie.id == IEEE_RSN_IE) { 85f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle rsne_found = true; 86f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //parsing WPA2 capabilities 87f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 88f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle ByteBuffer buf = ByteBuffer.wrap(ie.data); 89f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 90f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int total_len = ie.data.length; 91f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int offset = 2; 92f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 93f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //version 94f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((total_len - offset) < 2) { 95f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //not enough space for version field 96f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle security = ""; 97f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle error = true; 98f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle break; 99f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 100f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int val = 0; 101f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (0x0100 != buf.getShort(offset)) { 102f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //incorrect version 103f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle security = ""; 104f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle error = true; 105f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle break; 106f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 107f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle offset += 2; 108f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 109f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 110f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //group cipher 111f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((total_len - offset) < 4) { 112f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle security = ""; //parse error on group cipher suite 113f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle error = true; 114f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle break; 115f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 116f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle offset += 4; //skip the group cipher 117f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 118f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle security = "[WPA2"; //found the RSNE IE, hence start building the capability string 119f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 120f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //pairwise cipher 121f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((total_len - offset) < 2) { 122f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle security = ""; //parse error no pairwise cipher 123f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle error = true; 124f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle break; 125f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 126f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle val = buf.getShort(offset); 127f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((total_len - offset) < (2 + val * 4)) { 128f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle security = ""; //parse error no pairwise cipher 129f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle error = true; 130f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle break; 131f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 132f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle offset += 2 + val * 4; //skip the pairwise ciphers 133f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 134f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //AKM 135f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((total_len - offset) < 2) { 136f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle security = ""; //parse error no AKM 137f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle error = true; 138f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle break; 139f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 140f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle val = buf.getShort(offset); 141f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((total_len - offset) < (2 + val * 4)) { 142f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle security = ""; //parse error no pairwise cipher 143f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle error = true; 144f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle break; 145f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 146f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle offset += 2; 147f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (val == 0) { 148f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle security += "-EAP"; //default AKM 149f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 150f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle for (int i = 0; i < val; i++) { 151f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int akm = buf.getInt(offset); 152f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle boolean found = false; 153f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle switch (akm) { 154f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle case 0x01ac0f00: 155f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle security += found ? "+" : "-" + "EAP"; 156f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle found = true; 157f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle break; 158f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle case 0x02ac0f00: 159f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle security += found ? "+" : "-" + "PSK"; //PSK as 802.11-2012 11.6.1.2 160f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle found = true; 161f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle break; 162f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle case 0x03ac0f00: 163f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle security += found ? "+" : "-" + "FT/EAP"; 164f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle found = true; 165f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle break; 166f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle case 0x04ac0f00: 167f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle security += found ? "+" : "-" + "FT/PSK"; 168f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle found = true; 169f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle break; 170f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle case 0x06ac0f00: 171f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle security += found ? "+" : "-" + "PSK-SHA256"; 172f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle found = true; 173f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle break; 174f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle case 0x05ac0f00: 175f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle security += found ? "+" : "-" + "EAP-SHA256"; 176f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle found = true; 177f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle break; 178f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 179f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle offset += 4; 180f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 181f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //we parsed what we want at this point 182f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle security += "]"; 183f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle capabilities += security; 184f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 185f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 186f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 187f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (ie.id == VENDOR_SPECIFIC_IE) { 188f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int total_len = ie.data.length; 189f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int offset = 2; 190f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 191f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //version 192f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((total_len - offset) < 4) { 193f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //not enough space for OUI and type field 194f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle security = ""; 195f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle error = true; 196f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle break; 197f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 198f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 199f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle ByteBuffer buf = ByteBuffer.wrap(ie.data); 200f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 201f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (buf.getInt(offset) != 0x01F25000) { 202f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //look for HS2.0 and WPA IE 203f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle security = ""; 204f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle continue; 205f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 206f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 207f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle security = "[WPA"; //prep the string for WPA 208f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 209f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //version 210f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((total_len - offset) < 2) { 211f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //not enough space for version field 212f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle security = ""; 213f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle error = true; 214f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle break; 215f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 216f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int val = 0; 217f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (0x0100 != buf.getShort(offset)) { 218f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //incorrect version 219f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle security = ""; 220f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle error = true; 221f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle break; 222f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 223f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle offset += 2; 224f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 225f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 226f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //group cipher 227f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((total_len - offset) < 4) { 228f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle security = ""; //parse error on group cipher suite 229f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle error = true; 230f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle break; 231f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 232f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle offset += 4; //skip the group cipher 233f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 234f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 235f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //pairwise cipher 236f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((total_len - offset) < 2) { 237f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle security = ""; //parse error no pairwise cipher 238f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle error = true; 239f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle break; 240f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 241f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle val = buf.getShort(offset); 242f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((total_len - offset) < (2 + val * 4)) { 243f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle security = ""; //parse error no pairwise cipher 244f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle error = true; 245f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle break; 246f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 247f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle offset += 2 + val * 4; //skip the pairwise ciphers 248f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 249f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //AKM 250f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((total_len - offset) < 2) { 251f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle security = ""; //parse error no AKM 252f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle error = true; 253f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle break; 254f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 255f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle val = buf.getShort(offset); 256f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((total_len - offset) < (2 + val * 4)) { 257f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle security = ""; //parse error no pairwise cipher 258f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle error = true; 259f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle break; 260f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 261f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle offset += 2; 262f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (val == 0) { 263f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle security += "-EAP"; //default AKM 264f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 265f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle for (int i = 0; i < val; i++) { 266f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int akm = buf.getInt(offset); 267f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle boolean found = false; 268f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle switch (akm) { 269f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle case 0x01f25000: 270f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle security += found ? "+" : "-" + "EAP"; 271f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle found = true; 272f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle break; 273f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle case 0x02f25000: 274f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle security += found ? "+" : "-" + "PSK"; //PSK as 802.11-2012 11.6.1.2 275f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle found = true; 276f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle break; 277f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 278f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 279f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle offset += 4; 280f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 281f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //we parsed what we want at this point 282f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle security += "]"; 283f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 284f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 285f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 286f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (rsne_found == false && wpa_found == false && privacy) { 287f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //private Beacon without an RSNE or WPA IE, hence WEP0 288f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle capabilities += "[WEP]"; 289f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 290f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 291f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (error) 292f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return null; 293f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle else 294f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return capabilities; 295f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 296f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 297f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 298f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle} 299