Bugfixes in BinaryStruct and some Tests for MDNS
This commit is contained in:
parent
64a9b4126c
commit
96e7d4489a
9 changed files with 320 additions and 117 deletions
|
|
@ -65,7 +65,6 @@ public class ByteUtil {
|
|||
* @return a new byte containing a sub byte defined by the index and length
|
||||
*/
|
||||
public static byte getBits(byte data, int index, int length){
|
||||
length--;
|
||||
byte ret = (byte) (data & getBitMask(index, length));
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -77,6 +76,7 @@ public class ByteUtil {
|
|||
* @param length length of mask from index, valid values 1-8
|
||||
*/
|
||||
public static byte getBitMask(int index, int length) {
|
||||
--length;
|
||||
if(0 > index || index > 7)
|
||||
throw new IllegalArgumentException("Invalid index argument, allowed value is 0-7");
|
||||
if(length < 0 && index-length < 0)
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ import zutil.parser.binary.BinaryStruct;
|
|||
* Created by Ziver on 2016-02-09.
|
||||
* Reference: http://tools.ietf.org/html/rfc1035
|
||||
*/
|
||||
public class DNSPacket implements BinaryStruct {
|
||||
public class DNSPacketHeader implements BinaryStruct {
|
||||
public static final int OPCODE_QUERY = 0;
|
||||
public static final int OPCODE_IQUERY = 1;
|
||||
public static final int OPCODE_STATUS = 2;
|
||||
|
|
@ -42,9 +42,33 @@ public class DNSPacket implements BinaryStruct {
|
|||
public static final int RCODE_NOT_IMPLEMENTED = 4;
|
||||
public static final int RCODE_REFUSED = 5;
|
||||
|
||||
/*
|
||||
Header section format
|
||||
|
||||
The header contains the following fields:
|
||||
|
||||
1 1 1 1 1 1
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| ID |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
|QR| Opcode |AA|TC|RD|RA| Z | RCODE |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| QDCOUNT |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| ANCOUNT |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| NSCOUNT |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| ARCOUNT |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
|
||||
where:
|
||||
*/
|
||||
|
||||
|
||||
@BinaryField(index=0, length=16)
|
||||
int id;
|
||||
public int id;
|
||||
|
||||
//////////////// FLAGS
|
||||
//@BinaryField(index=10, length=16)
|
||||
|
|
@ -54,7 +78,7 @@ public class DNSPacket implements BinaryStruct {
|
|||
* query (0), or a response (1).
|
||||
*/
|
||||
@BinaryField(index=10, length=1)
|
||||
boolean flagQueryResponse;
|
||||
public boolean flagQueryResponse;
|
||||
/**
|
||||
* A four bit field that specifies kind of query in this message.
|
||||
* <pre>
|
||||
|
|
@ -64,21 +88,21 @@ public class DNSPacket implements BinaryStruct {
|
|||
* </pre>
|
||||
*/
|
||||
@BinaryField(index=11, length=4)
|
||||
int flagOperationCode;
|
||||
public int flagOperationCode;
|
||||
/**
|
||||
* This bit is valid in responses,
|
||||
* and specifies that the responding name server is an
|
||||
* authority for the domain name in question section.
|
||||
*/
|
||||
@BinaryField(index=12, length=1)
|
||||
boolean flagAuthoritativeAnswer;
|
||||
public boolean flagAuthoritativeAnswer;
|
||||
/**
|
||||
* specifies that this message was truncated
|
||||
* due to length greater than that permitted on the
|
||||
* transmission channel.
|
||||
*/
|
||||
@BinaryField(index=13, length=1)
|
||||
boolean flagTruncation;
|
||||
public boolean flagTruncation;
|
||||
/**
|
||||
* this bit may be set in a query and
|
||||
* is copied into the response. If RD is set, it directs
|
||||
|
|
@ -86,20 +110,20 @@ public class DNSPacket implements BinaryStruct {
|
|||
* Recursive query support is optional.
|
||||
*/
|
||||
@BinaryField(index=14, length=1)
|
||||
boolean flagRecursionDesired;
|
||||
public boolean flagRecursionDesired;
|
||||
/**
|
||||
* this be is set or cleared in a
|
||||
* response, and denotes whether recursive query support is
|
||||
* available in the name server.
|
||||
*/
|
||||
@BinaryField(index=15, length=1)
|
||||
boolean flagRecursionAvailable;
|
||||
public boolean flagRecursionAvailable;
|
||||
/**
|
||||
* Reserved for future use. Must be zero in all queries
|
||||
* and responses.
|
||||
*/
|
||||
@BinaryField(index=16, length=3)
|
||||
private int z;
|
||||
protected int z;
|
||||
/**
|
||||
* this field is set as part of responses.
|
||||
* The values have the following interpretation:
|
||||
|
|
@ -123,7 +147,7 @@ public class DNSPacket implements BinaryStruct {
|
|||
*</pre>
|
||||
*/
|
||||
@BinaryField(index=17, length=4)
|
||||
int flagResponseCode;
|
||||
public int flagResponseCode;
|
||||
|
||||
|
||||
//////////////// COUNTS
|
||||
|
|
@ -132,115 +156,57 @@ public class DNSPacket implements BinaryStruct {
|
|||
* Specifying the number of entries in the question section.
|
||||
*/
|
||||
@BinaryField(index=20, length=16)
|
||||
int countQuestion;
|
||||
public int countQuestion;
|
||||
/**
|
||||
* Answer Record Count.
|
||||
* specifying the number of resource records in
|
||||
* the answer section.
|
||||
*/
|
||||
@BinaryField(index=21, length=16)
|
||||
int countAnswerRecord;
|
||||
public int countAnswerRecord;
|
||||
/**
|
||||
* Name Server (Authority Record) Count.
|
||||
* Specifying the number of name server resource records
|
||||
* in the authority records section.
|
||||
*/
|
||||
@BinaryField(index=22, length=16)
|
||||
int countNameServer;
|
||||
public int countNameServer;
|
||||
/**
|
||||
* Additional Record Count.
|
||||
* Specifying the number of resource records in the
|
||||
* additional records section
|
||||
*/
|
||||
@BinaryField(index=23, length=16)
|
||||
int countAdditionalRecord;
|
||||
public int countAdditionalRecord;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Question section format
|
||||
1 1 1 1 1 1
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| |
|
||||
/ QNAME /
|
||||
/ /
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| QTYPE |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| QCLASS |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
|
||||
where:
|
||||
|
||||
QNAME a domain name represented as a sequence of labels, where
|
||||
each label consists of a length octet followed by that
|
||||
number of octets. The domain name terminates with the
|
||||
zero length octet for the null label of the root. Note
|
||||
that this field may be an odd number of octets; no
|
||||
padding is used.
|
||||
|
||||
QTYPE a two octet code which specifies the type of the query.
|
||||
The values for this field include all codes valid for a
|
||||
TYPE field, together with some more general codes which
|
||||
can match more than one type of RR.
|
||||
public void setDefaultQueryData() {
|
||||
// Set all flags to zero
|
||||
flagQueryResponse = false;
|
||||
flagOperationCode = 0;
|
||||
flagAuthoritativeAnswer = false;
|
||||
flagTruncation = false;
|
||||
flagRecursionDesired = false;
|
||||
flagRecursionAvailable = false;
|
||||
z = 0;
|
||||
flagResponseCode = 0;
|
||||
}
|
||||
|
||||
QCLASS a two octet code that specifies the class of the query.
|
||||
For example, the QCLASS field is IN for the Internet.
|
||||
*/
|
||||
public void setDefaultResponseData() {
|
||||
flagQueryResponse = true;
|
||||
flagAuthoritativeAnswer = true;
|
||||
|
||||
/*
|
||||
Resource record format
|
||||
|
||||
The answer, authority, and additional sections all share the same
|
||||
format: a variable number of resource records, where the number of
|
||||
records is specified in the corresponding count field in the header.
|
||||
Each resource record has the following format:
|
||||
1 1 1 1 1 1
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| |
|
||||
/ /
|
||||
/ NAME /
|
||||
| |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| TYPE |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| CLASS |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| TTL |
|
||||
| |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| RDLENGTH |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
|
||||
/ RDATA /
|
||||
/ /
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
|
||||
where:
|
||||
|
||||
NAME a domain name to which this resource record pertains.
|
||||
|
||||
TYPE two octets containing one of the RR type codes. This
|
||||
field specifies the meaning of the data in the RDATA
|
||||
field.
|
||||
|
||||
CLASS two octets which specify the class of the data in the
|
||||
RDATA field.
|
||||
|
||||
TTL a 32 bit unsigned integer that specifies the time
|
||||
interval (in seconds) that the resource record may be
|
||||
cached before it should be discarded. Zero values are
|
||||
interpreted to mean that the RR can only be used for the
|
||||
transaction in progress, and should not be cached.
|
||||
|
||||
RDLENGTH an unsigned 16 bit integer that specifies the length in
|
||||
octets of the RDATA field.
|
||||
|
||||
RDATA a variable length string of octets that describes the
|
||||
resource. The format of this information varies
|
||||
according to the TYPE and CLASS of the resource record.
|
||||
For example, the if the TYPE is A and the CLASS is IN,
|
||||
the RDATA field is a 4 octet ARPA Internet address.
|
||||
*/
|
||||
// Set the rest to zero
|
||||
// TODO: all flags should not be zeroed
|
||||
flagOperationCode = 0;
|
||||
flagTruncation = false;
|
||||
flagRecursionDesired = false;
|
||||
flagRecursionAvailable = false;
|
||||
z = 0;
|
||||
flagResponseCode = 0;
|
||||
}
|
||||
}
|
||||
69
src/zutil/net/dns/DNSPacketQuestion.java
Executable file
69
src/zutil/net/dns/DNSPacketQuestion.java
Executable file
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Ziver Koc
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package zutil.net.dns;
|
||||
|
||||
import zutil.parser.binary.BinaryStruct;
|
||||
|
||||
/**
|
||||
* Created by Ziver on 2016-02-09.
|
||||
* Reference: http://tools.ietf.org/html/rfc1035
|
||||
*/
|
||||
public class DNSPacketQuestion implements BinaryStruct {
|
||||
|
||||
/*
|
||||
Question section format
|
||||
1 1 1 1 1 1
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| |
|
||||
/ QNAME /
|
||||
/ /
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| QTYPE |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| QCLASS |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
|
||||
where:
|
||||
|
||||
QNAME a domain name represented as a sequence of labels, where
|
||||
each label consists of a length octet followed by that
|
||||
number of octets. The domain name terminates with the
|
||||
zero length octet for the null label of the root. Note
|
||||
that this field may be an odd number of octets; no
|
||||
padding is used.
|
||||
|
||||
QTYPE a two octet code which specifies the type of the query.
|
||||
The values for this field include all codes valid for a
|
||||
TYPE field, together with some more general codes which
|
||||
can match more than one type of RR.
|
||||
|
||||
QCLASS a two octet code that specifies the class of the query.
|
||||
For example, the QCLASS field is IN for the Internet.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
}
|
||||
88
src/zutil/net/dns/DNSPacketResource.java
Executable file
88
src/zutil/net/dns/DNSPacketResource.java
Executable file
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Ziver Koc
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package zutil.net.dns;
|
||||
|
||||
import zutil.parser.binary.BinaryStruct;
|
||||
|
||||
/**
|
||||
* Created by Ziver on 2016-02-09.
|
||||
* Reference: http://tools.ietf.org/html/rfc1035
|
||||
*/
|
||||
public class DNSPacketResource implements BinaryStruct {
|
||||
|
||||
/*
|
||||
The answer, authority, and additional sections all share the same
|
||||
format: a variable number of resource records, where the number of
|
||||
records is specified in the corresponding count field in the header.
|
||||
Each resource record has the following format:
|
||||
1 1 1 1 1 1
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| |
|
||||
/ /
|
||||
/ NAME /
|
||||
| |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| TYPE |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| CLASS |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| TTL |
|
||||
| |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| RDLENGTH |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
|
||||
/ RDATA /
|
||||
/ /
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
|
||||
where:
|
||||
|
||||
NAME a domain name to which this resource record pertains.
|
||||
|
||||
TYPE two octets containing one of the RR type codes. This
|
||||
field specifies the meaning of the data in the RDATA
|
||||
field.
|
||||
|
||||
CLASS two octets which specify the class of the data in the
|
||||
RDATA field.
|
||||
|
||||
TTL a 32 bit unsigned integer that specifies the time
|
||||
interval (in seconds) that the resource record may be
|
||||
cached before it should be discarded. Zero values are
|
||||
interpreted to mean that the RR can only be used for the
|
||||
transaction in progress, and should not be cached.
|
||||
|
||||
RDLENGTH an unsigned 16 bit integer that specifies the length in
|
||||
octets of the RDATA field.
|
||||
|
||||
RDATA a variable length string of octets that describes the
|
||||
resource. The format of this information varies
|
||||
according to the TYPE and CLASS of the resource record.
|
||||
For example, the if the TYPE is A and the CLASS is IN,
|
||||
the RDATA field is a 4 octet ARPA Internet address.
|
||||
*/
|
||||
|
||||
}
|
||||
|
|
@ -33,7 +33,6 @@ import java.io.ByteArrayOutputStream;
|
|||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
/**
|
||||
* Created by Ziver
|
||||
|
|
@ -49,12 +48,11 @@ public class MulticastDNSClient extends ThreadedUDPNetwork implements ThreadedUD
|
|||
}
|
||||
|
||||
|
||||
public void sendProbe() {
|
||||
try {
|
||||
public void sendProbe() throws IOException {
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
BinaryStructOutputStream out = new BinaryStructOutputStream(buffer);
|
||||
|
||||
DNSPacket header = new DNSPacket();
|
||||
DNSPacketHeader header = new DNSPacketHeader();
|
||||
out.write(header);
|
||||
|
||||
DatagramPacket packet = null;
|
||||
|
|
@ -64,14 +62,11 @@ public class MulticastDNSClient extends ThreadedUDPNetwork implements ThreadedUD
|
|||
InetAddress.getByName( MDNS_MULTICAST_ADDR ),
|
||||
MDNS_MULTICAST_PORT );
|
||||
send(packet);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receivedPacket(DatagramPacket packet, ThreadedUDPNetwork network) {
|
||||
DNSPacket header = new DNSPacket();
|
||||
DNSPacketHeader header = new DNSPacketHeader();
|
||||
BinaryStructInputStream.read(header, packet.getData());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,15 @@
|
|||
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 zutil.ByteUtil;
|
||||
import zutil.converter.Converter;
|
||||
import zutil.parser.binary.BinaryStruct.BinaryField;
|
||||
|
||||
|
|
@ -24,7 +27,7 @@ public class BinaryFieldData implements Comparable<BinaryFieldData> {
|
|||
protected static List<BinaryFieldData> getStructFieldList(Class<? extends BinaryStruct> clazz){
|
||||
if (!cache.containsKey(clazz)) {
|
||||
ArrayList<BinaryFieldData> list = new ArrayList<>();
|
||||
for (Field field : clazz.getFields()) {
|
||||
for (Field field : clazz.getDeclaredFields()) {
|
||||
if (field.isAnnotationPresent(BinaryField.class))
|
||||
list.add(new BinaryFieldData(field));
|
||||
}
|
||||
|
|
@ -56,15 +59,17 @@ public class BinaryFieldData implements Comparable<BinaryFieldData> {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: variable length support
|
||||
protected byte[] getValue(Object obj){
|
||||
try {
|
||||
field.setAccessible(true);
|
||||
if (field.getType() == Boolean.class || field.getType() == boolean.class)
|
||||
return new byte[]{ (byte)(field.getBoolean(obj) ? 0x01 : 0x00) };
|
||||
else if (field.getType() == Integer.class || field.getType() == int.class)
|
||||
return Converter.toBytes(field.getInt(obj));
|
||||
else if (field.getType() == String.class)
|
||||
return ((String)(field.get(obj))).getBytes();
|
||||
else
|
||||
throw new UnsupportedOperationException("Unsupported BinaryStruct field class: "+ field.getClass());
|
||||
} catch (IllegalAccessException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ public class BinaryStructOutputStream {
|
|||
byte[] data = field.getValue(struct);
|
||||
|
||||
int fieldBitLength = field.getBitLength();
|
||||
for (int i=data.length-1; fieldBitLength>0; fieldBitLength-=8, --i) {
|
||||
for (int i=(int)Math.ceil(fieldBitLength/8.0)-1; fieldBitLength>0; fieldBitLength-=8, --i) {
|
||||
byte b = data[i];
|
||||
if (restBitLength == 0 && fieldBitLength >= 8)
|
||||
out.write(0xFF & b);
|
||||
|
|
|
|||
66
test/zutil/net/dns/DNSPacketTest.java
Executable file
66
test/zutil/net/dns/DNSPacketTest.java
Executable file
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Ziver Koc
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package zutil.net.dns;
|
||||
|
||||
import org.junit.Test;
|
||||
import zutil.parser.binary.BinaryStructOutputStream;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Created by Ziver
|
||||
*/
|
||||
public class DNSPacketTest {
|
||||
|
||||
@Test
|
||||
public void headerQueryTest() throws IOException {
|
||||
DNSPacketHeader header = new DNSPacketHeader();
|
||||
header.setDefaultQueryData();
|
||||
header.countQuestion = 1;
|
||||
|
||||
byte[] data = BinaryStructOutputStream.serialize(header);
|
||||
assertEquals("header length", 12, data.length);
|
||||
assertEquals("Flag byte1", 0x00, data[2]);
|
||||
assertEquals("Flag byte2", 0x00, data[3]);
|
||||
assertEquals("Question count byte1", 0x00, data[4]);
|
||||
assertEquals("Question count byte2", 0x01, data[5]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void headerResponseTest() throws IOException {
|
||||
DNSPacketHeader header = new DNSPacketHeader();
|
||||
header.setDefaultResponseData();
|
||||
header.countAnswerRecord = 1;
|
||||
|
||||
byte[] data = BinaryStructOutputStream.serialize(header);
|
||||
assertEquals("header length", 12, data.length);
|
||||
assertEquals("Flag byte1", (byte)0x84, data[2]);
|
||||
assertEquals("Flag byte2", (byte)0x00, data[3]);
|
||||
assertEquals("Answer count byte1", 0x00, data[6]);
|
||||
assertEquals("Answer count byte2", 0x01, data[7]);
|
||||
}
|
||||
}
|
||||
|
|
@ -42,7 +42,7 @@ public class BinaryStructOutputStreamTest {
|
|||
public void basicIntTest() throws IOException {
|
||||
BinaryStruct struct = new BinaryStruct() {
|
||||
@BinaryField(index=1, length=32)
|
||||
public int i1 = 1;
|
||||
int i1 = 1;
|
||||
@BinaryField(index=2, length=32)
|
||||
public int i2 = 2;
|
||||
};
|
||||
|
|
@ -51,6 +51,20 @@ public class BinaryStructOutputStreamTest {
|
|||
assertArrayEquals(new byte[]{0,0,0,1, 0,0,0,2}, data);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shortIntTest() throws IOException {
|
||||
BinaryStruct struct = new BinaryStruct() {
|
||||
@BinaryField(index=1, length=16)
|
||||
int i1 = 1;
|
||||
@BinaryField(index=2, length=16)
|
||||
int i2 = 2;
|
||||
};
|
||||
|
||||
byte[] data = BinaryStructOutputStream.serialize(struct);
|
||||
assertArrayEquals(new byte[]{0,1, 0,2}, data);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void basicBooleanTest() throws IOException {
|
||||
BinaryStruct struct = new BinaryStruct() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue