1. /*
  2. * Copyright 2001-2004 The Apache Software Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.apache.commons.net.tftp;
  17. import java.net.DatagramPacket;
  18. import java.net.InetAddress;
  19. /***
  20. * A final class derived from TFTPPacket definiing the TFTP Error
  21. * packet type.
  22. * <p>
  23. * Details regarding the TFTP protocol and the format of TFTP packets can
  24. * be found in RFC 783. But the point of these classes is to keep you
  25. * from having to worry about the internals. Additionally, only very
  26. * few people should have to care about any of the TFTPPacket classes
  27. * or derived classes. Almost all users should only be concerned with the
  28. * <a href="org.apache.commons.net.tftp.TFTPClient.html#_top_">TFTPClient</a> class
  29. * <a href="org.apache.commons.net.tftp.TFTPClient.html#receiveFile">receiveFile()</a>
  30. * and
  31. * <a href="org.apache.commons.net.tftp.TFTPClient.html#sendFile">sendFile()</a>
  32. * methods.
  33. * <p>
  34. * <p>
  35. * @author Daniel F. Savarese
  36. * @see TFTPPacket
  37. * @see TFTPPacketException
  38. * @see TFTP
  39. ***/
  40. public final class TFTPErrorPacket extends TFTPPacket
  41. {
  42. /*** The undefined error code according to RFC 783, value 0. ***/
  43. public static final int UNDEFINED = 0;
  44. /*** The file not found error code according to RFC 783, value 1. ***/
  45. public static final int FILE_NOT_FOUND = 1;
  46. /*** The access violation error code according to RFC 783, value 2. ***/
  47. public static final int ACCESS_VIOLATION = 2;
  48. /*** The disk full error code according to RFC 783, value 3. ***/
  49. public static final int OUT_OF_SPACE = 3;
  50. /***
  51. * The illegal TFTP operation error code according to RFC 783, value 4.
  52. ***/
  53. public static final int ILLEGAL_OPERATION = 4;
  54. /*** The unknown transfer id error code according to RFC 783, value 5. ***/
  55. public static final int UNKNOWN_TID = 5;
  56. /*** The file already exists error code according to RFC 783, value 6. ***/
  57. public static final int FILE_EXISTS = 6;
  58. /*** The no such user error code according to RFC 783, value 7. ***/
  59. public static final int NO_SUCH_USER = 7;
  60. /*** The error code of this packet. ***/
  61. int _error;
  62. /*** The error message of this packet. ***/
  63. String _message;
  64. /***
  65. * Creates an error packet to be sent to a host at a given port
  66. * with an error code and error message.
  67. * <p>
  68. * @param destination The host to which the packet is going to be sent.
  69. * @param port The port to which the packet is going to be sent.
  70. * @param error The error code of the packet.
  71. * @param message The error message of the packet.
  72. ***/
  73. public TFTPErrorPacket(InetAddress destination, int port,
  74. int error, String message)
  75. {
  76. super(TFTPPacket.ERROR, destination, port);
  77. _error = error;
  78. _message = message;
  79. }
  80. /***
  81. * Creates an error packet based from a received
  82. * datagram. Assumes the datagram is at least length 4, else an
  83. * ArrayIndexOutOfBoundsException may be thrown.
  84. * <p>
  85. * @param datagram The datagram containing the received error.
  86. * @throws TFTPPacketException If the datagram isn't a valid TFTP
  87. * error packet.
  88. ***/
  89. TFTPErrorPacket(DatagramPacket datagram) throws TFTPPacketException
  90. {
  91. super(TFTPPacket.ERROR, datagram.getAddress(), datagram.getPort());
  92. int index, length;
  93. byte[] data;
  94. StringBuffer buffer;
  95. data = datagram.getData();
  96. length = datagram.getLength();
  97. if (getType() != data[1])
  98. throw new TFTPPacketException("TFTP operator code does not match type.");
  99. _error = (((data[2] & 0xff) << 8) | (data[3] & 0xff));
  100. if (length < 5)
  101. throw new TFTPPacketException("Bad error packet. No message.");
  102. index = 4;
  103. buffer = new StringBuffer();
  104. while (index < length && data[index] != 0)
  105. {
  106. buffer.append((char)data[index]);
  107. ++index;
  108. }
  109. _message = buffer.toString();
  110. }
  111. /***
  112. * This is a method only available within the package for
  113. * implementing efficient datagram transport by elminating buffering.
  114. * It takes a datagram as an argument, and a byte buffer in which
  115. * to store the raw datagram data. Inside the method, the data
  116. * is set as the datagram's data and the datagram returned.
  117. * <p>
  118. * @param datagram The datagram to create.
  119. * @param data The buffer to store the packet and to use in the datagram.
  120. * @return The datagram argument.
  121. ***/
  122. DatagramPacket _newDatagram(DatagramPacket datagram, byte[] data)
  123. {
  124. int length;
  125. length = _message.length();
  126. data[0] = 0;
  127. data[1] = (byte)_type;
  128. data[2] = (byte)((_error & 0xffff) >> 8);
  129. data[3] = (byte)(_error & 0xff);
  130. System.arraycopy(_message.getBytes(), 0, data, 4, length);
  131. data[length + 4] = 0;
  132. datagram.setAddress(_address);
  133. datagram.setPort(_port);
  134. datagram.setData(data);
  135. datagram.setLength(length + 4);
  136. return datagram;
  137. }
  138. /***
  139. * Creates a UDP datagram containing all the TFTP
  140. * error packet data in the proper format.
  141. * This is a method exposed to the programmer in case he
  142. * wants to implement his own TFTP client instead of using
  143. * the <a href="org.apache.commons.net.tftp.TFTPClient.html#_top_">TFTPClient</a>
  144. * class.
  145. * Under normal circumstances, you should not have a need to call this
  146. * method.
  147. * <p>
  148. * @return A UDP datagram containing the TFTP error packet.
  149. ***/
  150. public DatagramPacket newDatagram()
  151. {
  152. byte[] data;
  153. int length;
  154. length = _message.length();
  155. data = new byte[length + 5];
  156. data[0] = 0;
  157. data[1] = (byte)_type;
  158. data[2] = (byte)((_error & 0xffff) >> 8);
  159. data[3] = (byte)(_error & 0xff);
  160. System.arraycopy(_message.getBytes(), 0, data, 4, length);
  161. data[length + 4] = 0;
  162. return new DatagramPacket(data, data.length, _address, _port);
  163. }
  164. /***
  165. * Returns the error code of the packet.
  166. * <p>
  167. * @return The error code of the packet.
  168. ***/
  169. public int getError()
  170. {
  171. return _error;
  172. }
  173. /***
  174. * Returns the error message of the packet.
  175. * <p>
  176. * @return The error message of the packet.
  177. ***/
  178. public String getMessage()
  179. {
  180. return _message;
  181. }
  182. }