From 584d14e3cf5812f522bfd7977ee9cd6bd944db55 Mon Sep 17 00:00:00 2001 From: snandakumar Date: Wed, 12 Jul 2017 08:55:51 -0700 Subject: [PATCH] Issue #110 - Probe Request Information Element Order change --- .../packet/Dot11ProbeRequestPacket.java | 261 ++++++++---------- .../packet/Dot11ProbeRequestPacketTest.java | 56 ++++ 2 files changed, 172 insertions(+), 145 deletions(-) diff --git a/pcap4j-core/src/main/java/org/pcap4j/packet/Dot11ProbeRequestPacket.java b/pcap4j-core/src/main/java/org/pcap4j/packet/Dot11ProbeRequestPacket.java index 8b1bf97f2..2583353ad 100644 --- a/pcap4j-core/src/main/java/org/pcap4j/packet/Dot11ProbeRequestPacket.java +++ b/pcap4j-core/src/main/java/org/pcap4j/packet/Dot11ProbeRequestPacket.java @@ -11,6 +11,7 @@ import java.util.ArrayList; import java.util.Collections; +import java.util.LinkedList; import java.util.List; import org.pcap4j.util.ByteArrays; @@ -474,20 +475,23 @@ public static final class Dot11ProbeRequestHeader extends Dot11ManagementHeader */ private static final long serialVersionUID = -2203820242563461514L; - private final Dot11SsidElement ssid; - private final Dot11SupportedRatesElement supportedRates; - private final Dot11RequestElement request; - private final Dot11ExtendedSupportedRatesElement extendedSupportedRates; - private final Dot11DsssParameterSetElement dsssParameterSet; - private final Dot11SupportedOperatingClassesElement supportedOperatingClasses; - private final Dot11HTCapabilitiesElement htCapabilities; - private final Dot112040BssCoexistenceElement twentyFortyBssCoexistence; - private final Dot11ExtendedCapabilitiesElement extendedCapabilities; - private final Dot11SsidListElement ssidList; - private final Dot11ChannelUsageElement channelUsage; - private final Dot11InterworkingElement interworking; - private final Dot11MeshIdElement meshId; - private final List vendorSpecificElements; + private Dot11SsidElement ssid = null; + private Dot11SupportedRatesElement supportedRates = null; + private Dot11RequestElement request = null; + private Dot11ExtendedSupportedRatesElement extendedSupportedRates = null; + private Dot11DsssParameterSetElement dsssParameterSet = null; + private Dot11SupportedOperatingClassesElement supportedOperatingClasses = null; + private Dot11HTCapabilitiesElement htCapabilities = null; + private Dot112040BssCoexistenceElement twentyFortyBssCoexistence = null; + private Dot11ExtendedCapabilitiesElement extendedCapabilities = null; + private Dot11SsidListElement ssidList = null; + private Dot11ChannelUsageElement channelUsage = null; + private Dot11InterworkingElement interworking = null; + private Dot11MeshIdElement meshId = null; + private List vendorSpecificElements = new ArrayList(); + + private List infoElementOrderedList = new LinkedList(); + private static final short INFORMATION_ELEMENT_MAX_COUNT = 15; private Dot11ProbeRequestHeader( byte[] rawData, int offset, int length @@ -497,137 +501,97 @@ private Dot11ProbeRequestHeader( offset += mgmtHeaderLen; length -= mgmtHeaderLen; - if (length > 0 && rawData[offset] == SSID.value().byteValue()) { - this.ssid = Dot11SsidElement.newInstance(rawData, offset, length); - int elemLen = ssid.length(); - offset += elemLen; - length -= elemLen; - } - else { - this.ssid = null; - } - if (length > 0 && rawData[offset] == SUPPORTED_RATES.value().byteValue()) { - this.supportedRates = Dot11SupportedRatesElement.newInstance(rawData, offset, length); - int elemLen = supportedRates.length(); - offset += elemLen; - length -= elemLen; - } - else { - this.supportedRates = null; - } - if (length > 0 && rawData[offset] == REQUEST.value().byteValue()) { - this.request = Dot11RequestElement.newInstance(rawData, offset, length); - int elemLen = request.length(); - offset += elemLen; - length -= elemLen; - } - else { - this.request = null; - } - if (length > 0 && rawData[offset] == EXTENDED_SUPPORTED_RATES.value().byteValue()) { - this.extendedSupportedRates - = Dot11ExtendedSupportedRatesElement.newInstance(rawData, offset, length); - int elemLen = extendedSupportedRates.length(); - offset += elemLen; - length -= elemLen; - } - else { - this.extendedSupportedRates = null; - } - if (length > 0 && rawData[offset] == DSSS_PARAMETER_SET.value().byteValue()) { - this.dsssParameterSet - = Dot11DsssParameterSetElement.newInstance(rawData, offset, length); - int elemLen = dsssParameterSet.length(); - offset += elemLen; - length -= elemLen; - } - else { - this.dsssParameterSet = null; - } - if (length > 0 && rawData[offset] == SUPPORTED_OPERATING_CLASSES.value().byteValue()) { - this.supportedOperatingClasses - = Dot11SupportedOperatingClassesElement.newInstance(rawData, offset, length); - int elemLen = supportedOperatingClasses.length(); - offset += elemLen; - length -= elemLen; - } - else { - this.supportedOperatingClasses = null; - } - if (length > 0 && rawData[offset] == HT_CAPABILITIES.value().byteValue()) { - this.htCapabilities = Dot11HTCapabilitiesElement.newInstance(rawData, offset, length); - int elemLen = htCapabilities.length(); - offset += elemLen; - length -= elemLen; - } - else { - this.htCapabilities = null; - } - if (length > 0 && rawData[offset] == IE_20_40_BSS_COEXISTENCE.value().byteValue()) { - this.twentyFortyBssCoexistence - = Dot112040BssCoexistenceElement.newInstance(rawData, offset, length); - int elemLen = twentyFortyBssCoexistence.length(); - offset += elemLen; - length -= elemLen; - } - else { - this.twentyFortyBssCoexistence = null; - } - if (length > 0 && rawData[offset] == EXTENDED_CAPABILITIES.value().byteValue()) { - this.extendedCapabilities - = Dot11ExtendedCapabilitiesElement.newInstance(rawData, offset, length); - int elemLen = extendedCapabilities.length(); - offset += elemLen; - length -= elemLen; - } - else { - this.extendedCapabilities = null; - } - if (length > 0 && rawData[offset] == SSID_LIST.value().byteValue()) { - this.ssidList = Dot11SsidListElement.newInstance(rawData, offset, length); - int elemLen = ssidList.length(); - offset += elemLen; - length -= elemLen; - } - else { - this.ssidList = null; - } - if (length > 0 && rawData[offset] == CHANNEL_USAGE.value().byteValue()) { - this.channelUsage = Dot11ChannelUsageElement.newInstance(rawData, offset, length); - int elemLen = channelUsage.length(); - offset += elemLen; - length -= elemLen; - } - else { - this.channelUsage = null; - } - if (length > 0 && rawData[offset] == INTERWORKING.value().byteValue()) { - this.interworking = Dot11InterworkingElement.newInstance(rawData, offset, length); - int elemLen = interworking.length(); - offset += elemLen; - length -= elemLen; - } - else { - this.interworking = null; - } - if (length > 0 && rawData[offset] == MESH_ID.value().byteValue()) { - this.meshId = Dot11MeshIdElement.newInstance(rawData, offset, length); - int elemLen = meshId.length(); - offset += elemLen; - length -= elemLen; - } - else { - this.meshId = null; - } - - this.vendorSpecificElements = new ArrayList(); - while (length > 0 && rawData[offset] == VENDOR_SPECIFIC.value().byteValue()) { - Dot11VendorSpecificElement elem - = Dot11VendorSpecificElement.newInstance(rawData, offset, length); - vendorSpecificElements.add(elem); - int elemLen = elem.length(); - offset += elemLen; - length -= elemLen; + short iterCount = 0; + while (length > 4 && iterCount < INFORMATION_ELEMENT_MAX_COUNT) { + iterCount++; + if (length > 0 && rawData[offset] == SSID.value().byteValue()) { + this.ssid = Dot11SsidElement.newInstance(rawData, offset, length); + int elemLen = ssid.length(); + offset += elemLen; + length -= elemLen; + infoElementOrderedList.add(this.ssid); + }else if (length > 0 && rawData[offset] == SUPPORTED_RATES.value().byteValue()) { + this.supportedRates = Dot11SupportedRatesElement.newInstance(rawData, offset, length); + int elemLen = supportedRates.length(); + offset += elemLen; + length -= elemLen; + infoElementOrderedList.add(this.supportedRates); + }else if (length > 0 && rawData[offset] == REQUEST.value().byteValue()) { + this.request = Dot11RequestElement.newInstance(rawData, offset, length); + int elemLen = request.length(); + offset += elemLen; + length -= elemLen; + infoElementOrderedList.add(this.request); + }else if (length > 0 && rawData[offset] == EXTENDED_SUPPORTED_RATES.value().byteValue()) { + this.extendedSupportedRates = Dot11ExtendedSupportedRatesElement.newInstance(rawData, offset, length); + int elemLen = extendedSupportedRates.length(); + offset += elemLen; + length -= elemLen; + infoElementOrderedList.add(this.extendedSupportedRates); + }else if (length > 0 && rawData[offset] == DSSS_PARAMETER_SET.value().byteValue()) { + this.dsssParameterSet = Dot11DsssParameterSetElement.newInstance(rawData, offset, length); + int elemLen = dsssParameterSet.length(); + offset += elemLen; + length -= elemLen; + infoElementOrderedList.add(this.dsssParameterSet); + }else if (length > 0 && rawData[offset] == SUPPORTED_OPERATING_CLASSES.value().byteValue()) { + this.supportedOperatingClasses = Dot11SupportedOperatingClassesElement.newInstance(rawData, offset, length); + int elemLen = supportedOperatingClasses.length(); + offset += elemLen; + length -= elemLen; + infoElementOrderedList.add(this.supportedOperatingClasses); + }else if (length > 0 && rawData[offset] == HT_CAPABILITIES.value().byteValue()) { + this.htCapabilities = Dot11HTCapabilitiesElement.newInstance(rawData, offset, length); + int elemLen = htCapabilities.length(); + offset += elemLen; + length -= elemLen; + infoElementOrderedList.add(this.htCapabilities); + }else if (length > 0 && rawData[offset] == IE_20_40_BSS_COEXISTENCE.value().byteValue()) { + this.twentyFortyBssCoexistence = Dot112040BssCoexistenceElement.newInstance(rawData, offset, length); + int elemLen = twentyFortyBssCoexistence.length(); + offset += elemLen; + length -= elemLen; + infoElementOrderedList.add(this.twentyFortyBssCoexistence); + }else if (length > 0 && rawData[offset] == EXTENDED_CAPABILITIES.value().byteValue()) { + this.extendedCapabilities = Dot11ExtendedCapabilitiesElement.newInstance(rawData, offset, length); + int elemLen = extendedCapabilities.length(); + offset += elemLen; + length -= elemLen; + infoElementOrderedList.add(this.extendedCapabilities); + }else if (length > 0 && rawData[offset] == SSID_LIST.value().byteValue()) { + this.ssidList = Dot11SsidListElement.newInstance(rawData, offset, length); + int elemLen = ssidList.length(); + offset += elemLen; + length -= elemLen; + infoElementOrderedList.add(this.ssidList); + }else if (length > 0 && rawData[offset] == CHANNEL_USAGE.value().byteValue()) { + this.channelUsage = Dot11ChannelUsageElement.newInstance(rawData, offset, length); + int elemLen = channelUsage.length(); + offset += elemLen; + length -= elemLen; + infoElementOrderedList.add(this.channelUsage); + }else if (length > 0 && rawData[offset] == INTERWORKING.value().byteValue()) { + this.interworking = Dot11InterworkingElement.newInstance(rawData, offset, length); + int elemLen = interworking.length(); + offset += elemLen; + length -= elemLen; + infoElementOrderedList.add(this.interworking); + }else if (length > 0 && rawData[offset] == MESH_ID.value().byteValue()) { + this.meshId = Dot11MeshIdElement.newInstance(rawData, offset, length); + int elemLen = meshId.length(); + offset += elemLen; + length -= elemLen; + infoElementOrderedList.add(this.meshId); + }else { + while (length > 0 && rawData[offset] == VENDOR_SPECIFIC.value().byteValue()) { + Dot11VendorSpecificElement elem = Dot11VendorSpecificElement.newInstance(rawData, offset, length); + vendorSpecificElements.add(elem); + int elemLen = elem.length(); + offset += elemLen; + length -= elemLen; + infoElementOrderedList.add(elem); + } + } } } @@ -753,6 +717,13 @@ public List getVendorSpecificElements() { return new ArrayList(vendorSpecificElements); } + /** + * @return infoElementOrderedList + */ + public List getInformationElementOrderedList() { + return infoElementOrderedList; + } + @Override protected List getRawFields() { List rawFields = super.getRawFields(); diff --git a/pcap4j-packettest/src/test/java/org/pcap4j/packet/Dot11ProbeRequestPacketTest.java b/pcap4j-packettest/src/test/java/org/pcap4j/packet/Dot11ProbeRequestPacketTest.java index 8d0b921f5..ab62093cb 100644 --- a/pcap4j-packettest/src/test/java/org/pcap4j/packet/Dot11ProbeRequestPacketTest.java +++ b/pcap4j-packettest/src/test/java/org/pcap4j/packet/Dot11ProbeRequestPacketTest.java @@ -44,6 +44,7 @@ import org.pcap4j.packet.namednumber.Dot11InformationElementId; import org.pcap4j.packet.namednumber.Dot11ServiceIntervalGranularity; import org.pcap4j.packet.namednumber.Dot11VenueInfo; +import org.pcap4j.util.ByteArrays; import org.pcap4j.util.MacAddress; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -494,6 +495,61 @@ public void testNewPacket() { } } + @Test + public void testNewPacketUnOrdered(){ + try { + //raw data bytes string for unordered probe request + String rawDataString = "40000000ffffffffffff984be157aaf7ffffffffffff30b100034f454e010802040b0c1216182403010b2d1a" + + "600100ff0000000100000000000000000000000000000000000032043048606cf2825146"; + Integer fcsFromRawString = 1179747058; + byte[] rawData = ByteArrays.parseByteArray(rawDataString,""); + Dot11ProbeRequestPacket p + = Dot11ProbeRequestPacket.newPacket(rawData, 0, rawData.length); + assertEquals(p.getFcs(), fcsFromRawString); + }catch (IllegalRawDataException e) { + throw new AssertionError(e); + } + } + + @Test + public void testNewPacketOrdered(){ + try { + //raw data bytes string for ordered probe request + String rawDataString = "40000000ffffffffffffe4b318621f4cffffffffffff00140000010882840b168c92182432053048606cff" + + "2d1ae70917ffff0000000000000000000000000000000000000000008554ed06"; + Integer fcsFromRawString = 116216965; + byte[] rawData = ByteArrays.parseByteArray(rawDataString,""); + Dot11ProbeRequestPacket p + = Dot11ProbeRequestPacket.newPacket(rawData, 0, rawData.length); + + assertEquals(p.getFcs(), fcsFromRawString); + }catch (IllegalRawDataException e) { + throw new AssertionError(e); + } + } + + @Test + public void testNewPacketInformationElementOrder(){ + try { + //raw data bytes string for unordered probe request + String rawDataString = "40000000ffffffffffff984be157aaf7ffffffffffff30b100034f454e010802040b0c1216182403010b2d1a" + + "600100ff0000000100000000000000000000000000000000000032043048606cf2825146"; + + byte[] rawData = ByteArrays.parseByteArray(rawDataString,""); + Dot11ProbeRequestPacket p + = Dot11ProbeRequestPacket.newPacket(rawData, 0, rawData.length); + List informationElementOrderedList = p.getHeader().getInformationElementOrderedList(); + + assertEquals(informationElementOrderedList.get(0).getElementId().name(),"SSID"); + assertEquals(informationElementOrderedList.get(1).getElementId().name(),"Supported rates"); + assertEquals(informationElementOrderedList.get(2).getElementId().name(),"DSSS Parameter Set"); + assertEquals(informationElementOrderedList.get(3).getElementId().name(),"HT Capabilities"); + assertEquals(informationElementOrderedList.get(4).getElementId().name(),"Extended Supported Rates"); + }catch (IllegalRawDataException e) { + throw new AssertionError(e); + } + } + @Test public void testGetHeader() { Dot11ProbeRequestHeader h = packet.getHeader();