/*****************************************************************************/
/* File name: TestClient.java                                                */
/* Purpose: to test portmapper server                                        */
/*                                                                           */
/* Last modified: 30.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*                                                                           */
/* This program is distributed in the hope that it will be useful, but       */
/* WITHOUT ANY WARRANTY; without even the implied warranty of                */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General */
/* Public License for more details.                                          */
/*                                                                           */
/* This software is distributed under the terms                              */
/* of the GNU General Public License as published                            */
/* by the Free Software Foundation; either version 2, or (at your option)    */
/* any later version.                                                        */
/* See file COPYING for your rights (GNU GPL)                                */
/*****************************************************************************/

package pm;


import java.net.*;
import java.io.*;
import rpc.*;


public
class

TestClient
        extends rpc.ParserResponder
                                    implements Runnable
{

  private final static String RCSID = "$Header: /d/NFS/pm/RCS/TestClient.java,v 1.7 1999/08/02 16:49:03 vklimov Exp $";



  public

  TestClient( java.lang.String propertiesFilePath )

                                                    throws  SocketException
/*****************************************************************************/
/* Function name: TestClient                                                 */
/* File name: TestClient.java                                                */
/* Purpose: constructor for the TestClient class                             */
/* Throws: SocketException                                                   */
/* Parameters: propertiesFilePath                                            */
/* Returns:                                                                  */
/* Last modified: 10.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
                                                       /* TestClient */
/*---------------------------------------------------------------------------*/

      super( Constants.PORT_MAPPER_PORT,
             propertiesFilePath          );

    }
/*end of TestClient*/


  public
  void

  sendDumpRequestRPCMessageToPortMapper( long transactionId )
/*****************************************************************************/
/* Function name: sendDumpRequestRPCMessageToPortMapper                      */
/* File name: TestClient.java                                                */
/* Purpose: to create dump request RPC message and send it                   */
/*          to portmapping server                                            */
/* Parameters: transactionId                                                 */
/* Returns:                                                                  */
/* Last modified: 30.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      byte[] ibuf = null;
      int ilength = 0;
      InetAddress ipAddressWhereToSend = null;
      int portToSendTo = 0;
      DatagramPacket udpPacket = null;
      Message rpcMessage = null;

                                /* sendDumpRequestRPCMessageToPortMapper */
/*---------------------------------------------------------------------------*/

      ibuf = new byte[
              Constants.
                PORTMAPPER_DUMP_REQUEST_UDP_PACKET_DATA_LENGTH ];

      rpcMessage =
        new Message( ibuf );

      rpcMessage.
        putUnsignedInteger( transactionId );
      rpcMessage.
        putUnsignedInteger( rpc.Constants.RPC_CALL );
      rpcMessage.
        putUnsignedInteger(
          rpc.Constants.HIGHEST_RPC_PROTOCOL_VERSION_SUPPORTED );
      rpcMessage.
        putUnsignedInteger( (long) pm.Constants.PMAP_PROG );
      rpcMessage.
        putUnsignedInteger( pm.Constants.PMAP_VERS_HIGH );
      rpcMessage.
        putUnsignedInteger( (long) pm.Constants.PMAPPROC_DUMP );
      rpcMessage.
        putEmptyOpaqueAuthentication();
      rpcMessage.
        putEmptyOpaqueAuthentication();

      portToSendTo = pm.Constants.PORT_MAPPER_PORT;

      try
        {
          ipAddressWhereToSend =
            InetAddress.getByName(
              rpc.Constants.LOCAL_LOOP_IP_ADDRESS );
        }
      catch( UnknownHostException e )
        {
          System.out.println( e.getMessage() );
          return;                                      /* return ! */
        }
    /*end of try*/

      udpPacket = new
        DatagramPacket( ibuf, ibuf.length,
                        ipAddressWhereToSend,
                        portToSendTo          );

      try
        {
          udpSocket.send( udpPacket,
                          transactionId,
                          "sendDumpRequestRPCMessageToPortMapper" );
        }
      catch( IOException e )
        {
          System.out.println(
            "NFS TestClient, " +
            "sendDumpRequestRPCMessageToPortMapper: " +
            "IOException in sending datagram\n" +
            e.getMessage()                              );
        }
    /*end of try-catch*/

    }
/*end of sendDumpRequestRPCMessageToPortMapper*/


  public
  void

  sendRegistrationRPCMessageToPortMapper( long transactionId,
                                          Mapping mapping     )
/*****************************************************************************/
/* Function name: sendRegistrationRPCMessageToPortMapper                     */
/* File name: TestClient.java                                                */
/* Purpose: to create a port registration RPC message and send it            */
/*          to portmapping server                                            */
/* Parameters: transactionId                                                 */
/*             mapping                                                       */
/* Returns:                                                                  */
/* Last modified: 30.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      byte[] ibuf = null;
      int ilength = 0;
      InetAddress ipAddressWhereToSend = null;
      int portToSendTo = 0;
      DatagramPacket udpPacket = null;
      Message rpcMessage = null;

                                /* sendRegistrationRPCMessageToPortMapper */
/*---------------------------------------------------------------------------*/

      ibuf = new byte[
              nfs.Constants.
                PORTMAPPER_REGISTRATION_UDP_PACKET_DATA_LENGTH ];

      rpcMessage =
        new Message( ibuf );

      rpcMessage.
        putUnsignedInteger( transactionId );
      rpcMessage.
        putUnsignedInteger( rpc.Constants.RPC_CALL );
      rpcMessage.
        putUnsignedInteger(
          rpc.Constants.HIGHEST_RPC_PROTOCOL_VERSION_SUPPORTED );
      rpcMessage.
        putUnsignedInteger( (long) pm.Constants.PMAP_PROG );
      rpcMessage.
        putUnsignedInteger( pm.Constants.PMAP_VERS_HIGH );
      rpcMessage.
        putUnsignedInteger( (long) pm.Constants.PMAPPROC_SET );
      rpcMessage.
        putEmptyOpaqueAuthentication();
      rpcMessage.
        putEmptyOpaqueAuthentication();
                                                    /* registration 4-tuple */

      rpcMessage.
        putUnsignedInteger( mapping.programNumber );
      rpcMessage.
        putUnsignedInteger( mapping.versionNumber );
      rpcMessage.
        putUnsignedInteger( mapping.protocolNumber );
      rpcMessage.
        putUnsignedInteger( mapping.portNumber );

      portToSendTo = pm.Constants.PORT_MAPPER_PORT;

      try
        {
          ipAddressWhereToSend =
            InetAddress.getByName(
              rpc.Constants.LOCAL_LOOP_IP_ADDRESS );
        }
      catch( UnknownHostException e )
        {
          System.out.println( e.getMessage() );
          return;                                      /* return ! */
        }
    /*end of try*/

      udpPacket = new
        DatagramPacket( ibuf, ibuf.length,
                        ipAddressWhereToSend,
                        portToSendTo          );

      try
        {
          udpSocket.send( udpPacket,
                          transactionId,
                          "sendRegistrationRPCMessageToPortMapper" );
        }
      catch( IOException e )
        {
          System.out.println(
            "NFS TestClient, " +
            "sendRegistrationRPCMessageToPortMapper: " +
            "IOException in sending datagram\n" +
            e.getMessage()                              );
        }
    /*end of try-catch*/

    }
/*end of sendRegistrationRPCMessageToPortMapper*/


  public
  void

  sendGetPortRPCMessageToPortMapper( long transactionId )
/*****************************************************************************/
/* Function name: sendGetPortRPCMessageToPortMapper                          */
/* File name: TestClient.java                                                */
/* Purpose: to create a get port RPC message and send it                     */
/*          to portmapping server                                            */
/* Parameters: transactionId                                                 */
/* Returns:                                                                  */
/* Last modified: 30.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      byte[] ibuf = null;
      int ilength = 0;
      InetAddress ipAddressWhereToSend = null;
      int portToSendTo = 0;
      DatagramPacket udpPacket = null;
      Message rpcMessage = null;

                                /* sendGetPortRPCMessageToPortMapper */
/*---------------------------------------------------------------------------*/

      ibuf = new byte[
              nfs.Constants.
                PORTMAPPER_REGISTRATION_UDP_PACKET_DATA_LENGTH ];

      rpcMessage =
        new Message( ibuf );

      rpcMessage.
        putUnsignedInteger( transactionId );
      rpcMessage.
        putUnsignedInteger( rpc.Constants.RPC_CALL );
      rpcMessage.
        putUnsignedInteger(
          rpc.Constants.HIGHEST_RPC_PROTOCOL_VERSION_SUPPORTED );
      rpcMessage.
        putUnsignedInteger( (long) pm.Constants.PMAP_PROG );
      rpcMessage.
        putUnsignedInteger( pm.Constants.PMAP_VERS_HIGH );
      rpcMessage.
        putUnsignedInteger( (long) pm.Constants.PMAPPROC_GETPORT );
      rpcMessage.
        putEmptyOpaqueAuthentication();
      rpcMessage.
        putEmptyOpaqueAuthentication();
                                                    /* registration 4-tuple */

      rpcMessage.
        putUnsignedInteger( nfs.Constants.NFS_PROGRAM );
      rpcMessage.
        putUnsignedInteger( nfs.Constants.NFS_VERSION );
      rpcMessage.
        putUnsignedInteger( pm.Constants.IPPROTO_UDP );
      rpcMessage.
        putUnsignedInteger( (long) 0 );            /* ignored by the server */

      portToSendTo = pm.Constants.PORT_MAPPER_PORT;

      try
        {
          ipAddressWhereToSend =
            InetAddress.getByName(
              rpc.Constants.LOCAL_LOOP_IP_ADDRESS );
        }
      catch( UnknownHostException e )
        {
          System.out.println( e.getMessage() );
          return;                                      /* return ! */
        }
    /*end of try*/

      udpPacket = new
        DatagramPacket( ibuf, ibuf.length,
                        ipAddressWhereToSend,
                        portToSendTo          );

      try
        {
          udpSocket.send( udpPacket,
                          transactionId,
                          "sendGetPortRPCMessageToPortMapper" );
        }
      catch( IOException e )
        {
          System.out.println(
            "NFS TestClient, " +
            "sendGetPortRPCMessageToPortMapper: " +
            "IOException in sending datagram\n" +
            e.getMessage()                              );
        }
    /*end of try-catch*/

    }
/*end of sendGetPortRPCMessageToPortMapper*/


  public
  void

  sendUnregisterRPCMessageToPortMapper( long transactionId )
/*****************************************************************************/
/* Function name: sendUnregisterRPCMessageToPortMapper                       */
/* File name: TestClient.java                                                */
/* Purpose: to create an unregister RPC message and send it                  */
/*          to portmapping server                                            */
/* Parameters: transactionId                                                 */
/* Returns:                                                                  */
/* Last modified: 30.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      byte[] ibuf = null;
      int ilength = 0;
      InetAddress ipAddressWhereToSend = null;
      int portToSendTo = 0;
      DatagramPacket udpPacket = null;
      Message rpcMessage = null;

                                /* sendUnregisterRPCMessageToPortMapper */
/*---------------------------------------------------------------------------*/

      ibuf = new byte[
              nfs.Constants.
                PORTMAPPER_REGISTRATION_UDP_PACKET_DATA_LENGTH ];

      rpcMessage =
        new Message( ibuf );

      rpcMessage.
        putUnsignedInteger( transactionId );
      rpcMessage.
        putUnsignedInteger( rpc.Constants.RPC_CALL );
      rpcMessage.
        putUnsignedInteger(
          rpc.Constants.HIGHEST_RPC_PROTOCOL_VERSION_SUPPORTED );
      rpcMessage.
        putUnsignedInteger( (long) pm.Constants.PMAP_PROG );
      rpcMessage.
        putUnsignedInteger( pm.Constants.PMAP_VERS_HIGH );
      rpcMessage.
        putUnsignedInteger( (long) pm.Constants.PMAPPROC_UNSET );
      rpcMessage.
        putEmptyOpaqueAuthentication();
      rpcMessage.
        putEmptyOpaqueAuthentication();
                                                    /* registration 4-tuple */

      rpcMessage.
        putUnsignedInteger( nfs.Constants.NFS_PROGRAM );
      rpcMessage.
        putUnsignedInteger( nfs.Constants.NFS_VERSION );
      rpcMessage.
        putUnsignedInteger( pm.Constants.IPPROTO_UDP );
      rpcMessage.
        putUnsignedInteger( nfs.Constants.NFS_PORT );

      portToSendTo = pm.Constants.PORT_MAPPER_PORT;

      try
        {
          ipAddressWhereToSend =
            InetAddress.getByName(
              rpc.Constants.LOCAL_LOOP_IP_ADDRESS );
        }
      catch( UnknownHostException e )
        {
          System.out.println( e.getMessage() );
          return;                                      /* return ! */
        }
    /*end of try*/

      udpPacket = new
        DatagramPacket( ibuf, ibuf.length,
                        ipAddressWhereToSend,
                        portToSendTo          );

      try
        {
          udpSocket.send( udpPacket,
                          transactionId,
                          "sendUnregisterRPCMessageToPortMapper" );
        }
      catch( IOException e )
        {
          System.out.println(
            "NFS TestClient, " +
            "sendUnregisterRPCMessageToPortMapper: " +
            "IOException in sending datagram\n" +
            e.getMessage()                              );
        }
    /*end of try-catch*/

    }
/*end of sendUnregisterRPCMessageToPortMapper*/


  public
  void

  analyzeDumpRPCReplyMessage(
    ParserResponderReturnArguments
      parserResponderReturnArguments,
    int nMaxMappingsDumpToGet         )
/*****************************************************************************/
/* Function name: analyzeDumpRPCReplyMessage                                 */
/* File name: TestClient.java                                                */
/* Purpose: to analyze the reply of the portmapper on dump request           */
/* Parameters: parserResponderReturnArguments                                */
/*             nMaxMappingsDumpToGet                                         */
/* Returns:                                                                  */
/* Last modified: 07.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      int i;
      boolean continueToLoop = true;
      Mapping mapping = new Mapping();
      Message rpcMessageWithParametersToRemoteProcedure = null;

                                          /* analyzeDumpRPCReplyMessage */
/*---------------------------------------------------------------------------*/

      rpcMessageWithParametersToRemoteProcedure = new
        Message(
          parserResponderReturnArguments.
            byteArrayContainingParametersToRemoteProcedure );

      for (i=0;
           ( continueToLoop &&
             (i<nMaxMappingsDumpToGet)
           );                          i++)
        {
          mapping.programNumber =
            rpcMessageWithParametersToRemoteProcedure.
              getUnsignedInteger();
          mapping.versionNumber =
            rpcMessageWithParametersToRemoteProcedure.
              getUnsignedInteger();
          mapping.protocolNumber =
            rpcMessageWithParametersToRemoteProcedure.
              getUnsignedInteger();
          mapping.portNumber =
            rpcMessageWithParametersToRemoteProcedure.
              getUnsignedInteger();

          if ( (mapping.programNumber ==
                Constants.END_OF_MAPPING_LIST_UNSIGNED_INT) &&
               (mapping.versionNumber ==
                Constants.END_OF_MAPPING_LIST_UNSIGNED_INT) &&
               (mapping.protocolNumber ==
                Constants.END_OF_MAPPING_LIST_UNSIGNED_INT) &&
               (mapping.portNumber ==
                Constants.END_OF_MAPPING_LIST_UNSIGNED_INT)
             )
            continueToLoop = false;
          else
            System.out.println( "i=" + i +
                                " mapping=\n" +
                                mapping.toString() );
        /*end of if on end of list*/
        }
    /*end of for-loop*/

    }
/*end of analyzeDumpRPCReplyMessage*/


  public
  boolean

  analyzeRPCReplyMessageFromRegistration(
    ParserResponderReturnArguments
      parserResponderReturnArguments     )
/*****************************************************************************/
/* Function name: analyzeRPCReplyMessageFromRegistration                     */
/* File name: TestClient.java                                                */
/* Purpose: to analyze the reply of the portmapper on registration request   */
/* Parameters: parserResponderReturnArguments                                */
/* Returns: true - if registered OK, false - otherwise                       */
/* Last modified: 05.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      long registeredOK;
      Message rpcMessageWithParametersToRemoteProcedure = null;

                               /* analyzeRPCReplyMessageFromRegistration */
/*---------------------------------------------------------------------------*/

      rpcMessageWithParametersToRemoteProcedure = new
        Message(
          parserResponderReturnArguments.
            byteArrayContainingParametersToRemoteProcedure );

      registeredOK =
        rpcMessageWithParametersToRemoteProcedure.
          getUnsignedInteger();

      if (registeredOK == xdr.Constants.TRUE)
        return true;
      else
        return false;
    /*end of if*/

    }
/*end of analyzeRPCReplyMessageFromRegistration*/


  public
  long

  analyzeRPCReplyMessageWithPortNumber(
    ParserResponderReturnArguments
      parserResponderReturnArguments     )
/*****************************************************************************/
/* Function name: analyzeRPCReplyMessageWithPortNumber                       */
/* File name: TestClient.java                                                */
/* Purpose: to analyze the reply of the portmapper on get port request       */
/* Parameters: parserResponderReturnArguments                                */
/* Returns: the port number                                                  */
/* Last modified: 05.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      long portNumber;
      Message rpcMessageWithParametersToRemoteProcedure = null;

                               /* analyzeRPCReplyMessageWithPortNumber */
/*---------------------------------------------------------------------------*/

      rpcMessageWithParametersToRemoteProcedure = new
        Message(
          parserResponderReturnArguments.
            byteArrayContainingParametersToRemoteProcedure );

      portNumber =
        rpcMessageWithParametersToRemoteProcedure.
          getUnsignedInteger();

      return portNumber;

    }
/*end of analyzeRPCReplyMessageWithPortNumber*/


  public
  boolean

  analyzeRPCReplyMessageUnregister(
    ParserResponderReturnArguments
      parserResponderReturnArguments  )
/*****************************************************************************/
/* Function name: analyzeRPCReplyMessageUnregister                           */
/* File name: TestClient.java                                                */
/* Purpose: to analyze the reply of the portmapper on unregister request     */
/* Parameters: parserResponderReturnArguments                                */
/* Returns: true - if unregistered OK, false - otherwise                     */
/* Last modified: 05.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      long unregisteredOK;
      Message rpcMessageWithParametersToRemoteProcedure = null;

                                    /* analyzeRPCReplyMessageUnregister */
/*---------------------------------------------------------------------------*/

      rpcMessageWithParametersToRemoteProcedure = new
        Message(
          parserResponderReturnArguments.
            byteArrayContainingParametersToRemoteProcedure );

      unregisteredOK =
        rpcMessageWithParametersToRemoteProcedure.
          getUnsignedInteger();

      if (unregisteredOK == xdr.Constants.TRUE)
        return true;
      else
        return false;
    /*end of if*/

    }
/*end of analyzeRPCReplyMessageUnregister*/


  public
  boolean

  receiveRegistrationConfirmationRPCMessageFromPortMapper()
/*****************************************************************************/
/* Function name: receiveRegistrationConfirmationRPCMessageFromPortMapper    */
/* File name: TestClient.java                                                */
/* Purpose: to get an answer from the portmapper                             */
/* Parameters:                                                               */
/* Returns: true - if registered OK, false - otherwise                       */
/* Last modified: 05.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      ParserResponderReturnArguments
        parserResponderReturnArguments;
      boolean registeredOK;
      boolean nowMayProcessTheParametersToRemoteProcedure;
      byte[] byteBuffer = null;
      DatagramPacket udpPacket = null;

                 /* receiveRegistrationConfirmationRPCMessageFromPortMapper */
/*---------------------------------------------------------------------------*/

      byteBuffer = new byte[ pm.Constants.UDP_PACKET_LENGTH ];

      udpPacket = new
        DatagramPacket( byteBuffer,
                        byteBuffer.length );

      try
        {
          udpSocket.receive( udpPacket );
        }
      catch( IOException e )
        {
          System.out.println(
            "udpSocket.receive: " +
            e.getMessage()          );
        }
    /*end of try-catch*/

      parserResponderReturnArguments = new
        ParserResponderReturnArguments();

      nowMayProcessTheParametersToRemoteProcedure =
        processUDPPacket(
          udpPacket,
          parserResponderReturnArguments      );

      if ( nowMayProcessTheParametersToRemoteProcedure )
        {
          registeredOK =
            analyzeRPCReplyMessageFromRegistration(
              parserResponderReturnArguments        );

          return registeredOK;                                /* return ! */
        }
      else
        ;
    /*end of if on nowMayProcessTheParametersToRemoteProcedure*/

      return false;

    }
/*end of receiveRegistrationConfirmationRPCMessageFromPortMapper*/


  public
  long

  receiveGetPortNumberRPCMessageFromPortMapper()
/*****************************************************************************/
/* Function name: receiveGetPortNumberRPCMessageFromPortMapper               */
/* File name: TestClient.java                                                */
/* Purpose: to get port number from the portmapper                           */
/* Parameters:                                                               */
/* Returns: the port number                                                  */
/* Last modified: 05.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      ParserResponderReturnArguments
        parserResponderReturnArguments;
      long portNumber = pm.Constants.PORT_NOT_FOUND_NUMBER;
      boolean nowMayProcessTheParametersToRemoteProcedure;
      byte[] byteBuffer = null;
      DatagramPacket udpPacket = null;

                 /* receiveGetPortNumberRPCMessageFromPortMapper */
/*---------------------------------------------------------------------------*/

      byteBuffer = new byte[ pm.Constants.UDP_PACKET_LENGTH ];

      udpPacket = new
        DatagramPacket( byteBuffer,
                        byteBuffer.length );

      try
        {
          udpSocket.receive( udpPacket );
        }
      catch( IOException e )
        {
          System.out.println(
            "udpSocket.receive: " +
            e.getMessage()          );
        }
    /*end of try-catch*/

      parserResponderReturnArguments = new
        ParserResponderReturnArguments();

      nowMayProcessTheParametersToRemoteProcedure =
        processUDPPacket(
          udpPacket,
          parserResponderReturnArguments      );

      if ( nowMayProcessTheParametersToRemoteProcedure )
        {
          portNumber =
            analyzeRPCReplyMessageWithPortNumber(
              parserResponderReturnArguments        );
        }
      else
        ;
    /*end of if on nowMayProcessTheParametersToRemoteProcedure*/

      return portNumber;                                /* return ! */

    }
/*end of receiveGetPortNumberRPCMessageFromPortMapper*/


  public
  void

  receiveDumpRPCMessageFromPortMapperAndPrintOut(
    int nMaxMappingsDumpToGet                     )
/*****************************************************************************/
/* Function name: receiveDumpRPCMessageFromPortMapperAndPrintOut             */
/* File name: TestClient.java                                                */
/* Purpose: to get dump info from the portmapper and print it out            */
/* Parameters: nMaxMappingsDumpToGet                                         */
/* Returns: nothing                                                          */
/* Last modified: 07.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      ParserResponderReturnArguments
        parserResponderReturnArguments;
      boolean nowMayProcessTheParametersToRemoteProcedure;
      byte[] byteBuffer = null;
      DatagramPacket udpPacket = null;

                       /* receiveDumpRPCMessageFromPortMapperAndPrintOut */
/*---------------------------------------------------------------------------*/

      byteBuffer = new
        byte[ pm.Constants.
                PMAPPROC_DUMP_UDP_DATA_PREFIX_LENGTH +
              (nMaxMappingsDumpToGet *
               Constants.N_BYTES_PER_MAPPING)           ];

      udpPacket = new
        DatagramPacket( byteBuffer,
                        byteBuffer.length );

      try
        {
          udpSocket.receive( udpPacket );
        }
      catch( IOException e )
        {
          System.out.println(
            "udpSocket.receive: " +
            e.getMessage()          );
        }
    /*end of try-catch*/

      parserResponderReturnArguments = new
        ParserResponderReturnArguments();

      nowMayProcessTheParametersToRemoteProcedure =
        processUDPPacket(
          udpPacket,
          parserResponderReturnArguments      );

      if ( nowMayProcessTheParametersToRemoteProcedure )
        {
          analyzeDumpRPCReplyMessage(
            parserResponderReturnArguments,
            nMaxMappingsDumpToGet           );
        }
      else
        ;
    /*end of if on nowMayProcessTheParametersToRemoteProcedure*/

    }
/*end of receiveDumpRPCMessageFromPortMapperAndPrintOut*/


  public
  boolean

  receiveUnregisterConfirmationRPCMessageFromPortMapper()
/*****************************************************************************/
/* Function name: receiveUnregisterConfirmationRPCMessageFromPortMapper      */
/* File name: TestClient.java                                                */
/* Purpose: to get an answer from the portmapper                             */
/* Parameters:                                                               */
/* Returns: true - if unregistered OK, false - otherwise                     */
/* Last modified: 05.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      ParserResponderReturnArguments
        parserResponderReturnArguments;
      boolean unregisteredOK;
      boolean nowMayProcessTheParametersToRemoteProcedure;
      byte[] byteBuffer = null;
      DatagramPacket udpPacket = null;

                 /* receiveUnregisterConfirmationRPCMessageFromPortMapper */
/*---------------------------------------------------------------------------*/

      byteBuffer = new byte[ pm.Constants.UDP_PACKET_LENGTH ];

      udpPacket = new
        DatagramPacket( byteBuffer,
                        byteBuffer.length );

      try
        {
          udpSocket.receive( udpPacket );
        }
      catch( IOException e )
        {
          System.out.println(
            "udpSocket.receive: " +
            e.getMessage()          );
        }
    /*end of try-catch*/

      parserResponderReturnArguments = new
        ParserResponderReturnArguments();

      nowMayProcessTheParametersToRemoteProcedure =
        processUDPPacket(
          udpPacket,
          parserResponderReturnArguments      );

      if ( nowMayProcessTheParametersToRemoteProcedure )
        {
          unregisteredOK =
            analyzeRPCReplyMessageUnregister(
              parserResponderReturnArguments  );

          return unregisteredOK;                              /* return ! */
        }
      else
        ;
    /*end of if on nowMayProcessTheParametersToRemoteProcedure*/

      return false;

    }
/*end of receiveUnregisterConfirmationRPCMessageFromPortMapper*/


  public
  void

  run()
/*****************************************************************************/
/* Function name: run                                                        */
/* File name: TestClient.java                                                */
/* Purpose: to test the portmapper server                                    */
/* Parameters:                                                               */
/* Returns:                                                                  */
/* Last modified: 07.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      boolean registeredOK;
      boolean unregisteredOK;
      long portNumber = 0;
      Mapping mapping;
                                                                 /* run */
/*---------------------------------------------------------------------------*/

      mapping = new Mapping( nfs.Constants.NFS_PROGRAM,
                             nfs.Constants.NFS_VERSION,
                             pm.Constants.IPPROTO_UDP,
                             nfs.Constants.NFS_PORT     );

      sendRegistrationRPCMessageToPortMapper(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        mapping                                );

      registeredOK =
        receiveRegistrationConfirmationRPCMessageFromPortMapper();

System.out.println( "\n\nrun: registeredOK=" + registeredOK );
                                                            /* reject test */
      sendRegistrationRPCMessageToPortMapper(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        mapping                                    );

      registeredOK =
        receiveRegistrationConfirmationRPCMessageFromPortMapper();

System.out.println( "\n\nrun: registeredOK=" + registeredOK );

      sendGetPortRPCMessageToPortMapper(
        nfs.Constants.INITIAL_TRANSACTION_ID );

      portNumber =
        receiveGetPortNumberRPCMessageFromPortMapper();

System.out.println( "\n\nrun: got portNumber=" + portNumber );

      sendUnregisterRPCMessageToPortMapper(
        nfs.Constants.INITIAL_TRANSACTION_ID );

      unregisteredOK =
        receiveUnregisterConfirmationRPCMessageFromPortMapper();

System.out.println( "\n\nrun: unregisteredOK=" + unregisteredOK );

      sendUnregisterRPCMessageToPortMapper(
        nfs.Constants.INITIAL_TRANSACTION_ID       );

      unregisteredOK =
        receiveUnregisterConfirmationRPCMessageFromPortMapper();

System.out.println( "\n\nrun: unregisteredOK=" + unregisteredOK );

                                                       /* dump test */
      mapping = new Mapping( nfs.Constants.NFS_PROGRAM,
                             nfs.Constants.NFS_VERSION,
                             pm.Constants.IPPROTO_UDP,
                             nfs.Constants.NFS_PORT     );
      sendRegistrationRPCMessageToPortMapper(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        mapping                                    );

      registeredOK =
        receiveRegistrationConfirmationRPCMessageFromPortMapper();

System.out.println( "\n\nrun: registeredOK=" + registeredOK );

      mapping = new Mapping( 1, 1, 1, 1 );
      sendRegistrationRPCMessageToPortMapper(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        mapping                                    );

      registeredOK =
        receiveRegistrationConfirmationRPCMessageFromPortMapper();

System.out.println( "\n\nrun: registeredOK=" + registeredOK );

      mapping = new Mapping( 1, 2, 1, 1 );
      sendRegistrationRPCMessageToPortMapper(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        mapping                                    );

      registeredOK =
        receiveRegistrationConfirmationRPCMessageFromPortMapper();

System.out.println( "\n\nrun: registeredOK=" + registeredOK );

      mapping = new Mapping( 1, 3, 1, 1 );
      sendRegistrationRPCMessageToPortMapper(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        mapping                                    );

      registeredOK =
        receiveRegistrationConfirmationRPCMessageFromPortMapper();

System.out.println( "\n\nrun: registeredOK=" + registeredOK );

      mapping = new Mapping( 1, 4, 1, 1 );
      sendRegistrationRPCMessageToPortMapper(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        mapping                                    );

      registeredOK =
        receiveRegistrationConfirmationRPCMessageFromPortMapper();

System.out.println( "\n\nrun: registeredOK=" + registeredOK );

      mapping = new Mapping( 1, 5, 1, 1 );
      sendRegistrationRPCMessageToPortMapper(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        mapping                                    );

      registeredOK =
        receiveRegistrationConfirmationRPCMessageFromPortMapper();

System.out.println( "\n\nrun: registeredOK=" + registeredOK );

      mapping = new Mapping( 1, 1, 2, 1 );
      sendRegistrationRPCMessageToPortMapper(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        mapping                                    );

      registeredOK =
        receiveRegistrationConfirmationRPCMessageFromPortMapper();

System.out.println( "\n\nrun: registeredOK=" + registeredOK );

      mapping = new Mapping( 1, 1, 3, 1 );
      sendRegistrationRPCMessageToPortMapper(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        mapping                                    );

      registeredOK =
        receiveRegistrationConfirmationRPCMessageFromPortMapper();

System.out.println( "\n\nrun: registeredOK=" + registeredOK );

      mapping = new Mapping( 1, 1, 4, 1 );
      sendRegistrationRPCMessageToPortMapper(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        mapping                                    );

      registeredOK =
        receiveRegistrationConfirmationRPCMessageFromPortMapper();

System.out.println( "\n\nrun: registeredOK=" + registeredOK );

      mapping = new Mapping( 1, 1, 5, 1 );
      sendRegistrationRPCMessageToPortMapper(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        mapping                                    );

      registeredOK =
        receiveRegistrationConfirmationRPCMessageFromPortMapper();

System.out.println( "\n\nrun: registeredOK=" + registeredOK );

      mapping = new Mapping( 1, 2, 2, 1 );
      sendRegistrationRPCMessageToPortMapper(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        mapping                                    );

      registeredOK =
        receiveRegistrationConfirmationRPCMessageFromPortMapper();

System.out.println( "\n\nrun: registeredOK=" + registeredOK );

      mapping = new Mapping( 1, 2, 3, 1 );
      sendRegistrationRPCMessageToPortMapper(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        mapping                                    );

      registeredOK =
        receiveRegistrationConfirmationRPCMessageFromPortMapper();

System.out.println( "\n\nrun: registeredOK=" + registeredOK );

      mapping = new Mapping( 1, 2, 4, 1 );
      sendRegistrationRPCMessageToPortMapper(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        mapping                                    );

      registeredOK =
        receiveRegistrationConfirmationRPCMessageFromPortMapper();

System.out.println( "\n\nrun: registeredOK=" + registeredOK );

      mapping = new Mapping( 1, 2, 5, 1 );
      sendRegistrationRPCMessageToPortMapper(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        mapping                                    );

      registeredOK =
        receiveRegistrationConfirmationRPCMessageFromPortMapper();

System.out.println( "\n\nrun: registeredOK=" + registeredOK );

      mapping = new Mapping( 1, 3, 2, 2 );
      sendRegistrationRPCMessageToPortMapper(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        mapping                                    );

      registeredOK =
        receiveRegistrationConfirmationRPCMessageFromPortMapper();

System.out.println( "\n\nrun: registeredOK=" + registeredOK );

      mapping = new Mapping( 1, 3, 3, 2 );
      sendRegistrationRPCMessageToPortMapper(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        mapping                                    );

      registeredOK =
        receiveRegistrationConfirmationRPCMessageFromPortMapper();

System.out.println( "\n\nrun: registeredOK=" + registeredOK );

      mapping = new Mapping( 2, 3, 1, 1 );
      sendRegistrationRPCMessageToPortMapper(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        mapping                                    );

      registeredOK =
        receiveRegistrationConfirmationRPCMessageFromPortMapper();

System.out.println( "\n\nrun: registeredOK=" + registeredOK );

      mapping = new Mapping( 3, 3, 3, 3 );
      sendRegistrationRPCMessageToPortMapper(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        mapping                                    );

      registeredOK =
        receiveRegistrationConfirmationRPCMessageFromPortMapper();

System.out.println( "\n\nrun: registeredOK=" + registeredOK );

      mapping = new Mapping( 3, 4, 3, 3 );
      sendRegistrationRPCMessageToPortMapper(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        mapping                                    );

      registeredOK =
        receiveRegistrationConfirmationRPCMessageFromPortMapper();

System.out.println( "\n\nrun: registeredOK=" + registeredOK );

      mapping = new Mapping( 5, 5, 5, 5 );
      sendRegistrationRPCMessageToPortMapper(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        mapping                                    );

      registeredOK =
        receiveRegistrationConfirmationRPCMessageFromPortMapper();

System.out.println( "\n\nrun: registeredOK=" + registeredOK );

      sendDumpRequestRPCMessageToPortMapper(
        nfs.Constants.INITIAL_TRANSACTION_ID );

      receiveDumpRPCMessageFromPortMapperAndPrintOut(
        Constants.N_MAPPINGS_MAX_DUMP_TO_GET          );


      udpSocket.close();

  }
/*end of run*/


  public
  static
  void

  main( String[] args )
/*****************************************************************************/
/* Function name: main                                                       */
/* File name: TestClient.java                                                */
/* Purpose: main method for the TestClient class                             */
/* Parameters: agrument strings array                                        */
/* Returns:                                                                  */
/* Last modified: 10.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      TestClient test = null;
                                                          /* main */
/*---------------------------------------------------------------------------*/

      try
        {
          test = new TestClient( Constants.PROPERTIES_FILE_PATH );
        }
      catch( SocketException e )
        {
          System.out.println(
            "can\'t create io.UdpSocket: " +
            e.getMessage()                      );
          System.exit( 1 );
        }
    /*end of try-catch*/

      test.run();
      System.exit( 0 );

    }
/*end of main*/


} /* end of TestClient class */

/*****************************************************************************/
/* End of file: TestClient.java                                              */
/*****************************************************************************/
