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 * <p> 41 * <p> 42 * @author Daniel F. Savarese 43 * @see TFTPPacketException 44 * @see TFTP 45 ***/ 46 47 public abstract class TFTPPacket 48 { 49 /*** 50 * The minimum size of a packet. This is 4 bytes. It is enough 51 * to store the opcode and blocknumber or other required data 52 * depending on the packet type. 53 ***/ 54 static final int MIN_PACKET_SIZE = 4; 55 56 /*** 57 * This is the actual TFTP spec 58 * identifier and is equal to 1. 59 * Identifier returned by {@link #getType getType()} 60 * indicating a read request packet. 61 ***/ 62 public static final int READ_REQUEST = 1; 63 64 /*** 65 * This is the actual TFTP spec 66 * identifier and is equal to 2. 67 * Identifier returned by {@link #getType getType()} 68 * indicating a write request packet. 69 ***/ 70 public static final int WRITE_REQUEST = 2; 71 72 /*** 73 * This is the actual TFTP spec 74 * identifier and is equal to 3. 75 * Identifier returned by {@link #getType getType()} 76 * indicating a data packet. 77 ***/ 78 public static final int DATA = 3; 79 80 /*** 81 * This is the actual TFTP spec 82 * identifier and is equal to 4. 83 * Identifier returned by {@link #getType getType()} 84 * indicating an acknowledgement packet. 85 ***/ 86 public static final int ACKNOWLEDGEMENT = 4; 87 88 /*** 89 * This is the actual TFTP spec 90 * identifier and is equal to 5. 91 * Identifier returned by {@link #getType getType()} 92 * indicating an error packet. 93 ***/ 94 public static final int ERROR = 5; 95 96 /*** 97 * The TFTP data packet maximum segment size in bytes. This is 512 98 * and is useful for those familiar with the TFTP protocol who want 99 * to use the {@link org.apache.commons.net.tftp.TFTP} 100 * class methods to implement their own TFTP servers or clients. 101 ***/ 102 public static final int SEGMENT_SIZE = 512; 103 104 /*** The type of packet. ***/ 105 int _type; 106 107 /*** The port the packet came from or is going to. ***/ 108 int _port; 109 110 /*** The host the packet is going to be sent or where it came from. ***/ 111 InetAddress _address; 112 113 /*** 114 * When you receive a datagram that you expect to be a TFTP packet, you use 115 * this factory method to create the proper TFTPPacket object 116 * encapsulating the data contained in that datagram. This method is the 117 * only way you can instantiate a TFTPPacket derived class from a 118 * datagram. 119 * <p> 120 * @param datagram The datagram containing a TFTP packet. 121 * @return The TFTPPacket object corresponding to the datagram. 122 * @exception TFTPPacketException If the datagram does not contain a valid 123 * TFTP packet. 124 ***/ 125 public final static TFTPPacket newTFTPPacket(DatagramPacket datagram) 126 throws TFTPPacketException 127 { 128 byte[] data; 129 TFTPPacket packet = null; 130 131 if (datagram.getLength() < MIN_PACKET_SIZE) 132 throw new TFTPPacketException( 133 "Bad packet. Datagram data length is too short."); 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 * <p> 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(int type, InetAddress address, int port) 171 { 172 _type = type; 173 _address = address; 174 _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 * <p> 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 * <p> 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 * <p> 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 * <p> 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 * <p> 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 /*** Sets the port where the packet is going to be sent. ***/ 237 public final void setPort(int port) 238 { 239 _port = port; 240 } 241 242 /*** Sets the host address where the packet is going to be sent. ***/ 243 public final void setAddress(InetAddress address) 244 { 245 _address = address; 246 } 247 }