Files
packet-master/src/me/joshlarson/PacketMaster.java
T

201 lines
5.6 KiB
Java

package me.joshlarson;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Vector;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import me.joshlarson.gui.GUI;
import me.joshlarson.gui.GUIPacket;
import org.jnetpcap.Pcap;
import org.jnetpcap.nio.JBuffer;
import org.jnetpcap.packet.Payload;
import org.jnetpcap.packet.PcapPacket;
import org.jnetpcap.protocol.network.Ip4;
import com.swgnge.network.PacketType;
import com.swgnge.network.Utilities;
import com.swgnge.network.encryption.Encryption;
import com.swgnge.network.packets.Packet;
import com.swgnge.network.packets.soe.DataChannelA;
import com.swgnge.network.packets.soe.MultiPacket;
import com.swgnge.network.packets.soe.SessionResponse;
import com.swgnge.network.packets.swg.SWGPacket;
public class PacketMaster {
private static final int REMOTE_PING_PORT = 44462;
public enum ConnectionState {
NONE,
CONNECTING,
CONNECTED,
DISCONNECTING,
DISCONNECTED
}
private GUI gui;
private String [] files;
private PacketAnalysis packetAnalysis;
private List <GUIPacket> packets;
private InetAddress client;
private int crc = 0x76FBC4BA;
public static final void main(String [] args) throws Exception {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
PacketMaster master = new PacketMaster();
master.initialize();
master.run();
master.destroy();
System.exit(0);
}
public PacketMaster() {
packetAnalysis = new PacketAnalysis();
packets = new Vector<GUIPacket>();
gui = new GUI(packets);
}
public void initialize() throws IOException {
packetAnalysis.initialize();
files = new String [] {
// "Packets/Crafting/craft_BH_armor_set_0xEEDD424D.cap",
// "Packets/Crafting/craft_lava_resist_kit_0x1EBF709D.cap",
// "Packets/Crafting/craft_mabari-armor_set_0x7BF2F1CD.cap",
// "Packets/Crafting/craft_RIS_armor_set_0x7BF9455D.cap",
// "Packets/Crafting/craft_tailor_bandoliers_AIO Cap_0x7EBF5F20.cap",
// "Packets/Full PSWG Capture.pcap",
// "Packets/pswg_capture2.cap",
// "Packets/corellia_city.cap",
// "Packets/dantooine_city.cap",
// "Packets/mandalore.cap",
// "Packets/talus_city.cap",
"Packets/tattoine_city.cap",
// "Packets/tattoine_wayfar.cap",
// "Packets/speak_to_romo_vax.pcap"
// "Packets/kill_romo_vax.pcap"
};
}
public void run() throws UnknownHostException {
final StringBuilder errbuf = new StringBuilder(); // For any error msgs
for (String file : files) {
System.out.printf("Opening file for reading: %s%n", file);
Pcap pcap = Pcap.openOffline(file, errbuf);
if (pcap == null) {
System.err.printf("Error while opening device for capture: " + errbuf.toString());
return;
}
runAnalysis(pcap);
pcap.close();
}
while (!gui.isClosed()) {
try { Thread.sleep(50); } catch (InterruptedException e) { break; }
}
}
public void destroy() {
packetAnalysis.summarize();
}
private void runAnalysis(Pcap pcap) throws UnknownHostException {
PcapPacket packet = new PcapPacket(500);
int packetCount = 0;
Ip4 ip = new Ip4();
InetAddress addr = null;
Payload p = null;
while (pcap.nextEx(packet) == 1) {
if (packet == null)
return;
if (packet.hasHeader(ip)) {
addr = InetAddress.getByAddress(ip.source());
}
p = new Payload();
JBuffer buffer = packet.getHeader(p);
onPacket(addr, buffer.getByteArray(0, new byte[buffer.size()]), 0);
packetCount++;
if (packetCount == -1)
break;
}
}
private void onPacket(InetAddress addr, byte [] data, int port) {
int length = data.length;
if (length < 2)
return;
if (port != REMOTE_PING_PORT) {
if (data[0] == 0 && data[1] == 1) {
// System.out.println("Client: " + addr.toString());
this.client = addr;
packetAnalysis.setClient(addr);
} else if (data[0] == 0 && data[1] == 2) { // SessionResponse
// System.out.println("Server: " + addr.toString());
packetAnalysis.setServer(addr);
processSessionResponse(data);
} else {
ByteBuffer decrypt = Encryption.decode(ByteBuffer.wrap(data), crc);
if (decrypt.array().length >= 2) {
process(addr, decrypt);
}
}
}
}
private void process(InetAddress addr, ByteBuffer data) {
if (data.remaining() < 2)
return;
short opcode = data.getShort();
switch (opcode) {
case 3: {
MultiPacket multi = new MultiPacket();
multi.decode(data);
for (Packet p : multi.getPackets())
process(addr, p.getData());
break;
}
case 9:
processDataChannelA(addr, data);
break;
}
if (opcode >= 0x1E) {
data.position(0);
Packet.getShort(data); // Priority
int swgOpcode = Packet.getInt(data);
data.position(0);
process(addr, swgOpcode, data);
}
}
private void processDataChannelA(InetAddress addr, ByteBuffer buf) {
DataChannelA data = new DataChannelA(buf);
Vector<SWGPacket> packets = data.getPackets();
for (SWGPacket packet : packets) {
ByteBuffer pData = packet.getData();
pData.position(0);
process(addr, packet.getSWGOpcode(), pData);
}
}
private void process(InetAddress addr, int opcode, ByteBuffer data) {
// packetAnalysis.onPacket(addr, opcode, data);
data.position(0);
SWGPacket packet = PacketType.getForCrc(opcode);
packet.decode(data);
packets.add(new GUIPacket(packet, PacketType.fromCrc(opcode), opcode, addr.equals(client)));
gui.repaint();
}
private void processSessionResponse(byte [] data) {
SessionResponse res = new SessionResponse(ByteBuffer.wrap(data));
crc = res.getCrcSeed();
// System.out.println("New CRC: 0x" + Integer.toHexString(crc).toUpperCase());
}
}