View Javadoc

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