001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package org.apache.commons.net.tftp; 019 020import java.net.DatagramPacket; 021import java.net.InetAddress; 022 023/*** 024 * TFTPPacket is an abstract class encapsulating the functionality common 025 * to the 5 types of TFTP packets. It also provides a static factory 026 * method that will create the correct TFTP packet instance from a 027 * datagram. This relieves the programmer from having to figure out what 028 * kind of TFTP packet is contained in a datagram and create it himself. 029 * <p> 030 * Details regarding the TFTP protocol and the format of TFTP packets can 031 * be found in RFC 783. But the point of these classes is to keep you 032 * from having to worry about the internals. Additionally, only very 033 * few people should have to care about any of the TFTPPacket classes 034 * or derived classes. Almost all users should only be concerned with the 035 * {@link org.apache.commons.net.tftp.TFTPClient} class 036 * {@link org.apache.commons.net.tftp.TFTPClient#receiveFile receiveFile()} 037 * and 038 * {@link org.apache.commons.net.tftp.TFTPClient#sendFile sendFile()} 039 * methods. 040 * 041 * 042 * @see TFTPPacketException 043 * @see TFTP 044 ***/ 045 046public abstract class TFTPPacket 047{ 048 /*** 049 * The minimum size of a packet. This is 4 bytes. It is enough 050 * to store the opcode and blocknumber or other required data 051 * depending on the packet type. 052 ***/ 053 static final int MIN_PACKET_SIZE = 4; 054 055 /*** 056 * This is the actual TFTP spec 057 * identifier and is equal to 1. 058 * Identifier returned by {@link #getType getType()} 059 * indicating a read request packet. 060 ***/ 061 public static final int READ_REQUEST = 1; 062 063 /*** 064 * This is the actual TFTP spec 065 * identifier and is equal to 2. 066 * Identifier returned by {@link #getType getType()} 067 * indicating a write request packet. 068 ***/ 069 public static final int WRITE_REQUEST = 2; 070 071 /*** 072 * This is the actual TFTP spec 073 * identifier and is equal to 3. 074 * Identifier returned by {@link #getType getType()} 075 * indicating a data packet. 076 ***/ 077 public static final int DATA = 3; 078 079 /*** 080 * This is the actual TFTP spec 081 * identifier and is equal to 4. 082 * Identifier returned by {@link #getType getType()} 083 * indicating an acknowledgement packet. 084 ***/ 085 public static final int ACKNOWLEDGEMENT = 4; 086 087 /*** 088 * This is the actual TFTP spec 089 * identifier and is equal to 5. 090 * Identifier returned by {@link #getType getType()} 091 * indicating an error packet. 092 ***/ 093 public static final int ERROR = 5; 094 095 /*** 096 * The TFTP data packet maximum segment size in bytes. This is 512 097 * and is useful for those familiar with the TFTP protocol who want 098 * to use the {@link org.apache.commons.net.tftp.TFTP} 099 * 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(DatagramPacket datagram) 125 throws TFTPPacketException 126 { 127 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(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 * 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(int port) 241 { 242 _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(InetAddress address) 249 { 250 _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}