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 }