package com.netifera.platform.net.dns.internal.sniffing; import java.io.IOException; import org.xbill.DNS.AAAARecord; import org.xbill.DNS.ARecord; import org.xbill.DNS.CNAMERecord; import org.xbill.DNS.MXRecord; import org.xbill.DNS.Message; import org.xbill.DNS.NSRecord; import org.xbill.DNS.PTRRecord; import org.xbill.DNS.Rcode; import org.xbill.DNS.Record; import com.netifera.platform.net.daemon.sniffing.IIPSniffer; import com.netifera.platform.net.daemon.sniffing.IPacketModuleContext; import com.netifera.platform.net.packets.tcpip.IP; import com.netifera.platform.net.packets.tcpip.IPv4; import com.netifera.platform.net.packets.tcpip.IPv6; import com.netifera.platform.net.packets.tcpip.UDP; import com.netifera.platform.net.sniffing.IPacketFilter; import com.netifera.platform.util.addresses.AddressFormatException; import com.netifera.platform.util.addresses.inet.IPv4Address; import com.netifera.platform.util.addresses.inet.IPv6Address; import com.netifera.platform.util.addresses.inet.InternetAddress; public class DNSSniffer implements IIPSniffer { private final boolean DEBUG = System.getProperty("dnssniffer.debug") != null; public IPacketFilter getFilter() { // TODO Auto-generated method stub return null; } public String getName() { return "DNS Sniffer"; } public void handleIPv4Packet(IPv4 ipv4, IPacketModuleContext context) { handleIPPacket(ipv4, context); } public void handleIPv6Packet(IPv6 ipv6, IPacketModuleContext context) { handleIPPacket(ipv6, context); } private void handleIPPacket(IP ip, IPacketModuleContext context) { if (!(ip.getNextHeader() instanceof UDP)) return; UDP udp = (UDP) ip.getNextHeader(); if (udp.getSourcePort() != 53) return; try { Message msg = new Message(udp.payload().toBytes()); // System.err.println(msg); int rcode = msg.getHeader().getRcode(); if (rcode != Rcode.NOERROR && rcode != Rcode.NXDOMAIN) return; // no good response // processRecords(msg.getSectionArray(0), context.getRealm()); processRecords(msg.getSectionArray(1), context); // processRecords(msg.getSectionArray(2), context.getRealm()); // processRecords(msg.getSectionArray(3), context.getRealm()); } catch (IOException e) { // FIXME if (DEBUG) context.printOutput('(' + getName() + ") I/O Error: " + e.getMessage() + " for " + udp); } } private void processRecords(Record[] records, IPacketModuleContext context) { final long realm = context.getRealm(); final long space = context.getSpaceId(); for (Record o: records) { if (o instanceof ARecord) { ARecord a = (ARecord) o; Activator.getInstance().getDomainEntityFactory().createARecord(realm, space, a.getName().toString(), IPv4Address.fromInetAddress(a.getAddress())); } else if (o instanceof AAAARecord) { AAAARecord aaaa = (AAAARecord) o; Activator.getInstance().getDomainEntityFactory().createAAAARecord(realm, space, aaaa.getName().toString(), IPv6Address.fromInetAddress(aaaa.getAddress())); } else if (o instanceof PTRRecord) { PTRRecord ptr = (PTRRecord) o; String reverseName = ptr.getName().toString(); if (!reverseName.endsWith(".arpa.")) { warnUnknownFormat(context, reverseName); continue; } try { InternetAddress address = InternetAddress.fromARPA(reverseName); Activator.getInstance().getDomainEntityFactory().createPTRRecord(realm, space, address, ptr.getTarget().toString()); } catch(AddressFormatException e) { context.printOutput("Could not parse record " + reverseName); } } else if (o instanceof MXRecord) { if (DEBUG) context.printOutput("Unhandled DNS record: "+o); //MXRecord mx = (MXRecord) o; //Activator.getInstance().getDomainEntityFactory().createMXRecord(realm, domain.toString(), mx.getTarget().toString(), mx.getPriority()); } else if (o instanceof NSRecord) { if (DEBUG) context.printOutput("Unhandled DNS record: "+o); //NSRecord ns = (NSRecord) o; //Activator.getInstance().getDomainEntityFactory().createNSRecord(realm, domain.toString(), ns.getTarget().toString()); } else if (o instanceof CNAMERecord) { if (DEBUG) context.printOutput("Unhandled DNS record: "+o); } else { // FIXME should be display to dev people only context.printOutput("Unhandled DNS record: "+o); } } } private void warnUnknownFormat(IPacketModuleContext context, String name) { context.printOutput("Unknown reverse address format: "+ name); } }