| /** |
| * |
| */ |
| package javax.jmdns.impl; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.LinkedList; |
| import java.util.List; |
| |
| import javax.jmdns.impl.constants.DNSConstants; |
| |
| /** |
| * DNSMessage define a DNS message either incoming or outgoing. |
| * |
| * @author Werner Randelshofer, Rick Blair, Pierre Frisch |
| */ |
| public abstract class DNSMessage { |
| |
| /** |
| * |
| */ |
| public static final boolean MULTICAST = true; |
| |
| /** |
| * |
| */ |
| public static final boolean UNICAST = false; |
| |
| // protected DatagramPacket _packet; |
| // protected int _off; |
| // protected int _len; |
| // protected byte[] _data; |
| |
| private int _id; |
| |
| boolean _multicast; |
| |
| private int _flags; |
| |
| protected final List<DNSQuestion> _questions; |
| |
| protected final List<DNSRecord> _answers; |
| |
| protected final List<DNSRecord> _authoritativeAnswers; |
| |
| protected final List<DNSRecord> _additionals; |
| |
| /** |
| * @param flags |
| * @param id |
| * @param multicast |
| */ |
| protected DNSMessage(int flags, int id, boolean multicast) { |
| super(); |
| _flags = flags; |
| _id = id; |
| _multicast = multicast; |
| _questions = Collections.synchronizedList(new LinkedList<DNSQuestion>()); |
| _answers = Collections.synchronizedList(new LinkedList<DNSRecord>()); |
| _authoritativeAnswers = Collections.synchronizedList(new LinkedList<DNSRecord>()); |
| _additionals = Collections.synchronizedList(new LinkedList<DNSRecord>()); |
| } |
| |
| // public DatagramPacket getPacket() { |
| // return _packet; |
| // } |
| // |
| // public int getOffset() { |
| // return _off; |
| // } |
| // |
| // public int getLength() { |
| // return _len; |
| // } |
| // |
| // public byte[] getData() { |
| // if ( _data == null ) _data = new byte[DNSConstants.MAX_MSG_TYPICAL]; |
| // return _data; |
| // } |
| |
| /** |
| * @return message id |
| */ |
| public int getId() { |
| return (_multicast ? 0 : _id); |
| } |
| |
| /** |
| * @param id |
| * the id to set |
| */ |
| public void setId(int id) { |
| this._id = id; |
| } |
| |
| /** |
| * @return message flags |
| */ |
| public int getFlags() { |
| return _flags; |
| } |
| |
| /** |
| * @param flags |
| * the flags to set |
| */ |
| public void setFlags(int flags) { |
| this._flags = flags; |
| } |
| |
| /** |
| * @return true if multicast |
| */ |
| public boolean isMulticast() { |
| return _multicast; |
| } |
| |
| /** |
| * @return list of questions |
| */ |
| public Collection<? extends DNSQuestion> getQuestions() { |
| return _questions; |
| } |
| |
| /** |
| * @return number of questions in the message |
| */ |
| public int getNumberOfQuestions() { |
| return this.getQuestions().size(); |
| } |
| |
| public Collection<? extends DNSRecord> getAllAnswers() { |
| List<DNSRecord> aList = new ArrayList<DNSRecord>(_answers.size() + _authoritativeAnswers.size() + _additionals.size()); |
| aList.addAll(_answers); |
| aList.addAll(_authoritativeAnswers); |
| aList.addAll(_additionals); |
| return aList; |
| } |
| |
| /** |
| * @return list of answers |
| */ |
| public Collection<? extends DNSRecord> getAnswers() { |
| return _answers; |
| } |
| |
| /** |
| * @return number of answers in the message |
| */ |
| public int getNumberOfAnswers() { |
| return this.getAnswers().size(); |
| } |
| |
| /** |
| * @return list of authorities |
| */ |
| public Collection<? extends DNSRecord> getAuthorities() { |
| return _authoritativeAnswers; |
| } |
| |
| /** |
| * @return number of authorities in the message |
| */ |
| public int getNumberOfAuthorities() { |
| return this.getAuthorities().size(); |
| } |
| |
| /** |
| * @return list of additional answers |
| */ |
| public Collection<? extends DNSRecord> getAdditionals() { |
| return _additionals; |
| } |
| |
| /** |
| * @return number of additional in the message |
| */ |
| public int getNumberOfAdditionals() { |
| return this.getAdditionals().size(); |
| } |
| |
| /** |
| * Check if the message is truncated. |
| * |
| * @return true if the message was truncated |
| */ |
| public boolean isTruncated() { |
| return (_flags & DNSConstants.FLAGS_TC) != 0; |
| } |
| |
| /** |
| * Check if the message is a query. |
| * |
| * @return true is the message is a query |
| */ |
| public boolean isQuery() { |
| return (_flags & DNSConstants.FLAGS_QR_MASK) == DNSConstants.FLAGS_QR_QUERY; |
| } |
| |
| /** |
| * Check if the message is a response. |
| * |
| * @return true is the message is a response |
| */ |
| public boolean isResponse() { |
| return (_flags & DNSConstants.FLAGS_QR_MASK) == DNSConstants.FLAGS_QR_RESPONSE; |
| } |
| |
| /** |
| * Check if the message is empty |
| * |
| * @return true is the message is empty |
| */ |
| public boolean isEmpty() { |
| return (this.getNumberOfQuestions() + this.getNumberOfAnswers() + this.getNumberOfAuthorities() + this.getNumberOfAdditionals()) == 0; |
| } |
| |
| /** |
| * Debugging. |
| */ |
| String print() { |
| StringBuffer buf = new StringBuffer(200); |
| buf.append(this.toString()); |
| buf.append("\n"); |
| for (DNSQuestion question : _questions) { |
| buf.append("\tquestion: "); |
| buf.append(question); |
| buf.append("\n"); |
| } |
| for (DNSRecord answer : _answers) { |
| buf.append("\tanswer: "); |
| buf.append(answer); |
| buf.append("\n"); |
| } |
| for (DNSRecord answer : _authoritativeAnswers) { |
| buf.append("\tauthoritative: "); |
| buf.append(answer); |
| buf.append("\n"); |
| } |
| for (DNSRecord answer : _additionals) { |
| buf.append("\tadditional: "); |
| buf.append(answer); |
| buf.append("\n"); |
| } |
| return buf.toString(); |
| } |
| |
| /** |
| * Debugging. |
| * |
| * @param data |
| * @return data dump |
| */ |
| protected String print(byte[] data) { |
| StringBuilder buf = new StringBuilder(4000); |
| for (int off = 0, len = data.length; off < len; off += 32) { |
| int n = Math.min(32, len - off); |
| if (off < 0x10) { |
| buf.append(' '); |
| } |
| if (off < 0x100) { |
| buf.append(' '); |
| } |
| if (off < 0x1000) { |
| buf.append(' '); |
| } |
| buf.append(Integer.toHexString(off)); |
| buf.append(':'); |
| int index = 0; |
| for (index = 0; index < n; index++) { |
| if ((index % 8) == 0) { |
| buf.append(' '); |
| } |
| buf.append(Integer.toHexString((data[off + index] & 0xF0) >> 4)); |
| buf.append(Integer.toHexString((data[off + index] & 0x0F) >> 0)); |
| } |
| // for incomplete lines |
| if (index < 32) { |
| for (int i = index; i < 32; i++) { |
| if ((i % 8) == 0) { |
| buf.append(' '); |
| } |
| buf.append(" "); |
| } |
| } |
| buf.append(" "); |
| for (index = 0; index < n; index++) { |
| if ((index % 8) == 0) { |
| buf.append(' '); |
| } |
| int ch = data[off + index] & 0xFF; |
| buf.append(((ch > ' ') && (ch < 127)) ? (char) ch : '.'); |
| } |
| buf.append("\n"); |
| |
| // limit message size |
| if (off + 32 >= 2048) { |
| buf.append("....\n"); |
| break; |
| } |
| } |
| return buf.toString(); |
| } |
| |
| } |