View Javadoc

1   /*
2    * Copyright 2001-2005 The Apache Software Foundation
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.commons.net.tftp;
17  
18  import java.net.DatagramPacket;
19  import java.net.InetAddress;
20  
21  /***
22   * TFTPPacket is an abstract class encapsulating the functionality common
23   * to the 5 types of TFTP packets.  It also provides a static factory
24   * method that will create the correct TFTP packet instance from a
25   * datagram.  This relieves the programmer from having to figure out what
26   * kind of TFTP packet is contained in a datagram and create it himself.
27   * <p>
28   * Details regarding the TFTP protocol and the format of TFTP packets can
29   * be found in RFC 783.  But the point of these classes is to keep you
30   * from having to worry about the internals.  Additionally, only very
31   * few people should have to care about any of the TFTPPacket classes
32   * or derived classes.  Almost all users should only be concerned with the
33   * {@link org.apache.commons.net.tftp.TFTPClient} class
34   * {@link org.apache.commons.net.tftp.TFTPClient#receiveFile receiveFile()}
35   * and
36   * {@link org.apache.commons.net.tftp.TFTPClient#sendFile sendFile()}
37   * methods.
38   * <p>
39   * <p>
40   * @author Daniel F. Savarese
41   * @see TFTPPacketException
42   * @see TFTP
43   ***/
44  
45  public abstract class TFTPPacket
46  {
47      /***
48       * The minimum size of a packet.  This is 4 bytes.  It is enough
49       * to store the opcode and blocknumber or other required data
50       * depending on the packet type.
51       ***/
52      static final int MIN_PACKET_SIZE = 4;
53  
54      /***
55       * This is the actual TFTP spec
56       * identifier and is equal to 1.
57       * Identifier returned by {@link #getType getType()}
58       * indicating a read request packet.
59       ***/
60      public static final int READ_REQUEST = 1;
61  
62      /***
63       * This is the actual TFTP spec
64       * identifier and is equal to 2.
65       * Identifier returned by {@link #getType getType()}
66       * indicating a write request packet.
67       ***/
68      public static final int WRITE_REQUEST = 2;
69  
70      /***
71       * This is the actual TFTP spec
72       * identifier and is equal to 3.
73       * Identifier returned by {@link #getType getType()}
74       * indicating a data packet.
75       ***/
76      public static final int DATA = 3;
77  
78      /***
79       * This is the actual TFTP spec
80       * identifier and is equal to 4.
81       * Identifier returned by {@link #getType getType()}
82       * indicating an acknowledgement packet.
83       ***/
84      public static final int ACKNOWLEDGEMENT = 4;
85  
86      /***
87       * This is the actual TFTP spec
88       * identifier and is equal to 5.
89       * Identifier returned by {@link #getType getType()}
90       * indicating an error packet.
91       ***/
92      public static final int ERROR = 5;
93  
94      /***
95       * The TFTP data packet maximum segment size in bytes.  This is 512
96       * and is useful for those familiar with the TFTP protocol who want
97       * to use the {@link org.apache.commons.net.tftp.TFTP}
98       * class methods to implement their own TFTP servers or clients.
99       ***/
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 }