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