*********************************************************************
*
* 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