Source code of HPW routine I255605

Server program that runs on Host

 

*********************************************************************
*
*                                I255605
*
*                        TCP/IP Password Server
*
*             Written by William van den Heuvel, 1998
*
*             Update: 1998-11-10
*
*********************************************************************
*
* This program is a TCP/IP server that listens on port x.
*
* It provides Password services submitted by the client program.
* The client is a program that may run on any platform that
* supports TCP/IP.
* The client program submits the request by sending a TCP/IP message
* to port x. The server listens on this port and returns a reply.
*
***********************************************************************
*
* this program uses the EZASMI assembler macro API:
* EZASMI TYPE=ACCEPT      - bind server socket to a port
* EZASMI TYPE=READ
* EZASMI TYPE=WRITE
*
***********************************************************************
*
* on entry,
* register 1 points to the API parameters.
*
*......................................................................
*
* on completion,
* register 15 will contain a return code (RC):
*
* RC=0 - normal completion (always)
*
***********************************************************************




**********************************************************************
*
I255605  CSECT
I255605  AMODE ANY
I255605  RMODE ANY
*
R0       EQU   0
R1       EQU   1
R2       EQU   2
R3       EQU   3
R4       EQU   4
R5       EQU   5
R6       EQU   6
R7       EQU   7
R8       EQU   8
R9       EQU   9
R10      EQU   10   PARM - address of pointer to PARM-string)
R11      EQU   11   BASE - base register of this program
R12      EQU   12   CAA  - reserved for LE
R13      EQU   13   DSA  - Dynamic Storage Area
R14      EQU   14   return address
R15      EQU   15   entry point address
*
DSA      EQU   R13
CAA      EQU   R12
BASE     EQU   R11
API      EQU   R10        API parameters
GWA      EQU   R9         GLOBAL storage
TIE      EQU   R8         TASK storage
*
         USING API_DSECT,API
         USING DSA_DSECT,DSA
         USING GWA_DSECT,GWA
         USING TIE_DSECT,TIE
*
*********************************************************************



*********************************************************************
*
         LEMENTRY BASE=BASE,LENGTH=DSA_DSECT_LENGTH,PARAM=API TRACE=0
*
* note:
*        API -> API_DSECT
*        DSA -> DSA_DSECT
*
***********************************************************************


***      LEMTRACE 0,'I255605: entry'


***********************************************************************
*
*        get GLOBAL storage (GWA)
         L     GWA,API_GWA         get pointer to GWA
*
*        get TASK storage (TIE)
         L     TIE,API_TIE         get pointer to TIE
*
***********************************************************************






***********************************************************************
*
*        ACCEPT first incoming connection on the queue
*        If there are no connections (no backlog) then
*        we go in a wait state until a connection arrives.
*
A100     EQU   *
***      LEMTRACE 0,'I255605: issue ACCEPT'
         LEMTRACE 0,'I255605: Waiting for connection...'
*
         EZASMI TYPE=ACCEPT,                                           X
               TASK=(TIE),                 TASK storage (TIE)          X
               S=API_SERVER_SOCKET,        server socket               X
               NAME=DSA_NAME,         socket address structure         X
               RETCODE=DSA_RETCODE,   -1 (error) or 0 (successful)     X
               ERRNO=DSA_ERRNO,       error number (if RETCODE = -1)   X
               ERROR=A110             if API error occurs
         B     A120
*
*......................................................................
*
*        ACCEPT failed (ERROR exit)
A110     EQU   *
         LEMTRACE 0,'I255605: ACCEPT failed - ERROR exit'
         B     X100
*
*......................................................................
*
*        if DSA_RETCODE is -1 then DSA_ERRNO contains the error code
A120     EQU   *
*
         L    R15,DSA_RETCODE    R15 = RETCODE
         C    R15,=F'-1'         RETCODE = -1?
         BNE  A130               no; successful
*
*......................................................................
*
*        unsuccessful
*        DSA_ERRNO contains the error code
         LEMTRACE 0,'I255605: ACCEPT failed - ERRNO=',(DSA_ERRNO,4,B)
         B     X100
*
*......................................................................
*
*        successful
A130     EQU   *
***      LEMTRACE 0,'I255605: ACCEPT successful'
*
*......................................................................
*
*        get client socket
         ICM   R15,B'1111',DSA_RETCODE (fullword)
         STCM  R15,B'0011',API_CLIENT_SOCKET  (halfword)
*
*......................................................................
*
*        copy IP-address and port number of client to API
         MVC   API_CLIENT_IP,DSA_NAME_IP
         MVC   API_CLIENT_PORT,DSA_NAME_PORT
*
*......................................................................
*
*        TRACE
*
*        trace IP-address of client
         XR   2,2
         IC   2,API_CLIENT_IP+0
         XR   3,3
         IC   3,API_CLIENT_IP+1
         XR   4,4
         IC   4,API_CLIENT_IP+2
         XR   5,5
         IC   5,API_CLIENT_IP+3
*
         LEMTRACE 0,'I255605: CLIENT_IP=',                             X
               (2,B),'.',(3,B),'.',(4,B),'.',(5,B)
*
*
*        trace port number of client
***      LEMTRACE 0,'I255605: CLIENT_PORT=',(API_CLIENT_PORT,2,B)
*
***********************************************************************






***********************************************************************
*
*        READ request message from client
*
B100     EQU   *
***      LEMTRACE 0,'I255605: READ'
*
         EZASMI TYPE=READ,                                             X
               TASK=(TIE),                 TASK storage (TIE)          X
               S=API_CLIENT_SOCKET,          client socket             X
               NBYTE=REQUEST_BUFFER_SIZE,    buffer length             X
               BUF=API_REQUEST_MESSAGE,      read buffer               X
               RETCODE=DSA_RETCODE,   -1 (error) or 0 (successful)     X
               ERRNO=DSA_ERRNO,       error number (if RETCODE = -1)   X
               ERROR=B110             if API error occurs
         B     B120
*
*......................................................................
*
*        READ failed (ERROR exit)
B110     EQU   *
         LEMTRACE 0,'I255605: READ failed - ERROR exit'
         B     E100
*
*......................................................................
*
*        if DSA_RETCODE is -1 then DSA_ERRNO contains the error code
B120     EQU   *
*
         L    R15,DSA_RETCODE    R15 = RETCODE
         C    R15,=F'-1'         RETCODE = -1?
         BNE  B130               no; successful
*
*......................................................................
*
*        unsuccessful
*        DSA_ERRNO contains the error code
         LEMTRACE 0,'I255605: READ failed - ERRNO=',(DSA_ERRNO,4,B)
         B     E100
*
*......................................................................
*
*        successful
B130     EQU   *
***      LEMTRACE 0,'I255605: READ successful'
*
*        get length of received reply
*        RETCODE contains the number of bytes received
         MVC API_REQUEST_LENGTH,DSA_RETCODE
*
*        if REQUEST_LENGTH = 0 then the connection is closed (no data)
*        if REQUEST_LENGTH > 0 then we have received data
*
*        check if we have received data
         L   R15,API_REQUEST_LENGTH
         LTR R15,R15         any data?
         BNZ  B140           yes
*
*        connection was closed without any data
***      LEMTRACE 0,'I255605: no request received (connection closed)'
         B     E100
*
*......................................................................
*
*        reply message received
B140     EQU   *
*        API_REQUEST_LENGTH  contains the length of the message
*        API_REQUEST_MESSAGE contains the text of the message
*
***********************************************************************






***********************************************************************
*
*        call I255606 to process the request
*
*        init SHUTDOWN flag to 0
         MVI  DSA_SHUTDOWN,X'00'
*
*        I255606 expects two parameters:
*        param 1: pointer to API_REQUEST
*        param 2: pointer to API_REPLY
*
*        make param for I255606
         LA    R14,API_REQUEST       pointer 1: API_REQUEST
         LA    R15,API_REPLY         pointer 2: API_REPLY
         STM   R14,R15,DSA_I255606
*
*        call I255606
         LA    R1,DSA_I255606
         L     R15,=V(I255606)
         BASR  R14,R15
*
*        if return code in register 15 is not 0
         LTR   R15,R15
         BZ    D100
*
*        then set DSA_SHUTDOWN to non-zero
         MVI  DSA_SHUTDOWN,X'FF'
         LEMTRACE 0,'I255605: SHUTDOWN'
*
***********************************************************************



***********************************************************************
*
*        WRITE reply message to client
*
D100     EQU   *
***      LEMTRACE 0,'I255605: WRITE'
*
         EZASMI TYPE=WRITE,                                            X
               TASK=(TIE),                 TASK storage (TIE)          X
               S=API_CLIENT_SOCKET,          client socket             X
               NBYTE=API_REPLY_LENGTH,       reply message length      X
               BUF=API_REPLY_MESSAGE,        reply message             X
               RETCODE=DSA_RETCODE,   -1 (error) or 0 (successful)     X
               ERRNO=DSA_ERRNO,       error number (if RETCODE = -1)   X
               ERROR=D110             if API error occurs
         B     D120
*
*......................................................................
*
*        WRITE failed (ERROR exit)
D110     EQU   *
         LEMTRACE 0,'I255605: WRITE failed - ERROR exit'
         B     E100
*
*......................................................................
*
*        if DSA_RETCODE is -1 then DSA_ERRNO contains the error code
D120     EQU   *
*
         L    R15,DSA_RETCODE    R15 = RETCODE
         C    R15,=F'-1'         RETCODE = -1?
         BNE  D130               no; successful
*
*......................................................................
*
*        unsuccessful
*        DSA_ERRNO contains the error code
         LEMTRACE 0,'I255605: WRITE failed - ERRNO=',(DSA_ERRNO,4,B)
         B     E100
*
*......................................................................
*
*        successful
D130     EQU   *
***      LEMTRACE 0,'I255605: WRITE successful'
*
***********************************************************************





***********************************************************************
*
*        close client socket
*
E100     EQU   *
***      LEMTRACE 0,'I255605: CLOSE'
*
*        The socket number of the server is in API_SERVER_SOCKET
*
         EZASMI TYPE=CLOSE,                                            X
               TASK=(TIE),            TASK storage (TIE)               X
               S=API_CLIENT_SOCKET,   client socket                    X
               RETCODE=DSA_RETCODE,   return code (0 or -1)            X
               ERRNO=DSA_ERRNO,       error number (if RETCODE = -1)   X
               ERROR=E110             if API error occurs
         B     E120
*
*......................................................................
*
*        CLOSE failed (ERROR exit)
E110     EQU   *
         LEMTRACE 0,'I255605: close failed - ERROR exit'
         B     F100
*
*......................................................................
*
*        if RETCODE is -1 (error) then ERRNO contains the error code
*        else RETCODE contains the socket descriptor
E120     EQU   *
*
*        error?
         L    R15,DSA_RETCODE    R15 = RETCODE
         C    R15,=F'-1'         RETCODE = -1?
         BNE  E130               no; successful
*
*......................................................................
*
*        unsuccessful
*        ERRNO contains the error code
         LEMTRACE 0,'I255605: CLOSE failed - ERRNO=',(DSA_ERRNO,4,B)
         B     F100
*
*......................................................................
*
*        successful
E130     EQU   *
*
*        CLEAR socket descriptor
         XR   R15,R15
         STCM R15,B'0011',API_CLIENT_SOCKET
*
*......................................................................
*
*        TRACE
***      LEMTRACE 0,'I255605: Client SOCKET=',(API_CLIENT_SOCKET,2,B)
*
***********************************************************************



**********************************************************************
*
*        SHUTDOWN?
*
F100     EQU   *
*
*        if DSA_SHUTDOWN is zero
*        then go back to ACCEPT   (no shutdown)
*        else return to caller    (shutdown)
*
         CLI  DSA_SHUTDOWN,X'00'
         BE   A100
*
***********************************************************************






**********************************************************************
*
*        return to caller
X100     EQU *
***      LEMTRACE 0,'I255605: exit'
         LEMEXIT
*
*********************************************************************


* size of buffer for READ (maximum length of request message)
REQUEST_BUFFER_SIZE  DC F'80'





**********************************************************************
*
*  GWA   Global Work Area
*
GWA_DSECT EZASMI TYPE=GLOBAL,STORAGE=DSECT
*
*********************************************************************





**********************************************************************
*
*  TIE   Task Work Area
*
TIE_DSECT EZASMI TYPE=TASK,STORAGE=DSECT
*
*********************************************************************




***********************************************************************
*
* DSA - Dynamic Storage Area (pointed to by register 13)
*
DSA_DSECT     LEMDSA
*
*......................................................................
*
DSA_RETCODE       DS   F     return code
*                            0 = successful
*                           -1 = check ERRNO for error code
*
DSA_ERRNO         DS   F     error code (only if RETCODE=-1)
*
*......................................................................
*
                  DS   0D       d-align what follows
DSA_NAME          DS   0XL16
DSA_NAME_FAMILY   DS   H        FAMILY=2 (TCP)
DSA_NAME_PORT     DS   H        client PORT number
DSA_NAME_IP       DS   F        client IP-address
DSA_NAME_RESERVED DS   XL8      reserved but not used
*
*......................................................................
*
* parameters for I255606
*
DSA_I255606         DS  0D   D-align what follows
DSA_I255606_REQUEST DS   A   pointer to API_REQUEST
DSA_I255606_REPLY   DS   A   pointer to API_REPLY
*
*......................................................................
*
DSA_SHUTDOWN      DS  XL1  non-zero means "shutdown"
*                          (otherwise "accept next connection")
*
*......................................................................
*
              DS   0D   D-align what follows
DSA_DSECT_LENGTH EQU  *-DSA_DSECT
*
***********************************************************************
*
* API - parameters passed between modules
* this dsect is address via register API
*
API_DSECT       DSECT
*
* following fields are set by I25560:
API_BIND_IP     DS  XL4  IP-address to listen on (0.0.0.0 means "any")
API_BIND_PORT   DS  H    port number to listen on (0 means "any")
API_MAXSOC      DS  H    maximum number of sockets          for INITAPI
API_BACKLOG     DS  F    backlog queue incoming connections  for LISTEN
*
*......................................................................
*
* following fields are set by I255601:
API_GWA         DS  A    pointer to GLOBAL storage for EZASMI macro
API_TIE         DS  A    pointer to TASK   storage for EZASMI macro
API_MAXSNO      DS  H    highest socket number             from INITAPI
                DS  H    unused
*
*......................................................................
*
* following fields are set by I255602:
API_LOCAL_IP    DS  XL4  IP-address of server            from GETHOSTID
API_LOCAL_NAME  DS  CL26 local hostname (LL-string)    from GETHOSTNAME
*
*......................................................................
*
* following fields are set by I255603:
API_SERVER_SOCKET DS  H    server socket number             from SOCKET
*
*......................................................................
*
* following fields are set by I255604:
API_SERVER_IP     DS  XL4  IP-address of server      from GETSOCKETNAME
API_SERVER_PORT   DS  H    port bound to server      from GETSOCKETNAME
*
*......................................................................
*
* following fields are set by I255605:
*
API_CLIENT_IP     DS  XL4  client IP-address                from ACCEPT
API_CLIENT_PORT   DS  H    client port number               from ACCEPT
API_CLIENT_SOCKET DS  H    client socket                    from ACCEPT
*
API_REQUEST         DS 0F
API_REQUEST_LENGTH  DS F      length of request message        for READ
API_REQUEST_MESSAGE DS CL80   contents of request message      for READ
*
API_REPLY           DS 0F
API_REPLY_LENGTH    DS F      length of reply message         for WRITE
API_REPLY_MESSAGE   DS CL80   contents of reply message       for WRITE
*
***********************************************************************
        END