package com.netifera.platform.net.wifi.decoders; import java.nio.ByteBuffer; import com.netifera.platform.net.packets.IPacketDecoder; import com.netifera.platform.net.packets.IPacketHeader; import com.netifera.platform.net.packets.PacketPayload; import com.netifera.platform.net.packets.decoders.LLCDecoder; import com.netifera.platform.net.wifi.packets.ATIM; import com.netifera.platform.net.wifi.packets.Ack; import com.netifera.platform.net.wifi.packets.AssociationRequest; import com.netifera.platform.net.wifi.packets.AssociationResponse; import com.netifera.platform.net.wifi.packets.Beacon; import com.netifera.platform.net.wifi.packets.CTS; import com.netifera.platform.net.wifi.packets.ControlFrame; import com.netifera.platform.net.wifi.packets.DataFrame; import com.netifera.platform.net.wifi.packets.Deauthentication; import com.netifera.platform.net.wifi.packets.Disassociation; import com.netifera.platform.net.wifi.packets.PSPoll; import com.netifera.platform.net.wifi.packets.ProbeRequest; import com.netifera.platform.net.wifi.packets.ProbeResponse; import com.netifera.platform.net.wifi.packets.RTS; import com.netifera.platform.net.wifi.packets.WiFiFrame; public class WiFiDecoder implements IPacketDecoder { private final static IPacketDecoder llcDecoder = new LLCDecoder(); public IPacketHeader decode(ByteBuffer buffer) { final ByteBuffer wifiBuffer = buffer.slice(); final int x = wifiBuffer.get(0); final int mainType = (x & 0x0c) >> 2; final int subType = (x & 0xf0) >> 4; final int type = (mainType << 4) | subType; if(mainType == WiFiFrame.MGT_FRAME) { return decodeManagement(type, wifiBuffer); } else if(mainType == WiFiFrame.DATA_FRAME) { return decodeData(wifiBuffer); } else if(mainType == WiFiFrame.CONTROL_FRAME) { return decodeControl(type, wifiBuffer); } return decodeManagement(type, wifiBuffer); } private IPacketHeader decodeData(ByteBuffer buffer) { DataFrame dataFrame = new DataFrame(); if(!dataFrame.unpack(buffer)) { return new PacketPayload(buffer); } dataFrame.setNextPacket( llcDecoder.decode(buffer) ); return dataFrame; } private IPacketHeader decodeManagement(int type, ByteBuffer buffer) { final IPacketHeader header = getManagementHeader(type); if(header != null && header.unpack(buffer)) { return header; } else { return new PacketPayload(buffer); } } private IPacketHeader decodeControl(int type, ByteBuffer buffer) { final IPacketHeader header = getControlHeader(type); if(header != null && header.unpack(buffer)) { return header; } else { return new PacketPayload(buffer); } } private IPacketHeader getManagementHeader(int type) { switch(type) { case WiFiFrame.MGT_ASSOC_REQ: case WiFiFrame.MGT_REASSOC_REQ: return new AssociationRequest(); case WiFiFrame.MGT_ASSOC_RESP: case WiFiFrame.MGT_REASSOC_RESP: return new AssociationResponse(); case WiFiFrame.MGT_PROBE_REQ: return new ProbeRequest(); case WiFiFrame.MGT_PROBE_RESP: return new ProbeResponse(); case WiFiFrame.MGT_BEACON: return new Beacon(); case WiFiFrame.MGT_ATIM: return new ATIM(); case WiFiFrame.MGT_DISASS: return new Disassociation(); case WiFiFrame.MGT_DEAUTHENTICATION: return new Deauthentication(); default: return null; } } private IPacketHeader getControlHeader(int type) { switch(type) { case WiFiFrame.CTRL_PS_POLL: return new PSPoll(); case WiFiFrame.CTRL_RTS: return new RTS(); case WiFiFrame.CTRL_CTS: return new CTS(); case WiFiFrame.CTRL_ACKNOWLEDGEMENT: return new Ack(); default: return new ControlFrame(); } } // private static final Map<Integer, Class<? extends WiFiFrame>> typeMap; // private static final WiFiDecoder instance; // // static { // typeMap = new HashMap<Integer, Class<? extends WiFiFrame>>(); // typeMap.put(WiFiFrame.MGT_ASSOC_REQ, AssociationRequest.class); // typeMap.put(WiFiFrame.MGT_ASSOC_RESP, AssociationResponse.class); // typeMap.put(WiFiFrame.MGT_REASSOC_REQ, AssociationRequest.class); // typeMap.put(WiFiFrame.MGT_REASSOC_RESP, AssociationResponse.class); // typeMap.put(WiFiFrame.MGT_PROBE_REQ, ProbeRequest.class); // typeMap.put(WiFiFrame.MGT_PROBE_RESP, ProbeResponse.class); // typeMap.put(WiFiFrame.MGT_BEACON, Beacon.class); // typeMap.put(WiFiFrame.MGT_ATIM, ATIM.class); // typeMap.put(WiFiFrame.MGT_DISASS, Disassociation.class); // typeMap.put(WiFiFrame.MGT_AUTHENTICATION, Authentication.class); // typeMap.put(WiFiFrame.MGT_DEAUTHENTICATION, Deauthentication.class); // typeMap.put(WiFiFrame.CTRL_PS_POLL, PSPoll.class); // typeMap.put(WiFiFrame.CTRL_RTS, RTS.class); // typeMap.put(WiFiFrame.CTRL_CTS, CTS.class); // typeMap.put(WiFiFrame.CTRL_ACKNOWLEDGEMENT, Ack.class); // // typeMap.put(WiFiFrame.CTRL_CFP_END, ControlFrame.class); // // typeMap.put(WiFiFrame.CTRL_CFP_ENDACK, ControlFrame.class); // // instance = new WiFiDecoder(); // instance.put(DataFrame.class, 0, LLCDecoder.defaultInstance()); // } // // static public WiFiDecoder defaultInstance() { // return instance; // } // // public WiFiDecoder() { // super(); // } // // public IPacket decode(byte[] data, int offset, int length) { // int x = data[offset]; //// int version = x & 0x03; // int mainType = (x & 0x0c) >> 2; // int subType = (x & 0xf0) >> 4; // int type = (mainType << 4) | subType; // //// System.out.println("wifi: "+hexa(data, offset)); //// System.out.println(String.format("%x %x %x", type, mainType, subType)); // Class<? extends WiFiFrame> packetClass = typeMap.get(type); // if (packetClass == null) { // switch (mainType) { // case WiFiFrame.CONTROL_FRAME: packetClass = ControlFrame.class; // break; // case WiFiFrame.DATA_FRAME: packetClass = DataFrame.class; // break; // case WiFiFrame.MGT_FRAME: packetClass = ManagementFrame.class; // break; // default: // throw new PacketDecodeException("Unknown frame type "+type); // } // } // return decode(data, offset, length, packetClass); // } // // XXX /* private String hexa(byte[] bytes, int offset) { final String xlat = "0123456789abcdef"; String answer = ""; for (int i=offset; i<bytes.length; i++) { byte x = bytes[i]; answer += String.valueOf(xlat.charAt((x >>> 4) & 0x0F)) + String.valueOf(xlat.charAt(x & 0x0F)); } return answer; }*/ }