001: /*
002: * Copyright 2001-2005 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.apache.commons.net.tftp;
017:
018: import java.net.DatagramPacket;
019: import java.net.InetAddress;
020:
021: /***
022: * A final class derived from TFTPPacket definiing the TFTP Error
023: * packet type.
024: * <p>
025: * Details regarding the TFTP protocol and the format of TFTP packets can
026: * be found in RFC 783. But the point of these classes is to keep you
027: * from having to worry about the internals. Additionally, only very
028: * few people should have to care about any of the TFTPPacket classes
029: * or derived classes. Almost all users should only be concerned with the
030: * {@link org.apache.commons.net.tftp.TFTPClient} class
031: * {@link org.apache.commons.net.tftp.TFTPClient#receiveFile receiveFile()}
032: * and
033: * {@link org.apache.commons.net.tftp.TFTPClient#sendFile sendFile()}
034: * methods.
035: * <p>
036: * <p>
037: * @author Daniel F. Savarese
038: * @see TFTPPacket
039: * @see TFTPPacketException
040: * @see TFTP
041: ***/
042:
043: public final class TFTPErrorPacket extends TFTPPacket {
044: /*** The undefined error code according to RFC 783, value 0. ***/
045: public static final int UNDEFINED = 0;
046:
047: /*** The file not found error code according to RFC 783, value 1. ***/
048: public static final int FILE_NOT_FOUND = 1;
049:
050: /*** The access violation error code according to RFC 783, value 2. ***/
051: public static final int ACCESS_VIOLATION = 2;
052:
053: /*** The disk full error code according to RFC 783, value 3. ***/
054: public static final int OUT_OF_SPACE = 3;
055:
056: /***
057: * The illegal TFTP operation error code according to RFC 783, value 4.
058: ***/
059: public static final int ILLEGAL_OPERATION = 4;
060:
061: /*** The unknown transfer id error code according to RFC 783, value 5. ***/
062: public static final int UNKNOWN_TID = 5;
063:
064: /*** The file already exists error code according to RFC 783, value 6. ***/
065: public static final int FILE_EXISTS = 6;
066:
067: /*** The no such user error code according to RFC 783, value 7. ***/
068: public static final int NO_SUCH_USER = 7;
069:
070: /*** The error code of this packet. ***/
071: int _error;
072:
073: /*** The error message of this packet. ***/
074: String _message;
075:
076: /***
077: * Creates an error packet to be sent to a host at a given port
078: * with an error code and error message.
079: * <p>
080: * @param destination The host to which the packet is going to be sent.
081: * @param port The port to which the packet is going to be sent.
082: * @param error The error code of the packet.
083: * @param message The error message of the packet.
084: ***/
085: public TFTPErrorPacket(InetAddress destination, int port,
086: int error, String message) {
087: super (TFTPPacket.ERROR, destination, port);
088:
089: _error = error;
090: _message = message;
091: }
092:
093: /***
094: * Creates an error packet based from a received
095: * datagram. Assumes the datagram is at least length 4, else an
096: * ArrayIndexOutOfBoundsException may be thrown.
097: * <p>
098: * @param datagram The datagram containing the received error.
099: * @throws TFTPPacketException If the datagram isn't a valid TFTP
100: * error packet.
101: ***/
102: TFTPErrorPacket(DatagramPacket datagram) throws TFTPPacketException {
103: super (TFTPPacket.ERROR, datagram.getAddress(), datagram
104: .getPort());
105: int index, length;
106: byte[] data;
107: StringBuffer buffer;
108:
109: data = datagram.getData();
110: length = datagram.getLength();
111:
112: if (getType() != data[1])
113: throw new TFTPPacketException(
114: "TFTP operator code does not match type.");
115:
116: _error = (((data[2] & 0xff) << 8) | (data[3] & 0xff));
117:
118: if (length < 5)
119: throw new TFTPPacketException(
120: "Bad error packet. No message.");
121:
122: index = 4;
123: buffer = new StringBuffer();
124:
125: while (index < length && data[index] != 0) {
126: buffer.append((char) data[index]);
127: ++index;
128: }
129:
130: _message = buffer.toString();
131: }
132:
133: /***
134: * This is a method only available within the package for
135: * implementing efficient datagram transport by elminating buffering.
136: * It takes a datagram as an argument, and a byte buffer in which
137: * to store the raw datagram data. Inside the method, the data
138: * is set as the datagram's data and the datagram returned.
139: * <p>
140: * @param datagram The datagram to create.
141: * @param data The buffer to store the packet and to use in the datagram.
142: * @return The datagram argument.
143: ***/
144: DatagramPacket _newDatagram(DatagramPacket datagram, byte[] data) {
145: int length;
146:
147: length = _message.length();
148:
149: data[0] = 0;
150: data[1] = (byte) _type;
151: data[2] = (byte) ((_error & 0xffff) >> 8);
152: data[3] = (byte) (_error & 0xff);
153:
154: System.arraycopy(_message.getBytes(), 0, data, 4, length);
155:
156: data[length + 4] = 0;
157:
158: datagram.setAddress(_address);
159: datagram.setPort(_port);
160: datagram.setData(data);
161: datagram.setLength(length + 4);
162:
163: return datagram;
164: }
165:
166: /***
167: * Creates a UDP datagram containing all the TFTP
168: * error packet data in the proper format.
169: * This is a method exposed to the programmer in case he
170: * wants to implement his own TFTP client instead of using
171: * the {@link org.apache.commons.net.tftp.TFTPClient}
172: * class.
173: * Under normal circumstances, you should not have a need to call this
174: * method.
175: * <p>
176: * @return A UDP datagram containing the TFTP error packet.
177: ***/
178: public DatagramPacket newDatagram() {
179: byte[] data;
180: int length;
181:
182: length = _message.length();
183:
184: data = new byte[length + 5];
185: data[0] = 0;
186: data[1] = (byte) _type;
187: data[2] = (byte) ((_error & 0xffff) >> 8);
188: data[3] = (byte) (_error & 0xff);
189:
190: System.arraycopy(_message.getBytes(), 0, data, 4, length);
191:
192: data[length + 4] = 0;
193:
194: return new DatagramPacket(data, data.length, _address, _port);
195: }
196:
197: /***
198: * Returns the error code of the packet.
199: * <p>
200: * @return The error code of the packet.
201: ***/
202: public int getError() {
203: return _error;
204: }
205:
206: /***
207: * Returns the error message of the packet.
208: * <p>
209: * @return The error message of the packet.
210: ***/
211: public String getMessage() {
212: return _message;
213: }
214: }
|