diff --git a/src/zutil/net/dns/DNSPacket.java b/src/zutil/net/dns/DNSPacket.java new file mode 100755 index 0000000..868933a --- /dev/null +++ b/src/zutil/net/dns/DNSPacket.java @@ -0,0 +1,52 @@ +package zutil.net.dns; + +import zutil.parser.binary.BinaryStructOutputStream; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; + +/** + * This class is a general wrapper for a whole DNS packet. + * + * Created by ezivkoc on 2016-04-11. + */ +public class DNSPacket { + private DNSPacketHeader header; + private ArrayList questions; + private ArrayList answerRecords; + private ArrayList nameServers; + private ArrayList additionalRecords; + + + public DNSPacket(){ + header = new DNSPacketHeader(); + questions = new ArrayList<>(); + answerRecords = new ArrayList<>(); + nameServers = new ArrayList<>(); + additionalRecords = new ArrayList<>(); + } + + + public static DNSPacket read(InputStream in){ + return null; + } + + public void write(OutputStream out) throws IOException { + BinaryStructOutputStream structOut = new BinaryStructOutputStream(out); + structOut.write(header); + out.flush(); + + /*for (DNSPacketQuestion question : questions) + question.write(out); + for (DNSPacketResource answerRecord : answerRecords) + answerRecord.write(out); + for (DNSPacketResource nameServer : nameServers) + nameServer.write(out); + for (DNSPacketResource additionalRecord : additionalRecords) + additionalRecord.write(out);*/ + } + +} diff --git a/src/zutil/net/dns/DNSPacketQuestion.java b/src/zutil/net/dns/DNSPacketQuestion.java index c9546fc..fa61531 100755 --- a/src/zutil/net/dns/DNSPacketQuestion.java +++ b/src/zutil/net/dns/DNSPacketQuestion.java @@ -24,8 +24,14 @@ package zutil.net.dns; +import zutil.parser.binary.BinaryFieldData; +import zutil.parser.binary.BinaryFieldSerializer; import zutil.parser.binary.BinaryStruct; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + /** * Created by Ziver on 2016-02-09. * Reference: http://tools.ietf.org/html/rfc1035 @@ -64,6 +70,40 @@ public class DNSPacketQuestion implements BinaryStruct { For example, the QCLASS field is IN for the Internet. */ + @CustomBinaryField(index=10, serializer=QNameSerializer.class) + private String qName; + @BinaryField(index=10, length=1) + private int qType; + @BinaryField(index=20, length=1) + private int qClass; + + + private static class QNameSerializer implements BinaryFieldSerializer { + + public String read(InputStream in, BinaryFieldData field) throws IOException { + StringBuilder str = new StringBuilder(); + int c = in.read(); + while (c > 0){ + for (int i=0; i 0) + str.append('.'); + } + return toString(); + } + + public void write(OutputStream out, String domain, BinaryFieldData field) throws IOException { + String[] labels = domain.split("."); + for (String label : labels){ + out.write(label.length()); + out.write(label.getBytes()); + } + out.write(0); + } + + } } diff --git a/src/zutil/net/dns/DNSPacketResource.java b/src/zutil/net/dns/DNSPacketResource.java index 9b447d9..be2b5b8 100755 --- a/src/zutil/net/dns/DNSPacketResource.java +++ b/src/zutil/net/dns/DNSPacketResource.java @@ -26,6 +26,10 @@ package zutil.net.dns; import zutil.parser.binary.BinaryStruct; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + /** * Created by Ziver on 2016-02-09. * Reference: http://tools.ietf.org/html/rfc1035 @@ -85,4 +89,13 @@ public class DNSPacketResource implements BinaryStruct { the RDATA field is a 4 octet ARPA Internet address. */ + + public static DNSPacketResource read(InputStream in){ + return null; + } + + public void write(OutputStream out) throws IOException { + + } + } diff --git a/src/zutil/net/dns/MulticastDNSClient.java b/src/zutil/net/dns/MulticastDNSClient.java index db791a8..616b397 100755 --- a/src/zutil/net/dns/MulticastDNSClient.java +++ b/src/zutil/net/dns/MulticastDNSClient.java @@ -53,11 +53,10 @@ public class MulticastDNSClient extends ThreadedUDPNetwork implements ThreadedUD BinaryStructOutputStream out = new BinaryStructOutputStream(buffer); DNSPacketHeader header = new DNSPacketHeader(); + header.setDefaultQueryData(); out.write(header); - DatagramPacket packet = null; - - packet = new DatagramPacket( + DatagramPacket packet = new DatagramPacket( buffer.toByteArray(), buffer.size(), InetAddress.getByName( MDNS_MULTICAST_ADDR ), MDNS_MULTICAST_PORT ); diff --git a/src/zutil/parser/binary/BinaryFieldData.java b/src/zutil/parser/binary/BinaryFieldData.java index 01df0df..28ead5b 100755 --- a/src/zutil/parser/binary/BinaryFieldData.java +++ b/src/zutil/parser/binary/BinaryFieldData.java @@ -1,48 +1,62 @@ package zutil.parser.binary; -import java.io.InvalidClassException; -import java.io.InvalidObjectException; import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; +import java.util.*; -import zutil.ByteUtil; import zutil.converter.Converter; -import zutil.parser.binary.BinaryStruct.BinaryField; +import zutil.parser.binary.BinaryStruct.*; /** * A class representing each field in a BinaryStruct. */ -public class BinaryFieldData implements Comparable { +public class BinaryFieldData { private static final HashMap> cache = new HashMap<>(); private int index; private int length; + private BinaryFieldSerializer serializer; private Field field; protected static List getStructFieldList(Class clazz){ if (!cache.containsKey(clazz)) { - ArrayList list = new ArrayList<>(); - for (Field field : clazz.getDeclaredFields()) { - if (field.isAnnotationPresent(BinaryField.class)) - list.add(new BinaryFieldData(field)); + try { + ArrayList list = new ArrayList<>(); + for (Field field : clazz.getDeclaredFields()) { + if (field.isAnnotationPresent(BinaryField.class) || + field.isAnnotationPresent(CustomBinaryField.class)) + + list.add(new BinaryFieldData(field)); + + } + Collections.sort(list, new Comparator(){ + @Override + public int compare(BinaryFieldData o1, BinaryFieldData o2) { + return o1.index - o2.index; + } + }); + cache.put(clazz, list); + } catch (Exception e) { + throw new RuntimeException(e); } - Collections.sort(list); - cache.put(clazz, list); } return cache.get(clazz); } - private BinaryFieldData(Field f){ + private BinaryFieldData(Field f) throws IllegalAccessException, InstantiationException { field = f; - BinaryField fieldData = field.getAnnotation(BinaryField.class); - index = fieldData.index(); - length = fieldData.length(); + if (field.isAnnotationPresent(CustomBinaryField.class)){ + CustomBinaryField fieldData = field.getAnnotation(CustomBinaryField.class); + index = fieldData.index(); + serializer = (BinaryFieldSerializer) fieldData.serializer().newInstance(); + } + else { + BinaryField fieldData = field.getAnnotation(BinaryField.class); + index = fieldData.index(); + length = fieldData.length(); + } } protected void setValue(Object obj, byte[] data){ @@ -54,6 +68,8 @@ public class BinaryFieldData implements Comparable { field.set(obj, Converter.toInt(data)); else if (field.getType() == String.class) field.set(obj, new String(data)); + else + throw new UnsupportedOperationException("Unsupported BinaryStruct field class: "+ field.getClass()); } catch (IllegalAccessException e){ e.printStackTrace(); } @@ -81,8 +97,4 @@ public class BinaryFieldData implements Comparable { return length; } - @Override - public int compareTo(BinaryFieldData o) { - return this.index - o.index; - } } \ No newline at end of file diff --git a/src/zutil/parser/binary/BinaryFieldSerializer.java b/src/zutil/parser/binary/BinaryFieldSerializer.java new file mode 100755 index 0000000..df610eb --- /dev/null +++ b/src/zutil/parser/binary/BinaryFieldSerializer.java @@ -0,0 +1,21 @@ +package zutil.parser.binary; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * An Interface where custom field parser and writer can be implemented. + * NOTE: Partial octet serializing not supported. + * + * Created by Ziver on 2016-04-11. + */ +public interface BinaryFieldSerializer { + + T read(InputStream in, + BinaryFieldData field) throws IOException; + + void write(OutputStream out, + T obj, + BinaryFieldData field) throws IOException; +} diff --git a/src/zutil/parser/binary/BinaryStruct.java b/src/zutil/parser/binary/BinaryStruct.java index bb4c942..c1d9000 100755 --- a/src/zutil/parser/binary/BinaryStruct.java +++ b/src/zutil/parser/binary/BinaryStruct.java @@ -30,7 +30,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** - * Created by ezivkoc on 2016-01-28. + * Created by Ziver on 2016-01-28. */ public interface BinaryStruct { @@ -40,4 +40,11 @@ public interface BinaryStruct { int index(); int length(); } + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.FIELD) + @interface CustomBinaryField{ + int index(); + Class serializer(); + } }