View Javadoc

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   * @see TFTPPacketException
43   * @see TFTP
44   ***/
45  
46  public abstract class TFTPPacket
47  {
48      /***
49       * The minimum size of a packet.  This is 4 bytes.  It is enough
50       * to store the opcode and blocknumber or other required data
51       * depending on the packet type.
52       ***/
53      static final int MIN_PACKET_SIZE = 4;
54  
55      /***
56       * This is the actual TFTP spec
57       * identifier and is equal to 1.
58       * Identifier returned by {@link #getType getType()}
59       * indicating a read request packet.
60       ***/
61      public static final int READ_REQUEST = 1;
62  
63      /***
64       * This is the actual TFTP spec
65       * identifier and is equal to 2.
66       * Identifier returned by {@link #getType getType()}
67       * indicating a write request packet.
68       ***/
69      public static final int WRITE_REQUEST = 2;
70  
71      /***
72       * This is the actual TFTP spec
73       * identifier and is equal to 3.
74       * Identifier returned by {@link #getType getType()}
75       * indicating a data packet.
76       ***/
77      public static final int DATA = 3;
78  
79      /***
80       * This is the actual TFTP spec
81       * identifier and is equal to 4.
82       * Identifier returned by {@link #getType getType()}
83       * indicating an acknowledgement packet.
84       ***/
85      public static final int ACKNOWLEDGEMENT = 4;
86  
87      /***
88       * This is the actual TFTP spec
89       * identifier and is equal to 5.
90       * Identifier returned by {@link #getType getType()}
91       * indicating an error packet.
92       ***/
93      public static final int ERROR = 5;
94  
95      /***
96       * The TFTP data packet maximum segment size in bytes.  This is 512
97       * and is useful for those familiar with the TFTP protocol who want
98       * to use the {@link org.apache.commons.net.tftp.TFTP}
99       * 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 }