WifiParserpublic class WifiParser extends Object Describes information about a detected access point. In addition
to the attributes described here, the supplicant keeps track of
{@code quality}, {@code noise}, and {@code maxbitrate} attributes,
but does not currently report them to external clients. |
Fields Summary |
---|
private static final int | VENDOR_SPECIFIC_IE | private static final int | IEEE_RSN_IE | private static final int | WPA_IE_VENDOR_TYPE |
Constructors Summary |
---|
public WifiParser()
|
Methods Summary |
---|
public static java.lang.String | parse_akm(com.android.server.wifi.WifiParser$IE[] full_IE, java.util.BitSet ieee_cap) //WFA WPA vendor IE OUI/type
/*
* parse beacon or probe response frame and build the capabilities
* {@hide}
*
* This function is called so as to build the capabilities string of the scan result, hence it is called
* by AutoJoin controller when handling scan results that are coming from WifiScanner.
*
* It parses the ieee beacon's capability field, WPA and RSNE IE as per spec, but build the
* ScanResult.capabilities String in a way that mirror the values returned by wpa_supplicant.
*
* Once the capabilities string is build, the ScanResult can be used be the system as if it was coming from supplicant.
*/
/* @hide
* */
boolean privacy = false;
boolean error = false;
if (ieee_cap == null)
return null;
if (full_IE == null)
return null;
privacy = ieee_cap.get(4);
String capabilities = "";
boolean rsne_found = false;
boolean wpa_found = false;
for (IE ie : full_IE) {
String security = "";
if (ie.id == IEEE_RSN_IE) {
rsne_found = true;
//parsing WPA2 capabilities
ByteBuffer buf = ByteBuffer.wrap(ie.data);
int total_len = ie.data.length;
int offset = 2;
//version
if ((total_len - offset) < 2) {
//not enough space for version field
security = "";
error = true;
break;
}
int val = 0;
if (0x0100 != buf.getShort(offset)) {
//incorrect version
security = "";
error = true;
break;
}
offset += 2;
//group cipher
if ((total_len - offset) < 4) {
security = ""; //parse error on group cipher suite
error = true;
break;
}
offset += 4; //skip the group cipher
security = "[WPA2"; //found the RSNE IE, hence start building the capability string
//pairwise cipher
if ((total_len - offset) < 2) {
security = ""; //parse error no pairwise cipher
error = true;
break;
}
val = buf.getShort(offset);
if ((total_len - offset) < (2 + val * 4)) {
security = ""; //parse error no pairwise cipher
error = true;
break;
}
offset += 2 + val * 4; //skip the pairwise ciphers
//AKM
if ((total_len - offset) < 2) {
security = ""; //parse error no AKM
error = true;
break;
}
val = buf.getShort(offset);
if ((total_len - offset) < (2 + val * 4)) {
security = ""; //parse error no pairwise cipher
error = true;
break;
}
offset += 2;
if (val == 0) {
security += "-EAP"; //default AKM
}
for (int i = 0; i < val; i++) {
int akm = buf.getInt(offset);
boolean found = false;
switch (akm) {
case 0x01ac0f00:
security += found ? "+" : "-" + "EAP";
found = true;
break;
case 0x02ac0f00:
security += found ? "+" : "-" + "PSK"; //PSK as 802.11-2012 11.6.1.2
found = true;
break;
case 0x03ac0f00:
security += found ? "+" : "-" + "FT/EAP";
found = true;
break;
case 0x04ac0f00:
security += found ? "+" : "-" + "FT/PSK";
found = true;
break;
case 0x06ac0f00:
security += found ? "+" : "-" + "PSK-SHA256";
found = true;
break;
case 0x05ac0f00:
security += found ? "+" : "-" + "EAP-SHA256";
found = true;
break;
}
offset += 4;
}
//we parsed what we want at this point
security += "]";
capabilities += security;
}
if (ie.id == VENDOR_SPECIFIC_IE) {
int total_len = ie.data.length;
int offset = 2;
//version
if ((total_len - offset) < 4) {
//not enough space for OUI and type field
security = "";
error = true;
break;
}
ByteBuffer buf = ByteBuffer.wrap(ie.data);
if (buf.getInt(offset) != 0x01F25000) {
//look for HS2.0 and WPA IE
security = "";
continue;
}
security = "[WPA"; //prep the string for WPA
//version
if ((total_len - offset) < 2) {
//not enough space for version field
security = "";
error = true;
break;
}
int val = 0;
if (0x0100 != buf.getShort(offset)) {
//incorrect version
security = "";
error = true;
break;
}
offset += 2;
//group cipher
if ((total_len - offset) < 4) {
security = ""; //parse error on group cipher suite
error = true;
break;
}
offset += 4; //skip the group cipher
//pairwise cipher
if ((total_len - offset) < 2) {
security = ""; //parse error no pairwise cipher
error = true;
break;
}
val = buf.getShort(offset);
if ((total_len - offset) < (2 + val * 4)) {
security = ""; //parse error no pairwise cipher
error = true;
break;
}
offset += 2 + val * 4; //skip the pairwise ciphers
//AKM
if ((total_len - offset) < 2) {
security = ""; //parse error no AKM
error = true;
break;
}
val = buf.getShort(offset);
if ((total_len - offset) < (2 + val * 4)) {
security = ""; //parse error no pairwise cipher
error = true;
break;
}
offset += 2;
if (val == 0) {
security += "-EAP"; //default AKM
}
for (int i = 0; i < val; i++) {
int akm = buf.getInt(offset);
boolean found = false;
switch (akm) {
case 0x01f25000:
security += found ? "+" : "-" + "EAP";
found = true;
break;
case 0x02f25000:
security += found ? "+" : "-" + "PSK"; //PSK as 802.11-2012 11.6.1.2
found = true;
break;
}
offset += 4;
}
//we parsed what we want at this point
security += "]";
}
}
if (rsne_found == false && wpa_found == false && privacy) {
//private Beacon without an RSNE or WPA IE, hence WEP0
capabilities += "[WEP]";
}
if (error)
return null;
else
return capabilities;
|
|