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 * TFTPPacket is an abstract class encapsulating the functionality common 023 * to the 5 types of TFTP packets. It also provides a static factory 024 * method that will create the correct TFTP packet instance from a 025 * datagram. This relieves the programmer from having to figure out what 026 * kind of TFTP packet is contained in a datagram and create it himself. 027 * <p> 028 * Details regarding the TFTP protocol and the format of TFTP packets can 029 * be found in RFC 783. But the point of these classes is to keep you 030 * from having to worry about the internals. Additionally, only very 031 * few people should have to care about any of the TFTPPacket classes 032 * or derived classes. Almost all users should only be concerned with the 033 * {@link org.apache.commons.net.tftp.TFTPClient} class 034 * {@link org.apache.commons.net.tftp.TFTPClient#receiveFile receiveFile()} 035 * and 036 * {@link org.apache.commons.net.tftp.TFTPClient#sendFile sendFile()} 037 * methods. 038 * <p> 039 * <p> 040 * @author Daniel F. Savarese 041 * @see TFTPPacketException 042 * @see TFTP 043 ***/ 044 045 public abstract class TFTPPacket 046 { 047 /*** 048 * The minimum size of a packet. This is 4 bytes. It is enough 049 * to store the opcode and blocknumber or other required data 050 * depending on the packet type. 051 ***/ 052 static final int MIN_PACKET_SIZE = 4; 053 054 /*** 055 * This is the actual TFTP spec 056 * identifier and is equal to 1. 057 * Identifier returned by {@link #getType getType()} 058 * indicating a read request packet. 059 ***/ 060 public static final int READ_REQUEST = 1; 061 062 /*** 063 * This is the actual TFTP spec 064 * identifier and is equal to 2. 065 * Identifier returned by {@link #getType getType()} 066 * indicating a write request packet. 067 ***/ 068 public static final int WRITE_REQUEST = 2; 069 070 /*** 071 * This is the actual TFTP spec 072 * identifier and is equal to 3. 073 * Identifier returned by {@link #getType getType()} 074 * indicating a data packet. 075 ***/ 076 public static final int DATA = 3; 077 078 /*** 079 * This is the actual TFTP spec 080 * identifier and is equal to 4. 081 * Identifier returned by {@link #getType getType()} 082 * indicating an acknowledgement packet. 083 ***/ 084 public static final int ACKNOWLEDGEMENT = 4; 085 086 /*** 087 * This is the actual TFTP spec 088 * identifier and is equal to 5. 089 * Identifier returned by {@link #getType getType()} 090 * indicating an error packet. 091 ***/ 092 public static final int ERROR = 5; 093 094 /*** 095 * The TFTP data packet maximum segment size in bytes. This is 512 096 * and is useful for those familiar with the TFTP protocol who want 097 * to use the {@link org.apache.commons.net.tftp.TFTP} 098 * class methods to implement their own TFTP servers or clients. 099 ***/ 100 public static final int SEGMENT_SIZE = 512; 101 102 /*** The type of packet. ***/ 103 int _type; 104 105 /*** The port the packet came from or is going to. ***/ 106 int _port; 107 108 /*** The host the packet is going to be sent or where it came from. ***/ 109 InetAddress _address; 110 111 /*** 112 * When you receive a datagram that you expect to be a TFTP packet, you use 113 * this factory method to create the proper TFTPPacket object 114 * encapsulating the data contained in that datagram. This method is the 115 * only way you can instantiate a TFTPPacket derived class from a 116 * datagram. 117 * <p> 118 * @param datagram The datagram containing a TFTP packet. 119 * @return The TFTPPacket object corresponding to the datagram. 120 * @exception TFTPPacketException If the datagram does not contain a valid 121 * TFTP packet. 122 ***/ 123 public final static TFTPPacket newTFTPPacket(DatagramPacket datagram) 124 throws TFTPPacketException 125 { 126 byte[] data; 127 TFTPPacket packet = null; 128 129 if (datagram.getLength() < MIN_PACKET_SIZE) 130 throw new TFTPPacketException( 131 "Bad packet. Datagram data length is too short."); 132 133 data = datagram.getData(); 134 135 switch (data[1]) 136 { 137 case READ_REQUEST: 138 packet = new TFTPReadRequestPacket(datagram); 139 break; 140 case WRITE_REQUEST: 141 packet = new TFTPWriteRequestPacket(datagram); 142 break; 143 case DATA: 144 packet = new TFTPDataPacket(datagram); 145 break; 146 case ACKNOWLEDGEMENT: 147 packet = new TFTPAckPacket(datagram); 148 break; 149 case ERROR: 150 packet = new TFTPErrorPacket(datagram); 151 break; 152 default: 153 throw new TFTPPacketException( 154 "Bad packet. Invalid TFTP operator code."); 155 } 156 157 return packet; 158 } 159 160 /*** 161 * This constructor is not visible outside of the package. It is used 162 * by subclasses within the package to initialize base data. 163 * <p> 164 * @param type The type of the packet. 165 * @param address The host the packet came from or is going to be sent. 166 * @param port The port the packet came from or is going to be sent. 167 **/ 168 TFTPPacket(int type, InetAddress address, int port) 169 { 170 _type = type; 171 _address = address; 172 _port = port; 173 } 174 175 /*** 176 * This is an abstract method only available within the package for 177 * implementing efficient datagram transport by elminating buffering. 178 * It takes a datagram as an argument, and a byte buffer in which 179 * to store the raw datagram data. Inside the method, the data 180 * should be set as the datagram's data and the datagram returned. 181 * <p> 182 * @param datagram The datagram to create. 183 * @param data The buffer to store the packet and to use in the datagram. 184 * @return The datagram argument. 185 ***/ 186 abstract DatagramPacket _newDatagram(DatagramPacket datagram, byte[] data); 187 188 /*** 189 * Creates a UDP datagram containing all the TFTP packet 190 * data in the proper format. 191 * This is an abstract method, exposed to the programmer in case he 192 * wants to implement his own TFTP client instead of using 193 * the {@link org.apache.commons.net.tftp.TFTPClient} 194 * class. 195 * Under normal circumstances, you should not have a need to call this 196 * method. 197 * <p> 198 * @return A UDP datagram containing the TFTP packet. 199 ***/ 200 public abstract DatagramPacket newDatagram(); 201 202 /*** 203 * Returns the type of the packet. 204 * <p> 205 * @return The type of the packet. 206 ***/ 207 public final int getType() 208 { 209 return _type; 210 } 211 212 /*** 213 * Returns the address of the host where the packet is going to be sent 214 * or where it came from. 215 * <p> 216 * @return The type of the packet. 217 ***/ 218 public final InetAddress getAddress() 219 { 220 return _address; 221 } 222 223 /*** 224 * Returns the port where the packet is going to be sent 225 * or where it came from. 226 * <p> 227 * @return The port where the packet came from or where it is going. 228 ***/ 229 public final int getPort() 230 { 231 return _port; 232 } 233 234 /*** Sets the port where the packet is going to be sent. ***/ 235 public final void setPort(int port) 236 { 237 _port = port; 238 } 239 240 /*** Sets the host address where the packet is going to be sent. ***/ 241 public final void setAddress(InetAddress address) 242 { 243 _address = address; 244 } 245 }