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
018 package org.apache.commons.net.tftp;
019
020 import java.net.DatagramPacket;
021 import 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 * <p>
041 * <p>
042 * @see TFTPPacketException
043 * @see TFTP
044 ***/
045
046 public 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 * <p>
119 * @param datagram The datagram containing a TFTP packet.
120 * @return The TFTPPacket object corresponding to the datagram.
121 * @exception TFTPPacketException If the datagram does not contain a valid
122 * TFTP packet.
123 ***/
124 public final static 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 * <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 }