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 Data
  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 TFTPDataPacket extends TFTPPacket
  41. {
  42. /*** The maximum number of bytes in a TFTP data packet (512) ***/
  43. public static final int MAX_DATA_LENGTH = 512;
  44. /*** The minimum number of bytes in a TFTP data packet (0) ***/
  45. public static final int MIN_DATA_LENGTH = 0;
  46. /*** The block number of the packet. ***/
  47. int _blockNumber;
  48. /*** The length of the data. ***/
  49. int _length;
  50. /*** The offset into the _data array at which the data begins. ***/
  51. int _offset;
  52. /*** The data stored in the packet. ***/
  53. byte[] _data;
  54. /***
  55. * Creates a data packet to be sent to a host at a given port
  56. * with a given block number. The actual data to be sent is passed as
  57. * an array, an offset, and a length. The offset is the offset into
  58. * the byte array where the data starts. The length is the length of
  59. * the data. If the length is greater than MAX_DATA_LENGTH, it is
  60. * truncated.
  61. * <p>
  62. * @param destination The host to which the packet is going to be sent.
  63. * @param port The port to which the packet is going to be sent.
  64. * @param blockNumber The block number of the data.
  65. * @param data The byte array containing the data.
  66. * @param offset The offset into the array where the data starts.
  67. * @param length The length of the data.
  68. ***/
  69. public TFTPDataPacket(InetAddress destination, int port, int blockNumber,
  70. byte[] data, int offset, int length)
  71. {
  72. super(TFTPPacket.DATA, destination, port);
  73. _blockNumber = blockNumber;
  74. _data = data;
  75. _offset = offset;
  76. if (length > MAX_DATA_LENGTH)
  77. _length = MAX_DATA_LENGTH;
  78. else
  79. _length = length;
  80. }
  81. public TFTPDataPacket(InetAddress destination, int port, int blockNumber,
  82. byte[] data)
  83. {
  84. this(destination, port, blockNumber, data, 0, data.length);
  85. }
  86. /***
  87. * Creates a data packet based from a received
  88. * datagram. Assumes the datagram is at least length 4, else an
  89. * ArrayIndexOutOfBoundsException may be thrown.
  90. * <p>
  91. * @param datagram The datagram containing the received data.
  92. * @throws TFTPPacketException If the datagram isn't a valid TFTP
  93. * data packet.
  94. ***/
  95. TFTPDataPacket(DatagramPacket datagram) throws TFTPPacketException
  96. {
  97. super(TFTPPacket.DATA, datagram.getAddress(), datagram.getPort());
  98. _data = datagram.getData();
  99. _offset = 4;
  100. if (getType() != _data[1])
  101. throw new TFTPPacketException("TFTP operator code does not match type.");
  102. _blockNumber = (((_data[2] & 0xff) << 8) | (_data[3] & 0xff));
  103. _length = datagram.getLength() - 4;
  104. if (_length > MAX_DATA_LENGTH)
  105. _length = MAX_DATA_LENGTH;
  106. }
  107. /***
  108. * This is a method only available within the package for
  109. * implementing efficient datagram transport by elminating buffering.
  110. * It takes a datagram as an argument, and a byte buffer in which
  111. * to store the raw datagram data. Inside the method, the data
  112. * is set as the datagram's data and the datagram returned.
  113. * <p>
  114. * @param datagram The datagram to create.
  115. * @param data The buffer to store the packet and to use in the datagram.
  116. * @return The datagram argument.
  117. ***/
  118. DatagramPacket _newDatagram(DatagramPacket datagram, byte[] data)
  119. {
  120. data[0] = 0;
  121. data[1] = (byte)_type;
  122. data[2] = (byte)((_blockNumber & 0xffff) >> 8);
  123. data[3] = (byte)(_blockNumber & 0xff);
  124. // Doublecheck we're not the same
  125. if (data != _data)
  126. System.arraycopy(_data, _offset, data, 4, _length);
  127. datagram.setAddress(_address);
  128. datagram.setPort(_port);
  129. datagram.setData(data);
  130. datagram.setLength(_length + 4);
  131. return datagram;
  132. }
  133. /***
  134. * Creates a UDP datagram containing all the TFTP
  135. * data packet data in the proper format.
  136. * This is a method exposed to the programmer in case he
  137. * wants to implement his own TFTP client instead of using
  138. * the <a href="org.apache.commons.net.tftp.TFTPClient.html#_top_">TFTPClient</a>
  139. * class.
  140. * Under normal circumstances, you should not have a need to call this
  141. * method.
  142. * <p>
  143. * @return A UDP datagram containing the TFTP data packet.
  144. ***/
  145. public DatagramPacket newDatagram()
  146. {
  147. byte[] data;
  148. data = new byte[_length + 4];
  149. data[0] = 0;
  150. data[1] = (byte)_type;
  151. data[2] = (byte)((_blockNumber & 0xffff) >> 8);
  152. data[3] = (byte)(_blockNumber & 0xff);
  153. System.arraycopy(_data, _offset, data, 4, _length);
  154. return new DatagramPacket(data, _length + 4, _address, _port);
  155. }
  156. /***
  157. * Returns the block number of the data packet.
  158. * <p>
  159. * @return The block number of the data packet.
  160. ***/
  161. public int getBlockNumber()
  162. {
  163. return _blockNumber;
  164. }
  165. /*** Sets the block number of the data packet. ***/
  166. public void setBlockNumber(int blockNumber)
  167. {
  168. _blockNumber = blockNumber;
  169. }
  170. /***
  171. * Sets the data for the data packet.
  172. * <p>
  173. * @param data The byte array containing the data.
  174. * @param offset The offset into the array where the data starts.
  175. * @param length The length of the data.
  176. ***/
  177. public void setData(byte[] data, int offset, int length)
  178. {
  179. _data = data;
  180. _offset = offset;
  181. _length = length;
  182. if (length > MAX_DATA_LENGTH)
  183. _length = MAX_DATA_LENGTH;
  184. else
  185. _length = length;
  186. }
  187. /***
  188. * Returns the length of the data part of the data packet.
  189. * <p>
  190. * @return The length of the data part of the data packet.
  191. ***/
  192. public int getDataLength()
  193. {
  194. return _length;
  195. }
  196. /***
  197. * Returns the offset into the byte array where the packet data actually
  198. * starts.
  199. * <p>
  200. * @return The offset into the byte array where the packet data actually
  201. * starts.
  202. ***/
  203. public int getDataOffset()
  204. {
  205. return _offset;
  206. }
  207. /***
  208. * Returns the byte array containing the packet data.
  209. * <p>
  210. * @return The byte array containing the packet data.
  211. ***/
  212. public byte[] getData()
  213. {
  214. return _data;
  215. }
  216. }