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