    View Javadoc
    1   package org.apache.commons.net.tftp;
    2
    3   /* ====================================================================
    4    * The Apache Software License, Version 1.1
    5    *
    6    * Copyright (c) 2001 The Apache Software Foundation.  All rights
    7    * reserved.
    8    *
    9    * Redistribution and use in source and binary forms, with or without
    10   * modification, are permitted provided that the following conditions
    11   * are met:
    12   *
    13   * 1. Redistributions of source code must retain the above copyright
    14   *    notice, this list of conditions and the following disclaimer.
    15   *
    16   * 2. Redistributions in binary form must reproduce the above copyright
    17   *    notice, this list of conditions and the following disclaimer in
    18   *    the documentation and/or other materials provided with the
    19   *    distribution.
    20   *
    21   * 3. The end-user documentation included with the redistribution,
    22   *    if any, must include the following acknowledgment:
    23   *       "This product includes software developed by the
    24   *        Apache Software Foundation (http://www.apache.org/)."
    25   *    Alternately, this acknowledgment may appear in the software itself,
    26   *    if and wherever such third-party acknowledgments normally appear.
    27   *
    28   * 4. The names "Apache" and "Apache Software Foundation" and
    29   *    "Apache Commons" must not be used to endorse or promote products
    30   *    derived from this software without prior written permission. For
    31   *    written permission, please contact apache@apache.org.
    32   *
    33   * 5. Products derived from this software may not be called "Apache",
    34   *    nor may "Apache" appear in their name, without
    35   *    prior written permission of the Apache Software Foundation.
    36   *
    37   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
    38   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    39   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    40   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
    41   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    42   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    43   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
    44   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    45   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
    46   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
    47   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    48   * SUCH DAMAGE.
    49   * ====================================================================
    50   *
    51   * This software consists of voluntary contributions made by many
    52   * individuals on behalf of the Apache Software Foundation.  For more
    53   * information on the Apache Software Foundation, please see
    54   * <http://www.apache.org/>;.
    55   */
    56
    57  import java.net.DatagramPacket;
    58  import java.net.InetAddress;
    59
    60  /****
    61   * An abstract class derived from TFTPPacket definiing a TFTP Request
    62   * packet type.  It is subclassed by the
    63   * <a href="org.apache.commons.net.tftp.TFTPReadRequestPacket.html#_top_">
    64   * TFTPReadRequestPacket</a>  and
    65   * <a href="org.apache.commons.net.tftp.TFTPWriteRequestPacket.html#_top_">
    66   * TFTPWriteRequestPacket</a> classes.
    67   * <p>
    68   * Details regarding the TFTP protocol and the format of TFTP packets can
    69   * be found in RFC 783.  But the point of these classes is to keep you
    70   * from having to worry about the internals.  Additionally, only very
    71   * few people should have to care about any of the TFTPPacket classes
    72   * or derived classes.  Almost all users should only be concerned with the
    73   * <a href="org.apache.commons.net.tftp.TFTPClient.html#_top_">TFTPClient</a> class
    74   * <a href="org.apache.commons.net.tftp.TFTPClient.html#receiveFile">receiveFile()</a>
    75   * and
    76   * <a href="org.apache.commons.net.tftp.TFTPClient.html#sendFile">sendFile()</a>
    77   * methods.
    78   * <p>
    79   * <p>
    80   * @author Daniel F. Savarese
    81   * @see TFTPPacket
    82   * @see TFTPReadRequestPacket
    83   * @see TFTPWriteRequestPacket
    84   * @see TFTPPacketException
    85   * @see TFTP
    86   ***/
    87
    88  public abstract class TFTPRequestPacket extends TFTPPacket
    89  {
    90      /****
    91       * An array containing the string names of the transfer modes and indexed
    92       * by the transfer mode constants.
    93       ***/
    94      static final String[] _modeStrings = { "netascii", "octet" };
    95
    96      /****
    97       * A null terminated byte array representation of the ascii names of the
    98       * transfer mode constants.  This is convenient for creating the TFTP
    99       * request packets.
    100      ***/
    101     static final byte[] _modeBytes[] = {
    102                                            { (byte)'n', (byte)'e', (byte)'t', (byte)'a', (byte)'s', (byte)'c',
    103                                              (byte)'i', (byte)'i', 0 },
    104                                            { (byte)'o', (byte)'c', (byte)'t', (byte)'e', (byte)'t', 0 }
    105                                        };
    106
    107     /**** The transfer mode of the request. ***/
    108     int _mode;
    109
    110     /**** The filename of the request. ***/
    111     String _filename;
    112
    113     /****
    114      * Creates a request packet of a given type to be sent to a host at a
    115      * given port with a filename and transfer mode request.
    116      * <p>
    117      * @param destination  The host to which the packet is going to be sent.
    118      * @param port  The port to which the packet is going to be sent.
    119      * @param type The type of the request (either TFTPPacket.READ_REQUEST or
    120      *             TFTPPacket.WRITE_REQUEST).
    121      * @param filename The requested filename.
    122      * @param mode The requested transfer mode.  This should be on of the TFTP
    123      *        class MODE constants (e.g., TFTP.NETASCII_MODE).
    124      ***/
    125     TFTPRequestPacket(InetAddress destination, int port,
    126                       int type, String filename, int mode)
    127     {
    128         super(type, destination, port);
    129
    130         _filename = filename;
    131         _mode = mode;
    132     }
    133
    134     /****
    135      * Creates a request packet of a given type based on a received
    136      * datagram.  Assumes the datagram is at least length 4, else an
    137      * ArrayIndexOutOfBoundsException may be thrown.
    138      * <p>
    139      * @param type The type of the request (either TFTPPacket.READ_REQUEST or
    140      *             TFTPPacket.WRITE_REQUEST).
    141      * @param datagram  The datagram containing the received request.
    142      * @throws TFTPPacketException  If the datagram isn't a valid TFTP
    143      *         request packet of the appropriate type.
    144      ***/
    145     TFTPRequestPacket(int type, DatagramPacket datagram)
    146     throws TFTPPacketException
    147     {
    148         super(type, datagram.getAddress(), datagram.getPort());
    149
    150         byte[] data;
    151         int index, length;
    152         String mode;
    153         StringBuffer buffer;
    154
    155         data = datagram.getData();
    156
    157         if (getType() != data[1])
    158             throw new TFTPPacketException("TFTP operator code does not match type.");
    159
    160         buffer = new StringBuffer();
    161
    162         index = 2;
    163         length = datagram.getLength();
    164
    165         while (index < length && data[index] != 0)
    166         {
    167             buffer.append((char)data[index]);
    168             ++index;
    169         }
    170
    171         _filename = buffer.toString();
    172
    173         if (index >= length)
    174             throw new TFTPPacketException("Bad filename and mode format.");
    175
    176         buffer.setLength(0);
    177         ++index; // need to advance beyond the end of string marker
    178         while (index < length && data[index] != 0)
    179         {
    180             buffer.append((char)data[index]);
    181             ++index;
    182         }
    183
    184         mode = buffer.toString().toLowerCase();
    185         length = _modeStrings.length;
    186
    187         for (index = 0; index < length; index++)
    188         {
    189             if (mode.equals(_modeStrings[index]))
    190             {
    191                 _mode = index;
    192                 break;
    193             }
    194         }
    195
    196         if (index >= length)
    197         {
    198             throw new TFTPPacketException("Unrecognized TFTP transfer mode: " + mode);
    199             // May just want to default to binary mode instead of throwing
    200             // exception.
    201             //_mode = TFTP.OCTET_MODE;
    202         }
    203     }
    204
    205
    206     /****
    207      * This is a method only available within the package for
    208      * implementing efficient datagram transport by elminating buffering.
    209      * It takes a datagram as an argument, and a byte buffer in which
    210      * to store the raw datagram data.  Inside the method, the data
    211      * is set as the datagram's data and the datagram returned.
    212      * <p>
    213      * @param datagram  The datagram to create.
    214      * @param data The buffer to store the packet and to use in the datagram.
    215      * @return The datagram argument.
    216      ***/
    217     final DatagramPacket _newDatagram(DatagramPacket datagram, byte[] data)
    218     {
    219         int fileLength, modeLength;
    220
    221         fileLength = _filename.length();
    222         modeLength = _modeBytes[_mode].length;
    223
    224         data[0] = 0;
    225         data[1] = (byte)_type;
    226         System.arraycopy(_filename.getBytes(), 0, data, 2, fileLength);
    227         data[fileLength + 2] = 0;
    228         System.arraycopy(_modeBytes[_mode], 0, data, fileLength + 3,
    229                          modeLength);
    230
    231         datagram.setAddress(_address);
    232         datagram.setPort(_port);
    233         datagram.setData(data);
    234         datagram.setLength(fileLength + modeLength + 4);
    235
    236         return datagram;
    237     }
    238
    239     /****
    240      * Creates a UDP datagram containing all the TFTP
    241      * request packet data in the proper format.
    242      * This is a method exposed to the programmer in case he
    243      * wants to implement his own TFTP client instead of using
    244      * the <a href="org.apache.commons.net.tftp.TFTPClient.html#_top_">TFTPClient</a>
    245      * class.  Under normal circumstances, you should not have a need to call
    246      * this method.
    247      * <p>
    248      * @return A UDP datagram containing the TFTP request packet.
    249      ***/
    250     public final DatagramPacket newDatagram()
    251     {
    252         int fileLength, modeLength;
    253         byte[] data;
    254
    255         fileLength = _filename.length();
    256         modeLength = _modeBytes[_mode].length;
    257
    258         data = new byte[fileLength + modeLength + 4];
    259         data[0] = 0;
    260         data[1] = (byte)_type;
    261         System.arraycopy(_filename.getBytes(), 0, data, 2, fileLength);
    262         data[fileLength + 2] = 0;
    263         System.arraycopy(_modeBytes[_mode], 0, data, fileLength + 3,
    264                          modeLength);
    265
    266         return new DatagramPacket(data, data.length, _address, _port);
    267     }
    268
    269     /****
    270      * Returns the transfer mode of the request.
    271      * <p>
    272      * @return The transfer mode of the request.
    273      ***/
    274     public final int getMode()
    275     {
    276         return _mode;
    277     }
    278
    279     /****
    280      * Returns the requested filename.
    281      * <p>
    282      * @return The requested filename.
    283      ***/
    284     public final String getFilename()
    285     {
    286         return _filename;
    287     }
    288 }

This page was automatically generated by Maven