********************************************************************* * * I255604 * * 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=SETSOCKOPT - set socket options * EZASMI TYPE=BIND - bind server socket to a port * EZASMI TYPE=GETSOCKNAME - get bound port number * EZASMI TYPE=LISTEN - make backlog queue for incoming conections * *********************************************************************** * * on entry, * register 1 points to the API parameters. * *...................................................................... * * on completion, * register 15 will contain a return code (RC): * * RC=0 - normal completion (always) * *********************************************************************** ********************************************************************** * I255604 CSECT I255604 AMODE ANY I255604 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,'I255604: 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 * *********************************************************************** *********************************************************************** * * SETSOCKOPT - set options for server socket * * We are going to use the SO_LINGER option. * This option enables us to specify how long TCP will linger * on the server socket after CLOSE. * "LINGER" means that the socket will remain in use for a * certain period of time after the CLOSE. * * If we don't set a LINGER time then TCP will assume a long * LINGER time during which the server socket will remain * "in use" for about two minutes after the CLOSE. * If this server program is restarted within these two minutes * then it would get an error code 48 ("socket in use") when it * attempts to BIND the same socket again. * * Since this program does not send data over the server socket * there is no need for TCP to linger after CLOSE. Therefore, * we will set the linger time to 1 second, which is the shortest * time that can be specified. * (We can not specify 0 seconds because 0 means "use default") * * A100 EQU * LEMTRACE 0,'I255604: SETSOCKOPT' * * set OPTLEN - length of LINGER value MVC DSA_OPTLEN,=F'8' length of LINGER value * * set OPTVAL - LINGER value MVC DSA_OPTVAL_ONOFF,=F'1' enable LINGER time MVC DSA_OPTVAL_LINGER,=F'1' linger for 1 seconds * EZASMI TYPE=SETSOCKOPT, X TASK=(TIE), TASK storage (TIE) X S=API_SERVER_SOCKET, server socket X OPTNAME='SO_LINGER', set LINGER value X OPTLEN=DSA_OPTLEN, length of LINGER value X OPTVAL=DSA_OPTVAL, LINGER value 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 * *...................................................................... * * SETSOCKOPT failed (ERROR exit) A110 EQU * LEMTRACE 0,'I255604: SETSOCKOPT failed - ERROR exit' B A190 * *...................................................................... * * 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,'I255604: SETSOCKOPT failed - ERRNO=',(DSA_ERRNO,4,B) B A190 * *...................................................................... * * successful A130 EQU * LEMTRACE 0,'I255604: SETSOCKOPT successful' * *...................................................................... * A190 EQU * * *********************************************************************** *********************************************************************** * * BIND server socket to the port * B100 EQU * LEMTRACE 0,'I255604: BIND' * * initialize BIND parameters (socket address structur) MVC DSA_NAME_FAMILY,=H'2' FAMILY=2 (TCP) MVC DSA_NAME_PORT,API_BIND_PORT PORT MVC DSA_NAME_IP,API_BIND_IP IP-address MVC DSA_NAME_RESERVED,=D'0' reserved but not used * EZASMI TYPE=BIND, X TASK=(TIE), TASK storage (TIE) X S=API_SERVER_SOCKET, server socket X NAME=DSA_NAME, port and IP-address 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 * *...................................................................... * * BIND failed (ERROR exit) B110 EQU * LEMTRACE 0,'I255604: BIND failed - ERROR exit' B X100 * *...................................................................... * * 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,'I255604: BIND failed - ERRNO=',(DSA_ERRNO,4,B) B X100 * *...................................................................... * * successful B130 EQU * LEMTRACE 0,'I255604: BIND successful' * *********************************************************************** *********************************************************************** * * GETSOCKNAME to discover port * C100 EQU * LEMTRACE 0,'I255604: GETSOCKNAME' * EZASMI TYPE=GETSOCKNAME, X TASK=(TIE), TASK storage (TIE) X S=API_SERVER_SOCKET, server socket X NAME=DSA_NAME, port and IP-address X RETCODE=DSA_RETCODE, -1 (error) or 0 (successful) X ERRNO=DSA_ERRNO, error number (if RETCODE = -1) X ERROR=C110 if API error occurs B C120 * *...................................................................... * * BIND failed (ERROR exit) C110 EQU * LEMTRACE 0,'I255604: GETSOCKNAME failed - ERROR exit' B X100 * *...................................................................... * * if DSA_RETCODE is -1 then DSA_ERRNO contains the error code C120 EQU * * L R15,DSA_RETCODE R15 = RETCODE C R15,=F'-1' RETCODE = -1? BNE C130 no; successful * *...................................................................... * * unsuccessful * DSA_ERRNO contains the error code LEMTRACE 0,'I255604: GETSOCKNAME failed - ERRNO=',(DSA_ERRNO,4,B) B X100 * *...................................................................... * * successful C130 EQU * LEMTRACE 0,'I255604: GETSOCKNAME successful' * * TRACE **** LEMTRACE 0,'I255604: BIND=',(DSA_NAME,16,X) LEMTRACE 0,'I255604: PORT=',(DSA_NAME_PORT,2,B) * * copy IP-address and port number to API MVC API_BOUND_IP,DSA_NAME_IP MVC API_BOUND_PORT,DSA_NAME_PORT * *********************************************************************** *********************************************************************** * * LISTEN - create connection queue * D100 EQU * LEMTRACE 0,'I255604: LISTEN' * EZASMI TYPE=LISTEN, X TASK=(TIE), TASK storage (TIE) X S=API_SERVER_SOCKET, server socket X BACKLOG=API_BACKLOG, backlog incoming connections 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 * *...................................................................... * * LISTEN failed (ERROR exit) D110 EQU * LEMTRACE 0,'I255604: LISTEN failed - ERROR exit' B X100 * *...................................................................... * * 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,'I255604: LISTEN failed - ERRNO=',(DSA_ERRNO,4,B) B X100 * *...................................................................... * * successful D130 EQU * LEMTRACE 0,'I255604: LISTEN successful' * *********************************************************************** *********************************************************************** * * call I255605 passing API * LR R1,API L R15,=V(I255605) BASR R14,R15 * *********************************************************************** ********************************************************************** * * return to caller X100 EQU * LEMTRACE 0,'I255604: exit' LEMEXIT * ********************************************************************* ********************************************************************** * * 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) * *...................................................................... * * the following fields are used by SETSOCKOPT: * DSA_OPTLEN DS F length of OPTVAL (8) * DSA_OPTVAL DS 0F OPTVAL (LINGER value) DSA_OPTVAL_ONOFF DS F nonzero value means ON DSA_OPTVAL_LINGER DS F linger time (1 second) * *...................................................................... * * the following fields are used by BIND: * DSA_NAME DS 0XL16 DSA_NAME_FAMILY DS H FAMILY=2 (TCP) DSA_NAME_PORT DS H PORT number DSA_NAME_IP DS F IP_ADDRESS=0.0.0.0 (any) DSA_NAME_RESERVED DS XL8 reserved but not used * *...................................................................... * 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_BOUND_IP DS XL4 IP-address of server from GETSOCKETNAME API_BOUND_PORT DS H port bound to server from GETSOCKETNAME * *********************************************************************** END