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 * TFTPPacket is an abstract class encapsulating the functionality common 25 * to the 5 types of TFTP packets. It also provides a static factory 26 * method that will create the correct TFTP packet instance from a 27 * datagram. This relieves the programmer from having to figure out what 28 * kind of TFTP packet is contained in a datagram and create it himself. 29 * <p> 30 * Details regarding the TFTP protocol and the format of TFTP packets can 31 * be found in RFC 783. But the point of these classes is to keep you 32 * from having to worry about the internals. Additionally, only very 33 * few people should have to care about any of the TFTPPacket classes 34 * or derived classes. Almost all users should only be concerned with the 35 * {@link org.apache.commons.net.tftp.TFTPClient} class 36 * {@link org.apache.commons.net.tftp.TFTPClient#receiveFile receiveFile()} 37 * and 38 * {@link org.apache.commons.net.tftp.TFTPClient#sendFile sendFile()} 39 * methods. 40 * 41 * 42 * @see TFTPPacketException 43 * @see TFTP 44 */ 45 46 public abstract class TFTPPacket 47 { 48 /** 49 * The minimum size of a packet. This is 4 bytes. It is enough 50 * to store the opcode and blocknumber or other required data 51 * depending on the packet type. 52 */ 53 static final int MIN_PACKET_SIZE = 4; 54 55 /** 56 * This is the actual TFTP spec 57 * identifier and is equal to 1. 58 * Identifier returned by {@link #getType getType()} 59 * indicating a read request packet. 60 */ 61 public static final int READ_REQUEST = 1; 62 63 /** 64 * This is the actual TFTP spec 65 * identifier and is equal to 2. 66 * Identifier returned by {@link #getType getType()} 67 * indicating a write request packet. 68 */ 69 public static final int WRITE_REQUEST = 2; 70 71 /** 72 * This is the actual TFTP spec 73 * identifier and is equal to 3. 74 * Identifier returned by {@link #getType getType()} 75 * indicating a data packet. 76 */ 77 public static final int DATA = 3; 78 79 /** 80 * This is the actual TFTP spec 81 * identifier and is equal to 4. 82 * Identifier returned by {@link #getType getType()} 83 * indicating an acknowledgement packet. 84 */ 85 public static final int ACKNOWLEDGEMENT = 4; 86 87 /** 88 * This is the actual TFTP spec 89 * identifier and is equal to 5. 90 * Identifier returned by {@link #getType getType()} 91 * indicating an error packet. 92 */ 93 public static final int ERROR = 5; 94 95 /** 96 * The TFTP data packet maximum segment size in bytes. This is 512 97 * and is useful for those familiar with the TFTP protocol who want 98 * to use the {@link org.apache.commons.net.tftp.TFTP} 99 * class methods to implement their own TFTP servers or clients. 100 */ 101 public static final int SEGMENT_SIZE = 512; 102 103 /** The type of packet. */ 104 int type; 105 106 /** The port the packet came from or is going to. */ 107 int port; 108 109 /** The host the packet is going to be sent or where it came from. */ 110 InetAddress address; 111 112 /** 113 * When you receive a datagram that you expect to be a TFTP packet, you use 114 * this factory method to create the proper TFTPPacket object 115 * encapsulating the data contained in that datagram. This method is the 116 * only way you can instantiate a TFTPPacket derived class from a 117 * datagram. 118 * 119 * @param datagram The datagram containing a TFTP packet. 120 * @return The TFTPPacket object corresponding to the datagram. 121 * @throws TFTPPacketException If the datagram does not contain a valid 122 * TFTP packet. 123 */ 124 public static final TFTPPacket newTFTPPacket(final DatagramPacket datagram) 125 throws TFTPPacketException 126 { 127 final byte[] data; 128 TFTPPacket packet = null; 129 130 if (datagram.getLength() < MIN_PACKET_SIZE) { 131 throw new TFTPPacketException( 132 "Bad packet. Datagram data length is too short."); 133 } 134 135 data = datagram.getData(); 136 137 switch (data[1]) 138 { 139 case READ_REQUEST: 140 packet = new TFTPReadRequestPacket(datagram); 141 break; 142 case WRITE_REQUEST: 143 packet = new TFTPWriteRequestPacket(datagram); 144 break; 145 case DATA: 146 packet = new TFTPDataPacket(datagram); 147 break; 148 case ACKNOWLEDGEMENT: 149 packet = new TFTPAckPacket(datagram); 150 break; 151 case ERROR: 152 packet = new TFTPErrorPacket(datagram); 153 break; 154 default: 155 throw new TFTPPacketException( 156 "Bad packet. Invalid TFTP operator code."); 157 } 158 159 return packet; 160 } 161 162 /** 163 * This constructor is not visible outside of the package. It is used 164 * by subclasses within the package to initialize base data. 165 * 166 * @param type The type of the packet. 167 * @param address The host the packet came from or is going to be sent. 168 * @param port The port the packet came from or is going to be sent. 169 **/ 170 TFTPPacket(final int type, final InetAddress address, final int port) 171 { 172 this.type = type; 173 this.address = address; 174 this.port = port; 175 } 176 177 /** 178 * This is an abstract method only available within the package for 179 * implementing efficient datagram transport by elminating buffering. 180 * It takes a datagram as an argument, and a byte buffer in which 181 * to store the raw datagram data. Inside the method, the data 182 * should be set as the datagram's data and the datagram returned. 183 * 184 * @param datagram The datagram to create. 185 * @param data The buffer to store the packet and to use in the datagram. 186 * @return The datagram argument. 187 */ 188 abstract DatagramPacket newDatagram(DatagramPacket datagram, byte[] data); 189 190 /** 191 * Creates a UDP datagram containing all the TFTP packet 192 * data in the proper format. 193 * This is an abstract method, exposed to the programmer in case he 194 * wants to implement his own TFTP client instead of using 195 * the {@link org.apache.commons.net.tftp.TFTPClient} 196 * class. 197 * Under normal circumstances, you should not have a need to call this 198 * method. 199 * 200 * @return A UDP datagram containing the TFTP packet. 201 */ 202 public abstract DatagramPacket newDatagram(); 203 204 /** 205 * Returns the type of the packet. 206 * 207 * @return The type of the packet. 208 */ 209 public final int getType() 210 { 211 return type; 212 } 213 214 /** 215 * Returns the address of the host where the packet is going to be sent 216 * or where it came from. 217 * 218 * @return The type of the packet. 219 */ 220 public final InetAddress getAddress() 221 { 222 return address; 223 } 224 225 /** 226 * Returns the port where the packet is going to be sent 227 * or where it came from. 228 * 229 * @return The port where the packet came from or where it is going. 230 */ 231 public final int getPort() 232 { 233 return port; 234 } 235 236 /** 237 * Sets the port where the packet is going to be sent. 238 * @param port the port to set 239 */ 240 public final void setPort(final int port) 241 { 242 this.port = port; 243 } 244 245 /** Sets the host address where the packet is going to be sent. 246 * @param address the address to set 247 */ 248 public final void setAddress(final InetAddress address) 249 { 250 this.address = address; 251 } 252 253 /** 254 * For debugging 255 * @since 3.6 256 */ 257 @Override 258 public String toString() { 259 return address + " " + port + " " + type; 260 } 261 }