Fixed DNS FQDN parsing
This commit is contained in:
parent
f55473ced0
commit
600a4b648f
9 changed files with 86 additions and 64 deletions
|
|
@ -16,7 +16,7 @@ public class PositionalInputStream extends FilterInputStream {
|
|||
/**
|
||||
* @param in the underlying input stream.
|
||||
*/
|
||||
protected PositionalInputStream(InputStream in) {
|
||||
public PositionalInputStream(InputStream in) {
|
||||
super(in);
|
||||
}
|
||||
|
||||
|
|
@ -60,8 +60,8 @@ public class PositionalInputStream extends FilterInputStream {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void mark(int readlimit) {
|
||||
super.mark(readlimit);
|
||||
public void mark(int readLimit) {
|
||||
super.mark(readLimit);
|
||||
|
||||
synchronized(this) {
|
||||
mark = pos;
|
||||
|
|
|
|||
|
|
@ -78,7 +78,6 @@ public class MulticastDnsClient extends ThreadedUDPNetwork implements ThreadedUD
|
|||
int id = 0; // Needs to be zero when doing multicast
|
||||
activeProbes.add(id);
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
BinaryStructOutputStream out = new BinaryStructOutputStream(buffer);
|
||||
|
||||
DnsPacket dnsPacket = new DnsPacket();
|
||||
dnsPacket.getHeader().id = id;
|
||||
|
|
@ -87,7 +86,7 @@ public class MulticastDnsClient extends ThreadedUDPNetwork implements ThreadedUD
|
|||
domain,
|
||||
DnsConstants.TYPE.SRV,
|
||||
DnsConstants.CLASS.IN));
|
||||
dnsPacket.write(out);
|
||||
dnsPacket.write(buffer);
|
||||
|
||||
DatagramPacket udpPacket = new DatagramPacket(
|
||||
buffer.toByteArray(), buffer.size(),
|
||||
|
|
@ -106,8 +105,7 @@ public class MulticastDnsClient extends ThreadedUDPNetwork implements ThreadedUD
|
|||
try {
|
||||
ByteArrayInputStream buffer = new ByteArrayInputStream(packet.getData(),
|
||||
packet.getOffset(), packet.getLength());
|
||||
BinaryStructInputStream in = new BinaryStructInputStream(buffer);
|
||||
DnsPacket dnsPacket = DnsPacket.read(in);
|
||||
DnsPacket dnsPacket = DnsPacket.read(buffer);
|
||||
|
||||
//System.out.println("Received:\n" +ByteUtil.toFormattedString(packet.getData(), packet.getOffset(), packet.getLength()));
|
||||
MultiPrintStream.out.dump(dnsPacket,3);
|
||||
|
|
|
|||
|
|
@ -112,8 +112,7 @@ public class MulticastDnsServer extends ThreadedUDPNetwork implements ThreadedUD
|
|||
try {
|
||||
ByteArrayInputStream buffer = new ByteArrayInputStream(packet.getData(),
|
||||
packet.getOffset(), packet.getLength());
|
||||
BinaryStructInputStream in = new BinaryStructInputStream(buffer);
|
||||
DnsPacket dnsPacket = DnsPacket.read(in);
|
||||
DnsPacket dnsPacket = DnsPacket.read(buffer);
|
||||
|
||||
// Just handle queries and no responses
|
||||
if (! dnsPacket.getHeader().flagQueryResponse) {
|
||||
|
|
@ -121,9 +120,8 @@ public class MulticastDnsServer extends ThreadedUDPNetwork implements ThreadedUD
|
|||
|
||||
if (response != null) {
|
||||
ByteArrayOutputStream outBuffer = new ByteArrayOutputStream();
|
||||
BinaryStructOutputStream out = new BinaryStructOutputStream(outBuffer);
|
||||
response.write(out);
|
||||
out.close();
|
||||
response.write(outBuffer);
|
||||
outBuffer.close();
|
||||
|
||||
DatagramPacket outPacket = new DatagramPacket(
|
||||
outBuffer.toByteArray(), outBuffer.size(),
|
||||
|
|
|
|||
|
|
@ -24,10 +24,13 @@
|
|||
|
||||
package zutil.net.dns.packet;
|
||||
|
||||
import zutil.io.PositionalInputStream;
|
||||
import zutil.parser.binary.BinaryStructInputStream;
|
||||
import zutil.parser.binary.BinaryStructOutputStream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
|
@ -94,7 +97,9 @@ public class DnsPacket {
|
|||
}
|
||||
|
||||
|
||||
public static DnsPacket read(BinaryStructInputStream structIn) throws IOException {
|
||||
public static DnsPacket read(InputStream in) throws IOException {
|
||||
BinaryStructInputStream structIn = new BinaryStructInputStream(new PositionalInputStream(in));
|
||||
|
||||
DnsPacket packet = new DnsPacket();
|
||||
structIn.read(packet.header);
|
||||
|
||||
|
|
@ -116,7 +121,9 @@ public class DnsPacket {
|
|||
}
|
||||
}
|
||||
|
||||
public void write(BinaryStructOutputStream structOut) throws IOException {
|
||||
public void write(OutputStream out) throws IOException {
|
||||
BinaryStructOutputStream structOut = new BinaryStructOutputStream(out);
|
||||
|
||||
structOut.write(header);
|
||||
|
||||
for (DnsPacketQuestion question : questions)
|
||||
|
|
|
|||
|
|
@ -24,40 +24,64 @@
|
|||
|
||||
package zutil.net.dns.packet;
|
||||
|
||||
import zutil.io.PositionalInputStream;
|
||||
import zutil.parser.binary.BinaryFieldData;
|
||||
import zutil.parser.binary.BinaryFieldSerializer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* A serializer class that can read and write a DNS FQDN in binary format.
|
||||
*/
|
||||
public class FQDNStringSerializer implements BinaryFieldSerializer<String> {
|
||||
private HashMap<Integer, String> stringCache = new HashMap<>();
|
||||
|
||||
|
||||
public String read(InputStream in, BinaryFieldData field) throws IOException {
|
||||
StringBuilder str = new StringBuilder();
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
int pos = (int) ((PositionalInputStream) in).getPosition();
|
||||
int c;
|
||||
|
||||
while ((c=in.read()) > 0) {
|
||||
if (str.length() > 0) // Don't add dot to first loop
|
||||
str.append('.');
|
||||
if (buffer.length() > 0) // Don't add dot to first loop
|
||||
buffer.append('.');
|
||||
|
||||
if ((c & 0b1100_0000) == 0b1100_0000) {
|
||||
// This a offset pointer to the String data
|
||||
// This is an offset pointer to the String data
|
||||
int offset = (c & 0b0011_1111) << 8;
|
||||
offset |= in.read() & 0b1111_1111;
|
||||
str.append(offset);
|
||||
|
||||
if (stringCache.containsKey(offset))
|
||||
buffer.append(stringCache.get(offset));
|
||||
else
|
||||
buffer.append('<').append(offset).append('>');
|
||||
break; // PTR is always the last part of the FQDN
|
||||
} else {
|
||||
// Normal String data
|
||||
// Read normal String data
|
||||
for (int i = 0; i < c; ++i) {
|
||||
str.append((char) in.read());
|
||||
buffer.append((char) in.read());
|
||||
}
|
||||
}
|
||||
}
|
||||
return str.toString();
|
||||
|
||||
String output = buffer.toString();
|
||||
|
||||
// Populate cache
|
||||
if (in instanceof PositionalInputStream) {
|
||||
stringCache.put(pos, output);
|
||||
for (int index = 0; index >= 0;) {
|
||||
index = buffer.indexOf(".", index);
|
||||
if (index >= 0) {
|
||||
++index;
|
||||
stringCache.put(pos + index, buffer.substring(index));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
public void write(OutputStream out, String domain, BinaryFieldData field) throws IOException {
|
||||
|
|
@ -70,5 +94,4 @@ public class FQDNStringSerializer implements BinaryFieldSerializer<String> {
|
|||
}
|
||||
out.write(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,15 +29,13 @@ import java.io.InputStream;
|
|||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* An Interface where custom field parser and writer can be implemented.
|
||||
* An Interface defining a custom field parser and writer.
|
||||
* <p></p>
|
||||
* One instance of the serializer and will have the scope of the methods
|
||||
* {@link BinaryStructInputStream#read(BinaryStruct)} and {@link BinaryStructOutputStream#write(BinaryStruct)}
|
||||
* where as it will be deallocated after the methods have returned.
|
||||
* One singleton instance of the serializer will be instantiated for the lifetime of the
|
||||
* {@link BinaryStructInputStream} and {@link BinaryStructOutputStream} objects.
|
||||
* <p></p>
|
||||
* NOTE: Partial octet serializing not supported.
|
||||
*
|
||||
* Created by Ziver on 2016-04-11.
|
||||
*/
|
||||
public interface BinaryFieldSerializer<T> {
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ import java.util.Map;
|
|||
|
||||
/**
|
||||
* A stream class that parses a byte stream into binary struct objects.
|
||||
* <p><p/>
|
||||
* <p></p>
|
||||
* Limitations:<br>
|
||||
* - Does not support sub binary objects.<br>
|
||||
*
|
||||
|
|
@ -47,6 +47,9 @@ public class BinaryStructInputStream {
|
|||
private byte data;
|
||||
private int dataBitIndex = -1;
|
||||
|
||||
private Map<Class, BinaryFieldSerializer> serializerCache = new HashMap<>();
|
||||
|
||||
|
||||
public BinaryStructInputStream(InputStream in) {
|
||||
this.in = in;
|
||||
}
|
||||
|
|
@ -78,7 +81,6 @@ public class BinaryStructInputStream {
|
|||
*/
|
||||
public int read(BinaryStruct struct) throws IOException {
|
||||
List<BinaryFieldData> structDataList = BinaryFieldData.getStructFieldList(struct.getClass());
|
||||
Map<Class, BinaryFieldSerializer> serializerCache = new HashMap<>();
|
||||
|
||||
int totalReadLength = 0;
|
||||
for (BinaryFieldData field : structDataList) {
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ import java.util.Map;
|
|||
|
||||
/**
|
||||
* A stream class that generates a byte stream from a binary struct objects.
|
||||
* <p><p/>
|
||||
* <p></p>
|
||||
* Limitations:<br>
|
||||
* - Does not support sub binary objects.<br>
|
||||
*
|
||||
|
|
@ -48,6 +48,8 @@ public class BinaryStructOutputStream {
|
|||
private byte rest;
|
||||
private int restBitLength; // length from Most Significant Bit
|
||||
|
||||
private Map<Class, BinaryFieldSerializer> serializerCache = new HashMap<>();
|
||||
|
||||
|
||||
public BinaryStructOutputStream(OutputStream out) {
|
||||
this.out = out;
|
||||
|
|
@ -88,7 +90,6 @@ public class BinaryStructOutputStream {
|
|||
*/
|
||||
public void write(BinaryStruct struct) throws IOException {
|
||||
List<BinaryFieldData> structDataList = BinaryFieldData.getStructFieldList(struct.getClass());
|
||||
Map<Class, BinaryFieldSerializer> serializerCache = new HashMap<>();
|
||||
|
||||
for (BinaryFieldData field : structDataList) {
|
||||
if (field.hasSerializer()) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue