Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!seismo!gatech!bloom-beacon!oberon!cit-vax!ucla-cs!zen!ucbvax!sitvxb!dstevens From: dstevens@sitvxb (David L Stevens) Newsgroups: comp.os.vms Subject: Help with a Kernal mode macro program Message-ID: <870708122836.001@sitvxb> Date: Wed, 8-Jul-87 12:29:44 EDT Article-I.D.: sitvxb.870708122836.001 Posted: Wed Jul 8 12:29:44 1987 Date-Received: Sun, 12-Jul-87 10:45:03 EDT Sender: daemon@ucbvax.BERKELEY.EDU Distribution: world Organization: The ARPA Internet Lines: 272 Greetings, I am trying to modify FINGER to go out and get the Server and Port name from the UCB blocks for the LAT device, we are using LAT-Plus. I have below the code that I use, the problem I am having is that the MOVC3 statement in the Kernal Mode code, crashes the system every time I run it. If I take out the MOVC3 statements, and run the program the Length of the port string, the length of the Server string are retrieved no problem. Also I checked, and R8 does point at the beginning of the LAT information area in the UCB block. If anyone can tell me what I am doing wrong here please let me know, I'm stumpted. Remember this is KERNAL Mode code that is broken, and as such will crash the system, and requires CMKRNL priv, so be carefull when you test it/(hopfully) fix it. ------------------------------------------------------------------------------ LAT_PLUS_INFO.MAR .title lat_plus_info ;;; lat_info - get information about LAT terminals (privileged) ;++ ; Module : LAT_INFO.MAR ; Author : David L. Stevens ; Stevens Institute of Technology ; ; This module was based on the TTUCB.MAR file of the Finger system. I ; gratefully thank the author of that program for the help that it ; gave me while hacking out this program. This program requires ; CMKRNL privileges to run. It will retrieve the Server name, the ; Server Port Number and the Server's Ethernet address. Hopefully ; DEC will not modify the format of a LAT Plus UCB and destroy the offsets. ; ; revision history: ; ; 7-July-1987 Create this Module. [DLS] ; ;-- .library /sys$library:lib.mlb/ $ucbdef $ddbdef $ipldef $ttyucbdef ; ; Useful constants ; num_args = 4 ;; Number of arguments ap_numb = 4 ;; Offset to unit number ap_name = 8 ;; Offset to return buff addr ap_port = 12 ;; Offset to return port buffer ap_eth = 16 ;; Offset to return eth buffer ucb$b_srv_info = ^x134 ;; offset in UCB to server info srv_info_port = 1 srv_info_name = 2 ;; ;; LAT_INFO ;; ;; this routine is called to get information about a specified lat line ;; ;; r2 - LTA device number to get info on ;; r3 - Pointer to return buffer for the Server name ;; r4 - Pointer to return buffer for the Server port ;; r5 - Pointer to return buffer for the Server ethernet address ;; r6 - Scratch ;; .entry lat_info,^Mcmpl #num_args,(ap) ; need this many arguments beql 10$ ; branch if correct movl #ss$_badparam,r0 ; setup error status ret ; go give him the bad news 10$: clrl eth_addr ; Clear out the -- clrw eth_addr+4 ; -- ethernet addr buffer clrb srv_name_len ; Clear out the server name len clrb port_len ; Clear out the port # buff $lkwset_s inadr=lock1 ; lock routine into working set cmpl #ss$_wasclr,r0 ; did we lock the pages? beql 20$ ; branch if so cmpl #ss$_wasset,r0 ; were they already locked? bneq err ; if not, then error 20$: movw ap_numb(ap),unit_numb ; Get the needed unit number $cmkrnl_s routin=latinfkrn ; do the privileged stuff movl r0,r6 ; save status for later $ulwset_s inadr=lock1 ; unlock kernel routine cmpl #ss$_wasclr,r0 ; did we unlock the pages? beql info ; branch if so cmpl #ss$_wasset,r0 ; were they already unlocked? beql info ; branch if so err: ret ; ERROR; that's all folks! info: tstb srv_name_len beql 40$ movl ap_name(ap),r3 ; Get the return name buf addr movc3 srv_name_len,srv_name_str,(r3) 40$: tstb port_len beql 50$ movl ap_port(ap),r4 ; Get the return port buf addr movc3 port_len,port_numb,(r4) 50$: tstl eth_addr beql 60$ movl ap_eth(ap),r5 ; Get the return eth-adr buf adr movl eth_addr,(r5) movw eth_addr+4,4(r5) 60$: movl r6,r0 ret ; that's all folks! ; ; Descriptor used to lock kernel routine into our working set ; lock1: .address latinfkrn .address latinfkrnend ;; ;; LATINFKRN ;; ;; Entry point for the privileged search and slurp. The following ;; registers are used: ;; ;; r0 - return status ;; r6 - Port Buffer ;; r7 - Server name buffer ;; r8 - Start address of LAT Plus Info ;; r9 - address of current LAT UCB ;; r10 - address of current DDB ;; .entry latinfkrn,^M jsb sch$iolockr ;; lock io data base for read dsbint #ipl$_synch ;; raise ipl while mucking... ;; ;; First we need to search the DDB's for the one for the desired device ;; movl ioc$gl_devlist,r10 ;; ddb list in r10 movl #port_numb, r6 ;; Port buffer address movl #srv_name_str, r7 ;; Server name buffer address brb jump1 ;; jump into middle loop loop1: movl ddb$l_link(r10),r10 ;; look at next ddb jump1: beql finish ;; already did last controller cmpc3 #3,dev_name,ddb$t_name+1(r10) ;; Is it an LTA DDB ??? bneq loop1 ;; No try for the next one. ;; ;; Now we traverse down the string of UCB's for the correct unit ;; movl ddb$l_ucb(r10),r9 ;; fetch first ucb for this ddb brb jump2 ;; jump into innermost loop loop2: movl ucb$l_link(r9),r9 ;; look at next ucb jump2: beql finish ;; no more units left cmpw unit_numb,ucb$w_unit(r9) ;; is this the right unit number bneq loop2 ;; next ucb if not ;; ;; Establish a pointer to the beginning of the LAT Plus Data ;; addl3 #ucb$b_srv_info, r9, r8 ;; ;; Now we get the information we need about the LAT line ;; movzbw (r8), port_len ;; Get the length of port string beql srvinf ;; If Zero length then branch ;; ;; Move the data into the storage area ;; movc3 port_len, srv_info_port(r8), (r6) ;; ;; Get the Server name information ;; srvinf: addl2 port_len, r8 ;; Offset to srv name length ;; ;; Get the length of the string ;; movzbw srv_info_port(r8), srv_name_len beql finish ;; If Zero length then branch ;; ;; Get the data ;; ;; movc3 srv_name_len, srv_info_name(r8), (r7) ;; ;; Now set up for a return ;; finish: jsb sch$iounlock ;; unlock io data base enbint ;; restore ipl movl #ss$_normal,r0 ;; set up normal return ret ;; back to user mode ;; ;; Storage locations ;; dev_name: .asciz "LTA" ;; Generic device name unit_numb: .blkw 1 ;; Current unit number port_len: .blkw 1 ;; Length of port string port_numb: .blkb 16 ;; Remote port string srv_name_len: .blkw 1 ;; Length of server name string srv_name_str: .blkb 16 ;; Server name string eth_addr: .blkw 3 ;; Servers Ethernet Address latinfkrnend: ;; end of locked memory .end ------------------------------------------------------------------------------- TEST.C #include main() { char name[20]; char port[20]; int ether[2]; int i = 0; ether[0] = 0; ether[1] = 0; for (;i<20;i++) { name[i] = NULL; port[i] = NULL; } lat_info(1,&name[0], &port[0], ðer[0]); printf(" LTA1, Server name %s, port %s, ether %x%x. \n", name, port, ether[0],ether[1]); } ------------------------------------------------------------------------------- The command to link the programs together is: $ LINK TEST,LAT_PLUS_INFO,SYS$SYSTEM:SYS.STB/SELECT Any and all help will be gratefully appreciated. - Thanx - Dave Stevens - Systems Programmer - Stevens Institute of Technology - Address: BITnet: DSTEVENS@SITVXA ARPAnet: DSTEVENS%SITVXA.BITNET@WISCVM.ARPA CCnet: SITVXA::DSTEVENS