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