/*
* Copyright 2010 NCHOVY
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.krakenapps.pcap.decoder.dhcp;
import java.net.InetAddress;
import java.util.HashSet;
import java.util.Set;
import org.krakenapps.pcap.Protocol;
import org.krakenapps.pcap.decoder.dhcp.options.DhcpOption;
import org.krakenapps.pcap.decoder.dhcp.options.ParameterRequestListOption;
import org.krakenapps.pcap.decoder.ethernet.MacAddress;
import org.krakenapps.pcap.decoder.udp.UdpPacket;
import org.krakenapps.pcap.decoder.udp.UdpProcessor;
import org.krakenapps.pcap.live.PcapDevice;
import org.krakenapps.pcap.live.PcapDeviceManager;
import org.krakenapps.pcap.live.PcapDeviceMetadata;
import org.krakenapps.pcap.util.Buffer;
import org.krakenapps.pcap.util.IpConverter;
import org.krakenapps.pcap.util.PcapLiveRunner;
public class DhcpDecoder implements UdpProcessor {
private Set<DhcpProcessor> callbacks = new HashSet<DhcpProcessor>();
public void register(DhcpProcessor processor) {
callbacks.add(processor);
}
public void unregister(DhcpProcessor processor) {
callbacks.remove(processor);
}
@Override
public void process(UdpPacket p) {
Buffer b = p.getData();
byte op = b.get();
byte htype = b.get();
byte hlen = b.get();
byte hops = b.get();
int xid = b.getInt();
short secs = b.getShort();
short flags = b.getShort();
InetAddress clientAddress = IpConverter.toInetAddress(b.getInt());
InetAddress yourAddress = IpConverter.toInetAddress(b.getInt());
InetAddress nextServerAddress = IpConverter.toInetAddress(b.getInt());
InetAddress gatewayAddress = IpConverter.toInetAddress(b.getInt());
byte[] mac = new byte[6];
b.gets(mac);
MacAddress clientMac = new MacAddress(mac);
byte[] temp = new byte[202];
b.gets(temp);
// check magic cookie
long magicCookie = b.getInt() & 0xffffffffl;
if (magicCookie != 0x63825363L)
return;
DhcpMessage msg = new DhcpMessage();
msg.setMessageType(op);
msg.setHardwareType(htype);
msg.setHardwareAddressLength(hlen);
msg.setHops(hops);
msg.setTransactionId(xid);
msg.setSecs(secs);
msg.setFlags(flags);
msg.setClientAddress(clientAddress);
msg.setYourAddress(yourAddress);
msg.setNextServerAddress(nextServerAddress);
msg.setGatewayAddress(gatewayAddress);
msg.setClientMac(clientMac);
// parse options
int remaining = b.readableBytes();
for (int i = 0; i < remaining;) {
byte type = b.get();
if (type == (byte) 0xFF)
break; // end of option
int length = b.get() & 0xFF;
byte[] value = new byte[length];
b.gets(value);
DhcpOption option = DhcpOptionParser.create(type, length, value);
msg.getOptions().add(option);
i += 2 + length;
}
for (DhcpProcessor callback : callbacks) {
try {
callback.process(msg);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws Exception {
for (PcapDeviceMetadata device : PcapDeviceManager.getDeviceMetadataList()) {
System.out.println(device);
}
PcapDeviceMetadata metadata = PcapDeviceManager.getDeviceMetadataList().get(0);
PcapDevice device = PcapDeviceManager.open(metadata.getName(), Integer.MAX_VALUE);
DhcpDecoder dhcp = new DhcpDecoder();
PcapLiveRunner runner = new PcapLiveRunner(device);
runner.setUdpProcessor(Protocol.DHCP, dhcp);
dhcp.register(new DhcpProcessor() {
@Override
public void process(DhcpMessage msg) {
StringBuilder sb = new StringBuilder();
String finger = null;
int i = 0;
for (DhcpOption option : msg.getOptions()) {
if (i != 0)
sb.append(",");
sb.append(option.getType());
if (option instanceof ParameterRequestListOption) {
ParameterRequestListOption o = (ParameterRequestListOption) option;
finger = "client ip: " + msg.getClientAddress() + " client mac: " + msg.getClientMac()
+ " your ip: " + msg.getYourAddress() + " finger => " + o.getFingerprint();
}
i++;
}
String options = sb.toString();
System.out.println("options: " + options + ", " + finger);
}
});
runner.run();
}
}