[comp.os.vms] determining remote information for an RTAn: terminal

gkn@A.SDSC.EDU (08/01/87)

Here are some code *fragments* to do what is necessary to grab the remote
node name/address and remote ID for a process which is connected to the
local machine via SET HOST.

These are code fragments only.  They were taken from a much larger program.
They do not represent a complete set of routines, and are intended to serve
as an example of what needs to be done.  Perhaps if I have time or if enough
people pound on me I'll put them together into a routine that someone can
call.

Some of the routines run in kernel mode, thus requiring CMKRNL privilege.
They must link against SYS$SYSTEM:NETDEF.STB and SYS$SYSTEM:SYS.STB.


; NFB to return the node name from a node address

NFB:		.Byte	NFB$C_FC_SHOW	;NFB$B_FCT	 Function = show
		.Byte	1@NFB$V_NOCTX	;NFB$B_FLAGS	 Flags = Don't store search context
		.Byte	NFB$C_DB_NDI	;NFB$B_DATABASE	 Database = Remote node info
		.Byte	NFB$C_OP_EQL	;NFB$B_OPER	 Operation = Match if equal
		.Long	NFB$C_NDI_TAD	;NFB$L_SRCH_KEY	 Search key = "Transformed node address"
		.Long	0		;NFB$L_SRCH2_KEY [no second key]
		.Byte	0		;NFB$B_OPER2	 [no second key]
		.Byte	0		;NFB$B_MBZ1	 Must be zero
		.Word	0		;NFB$W_CELL_SIZE [default cell size]
		.Long	NFB$C_NDI_NNA	;NFB$L_FLDID	 Field 1:  Return node name
		.Long	NFB$C_ENDOFLIST	;	...	 That's all
RET_BUFF:	.Blkb	32		;Network output buffer

	.Page
	.Subtitle	FIND_RT		- Find the remote ID for a DECnet remote terminal

;+
;
; ----- FIND_RT:  Find the remote ID for a DECnet remote terminal
;
;
; This routine will extract the XWB address  out of the UCB for a DECnet
; remote terminal.  From the XWB we will extract the remote node address
; (which we  feed  to NETACP to  find the node  name) and the  remote ID
; string (which is usually the username).
;
; Inputs:
;
;	Kernel mode, $CMKRNL interface
;	PIB	-	Current PIB address
;
; Outputs:
;
;	R0	-	LBS, OK
;	REMOTE_ADDR:	Remote node address
;	REMOTE_ID:	Remote ID string
;
;-

FIND_RT: .Word	^M<R2,R3,R4,R5,R6,R7,R8,R9,R10,R11> ;Here in kernel mode to find the UCB and XWB for a given RT device

	MOVL	PIB,R1			;Address our PIB
	MOVAB	PIB$L_TERMLENG(R1),R1	;Point to device name descriptor
	BSBW	FIND_UCB		;Go hunt down the UCB
	BLBC	R0,10$			;Branch if error

; Obtain the remote node address and remote user ID for this link

	MOVL	UCB$L_RTT_NETWIND(R1),R1     ;Get the XWB address
	MOVZWL	XWB$W_REMNOD(R1),REMOTE_ADDR ;Stash the remote node address
	MOVQ	XWB$T_RID-1(R1),REMOTE_ID    ;Copy all 16 bytes
	MOVQ	XWB$T_RID+7(R1),REMOTE_ID+8  ; of the remote ID

10$:	RSB				;Back to FIND_UCB

	.Page
	.Subtitle	FIND_UCB	- Scan the I/O database

;+
;
; ----- FIND_UCB:  Scan the I/O database
;
;
; This routine is  called  to scan  the I/O  database  to find the UCB
; for a  given device (at present, the only  thing WHOM  looks for are
; terminal UCBs).  This routine  also establishes a co-routine linkage
; with it's caller (using a CALLG instruction) so that the caller owns
; the I/O database MUTEX while futzing with the UCB.
;
; Inputs:
;
;	Kernel mode, JSB interface
;	R1	- Address of the device name descriptor to search for
;
; Outputs:
;
;	R0	- Status (SS$_NORMAL or SS$_NOSUCHDEV)
;	R1	- UCB address if success
;	R4	- PCB address
;
;-

FIND_UCB:				;Ref. label

; Lock the I/O database mutex for read access

	MOVL	G^SCH$GL_CURPCB,R4	;Get my PCB address
	JSB	G^SCH$IOLOCKR		;;Lock the I/O database
	JSB	G^IOC$SEARCHDEV		;;Go find the UCB for the device

; Establish a co-routine linkage with the caller

	JSB	@(SP)+			;;Call the caller back
	PUSHL	R0			;;Save the return code

; Unlock the I/O database mutex

	MOVL	G^SCH$GL_CURPCB,R4	;;Get my PCB address again
	JSB	G^SCH$IOUNLOCK		;;Release the I/O database
	SETIPL	#0			;;Back down to zero, please.
	POPL	R0			;Restore the return code
	RET				;Back to user mode

	.Page
	.Subtitle	GET_NODE	- Ask NETACP for a remote node name

;+
;
; ----- GET_NODE:  Ask NETACP for a remote node name
;
;
; This routine will ask NETACP to translate a given node address into
; a remote node name.
;
; Inputs:
;
;	REMOTE_ADDR:	Remote node address
;
; Outputs:
;
;	NODE_DESC:	Descriptor of the node name
;
;-

GET_NODE:				;Ref. label

	MOVAL	NFB_DESC,R2		;Address the proper NFB
	BSBW	ASK_NETACP		;Go do the QIO
	MOVZWL	RET_BUFF,NODE_DESC	;Stash node name length
	BNEQ	10$			;If NEQ OK

; >HACK ALERT<
;
;	NETACP returns zero  for the length of the node name if we
;	search the  remote  node database  with the address of our
;	own node.  To get our own node name, specify an address of
;	zero (sigh).
;
;	NETACP also returns zero  for the length  of the node name
;	if we specify  an invalid node  address, but  we're immune
;	from that since  we got the address  from the  XWB  in the
;	first place !

	CLRL	REMOTE_ADDR		;Try again with 0
	BSBW	ASK_NETACP		;Ask again
	MOVZWL	RET_BUFF,NODE_DESC	;Stash node name length

10$:	RSB				;Done

	.Page
	.Subtitle	ASK_NETACP	- Do an IO$_ACPCONTROL $QIO

;+
;
; ----- ASK_NETACP:  Do an IO$_ACPCONTROL $QIO
;
;
; This routine will issue an IO$_ACPCONTROL $QIO to NETACP.
;
; Inputs:
;
;	R2	- Address of the NFB descriptor
;
; Outputs:
;
;	R0	- Status from NETACP
;
;-

ASK_NETACP:				;Ref. label

	TSTW	NET_CHAN		;Already know how to talk to NETACP ?
	BNEQ	10$			;If NEQ yes

; Get a path to the network

	$ASSIGN_S CHAN=NET_CHAN,-	;Get a channel
		DEVNAM=NET0		; to NETACP
	BLBC	R0,20$			;Oh well

; Ask NETACP

10$:	MOVAB	KEY_DESC,R0		;Address our key descriptor to maintain PIC
	MOVAB	RET_DESC,R1		;Address our return descriptor to maintain PIC
	$QIOW_S	CHAN=NET_CHAN,-		;Ask NETACP for
		FUNC=#IO$_ACPCONTROL,-	; the desired info
		IOSB=IOSB,-		;I/O status here
		P1=(R2),-		;Address of our NFB descriptor
		P2=R0,-			;Address of our key descriptor
		P4=R1			;Address of our return buffer descriptor
	MOVZWL	IOSB,R0			;Get return status

20$:	RSB				;Done



gkn
--------------------------------------
Arpa:	GKN@SDS.SDSC.EDU
Bitnet:	GKN@SDSC
Span:	SDSC::GKN (27.1)
USPS:	Gerard K. Newman
	San Diego Supercomputer Center
	P.O. Box 85608
	San Diego, CA 92138
AT&T:	619.534.5076