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