Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_SRC_1_19910112
-
6-1-monitor/ipnidv.mac
There are 5 other files named ipnidv.mac in the archive. Click here to see a list.
; *** Edit 7450 to IPNIDV.MAC by PRATT on 16-Apr-87, for SPR #21374
; Fix up ARP table problems and also create a lock for GHT updating.
;------------------------- Autopatch Tape # 13 -------------------------
; *** Edit 7227 to IPNIDV.MAC by MELOHN on 23-Jan-86 (TCO 6.1.1568)
; Increase ARP portal size so that we can receive ARP msgs from Ultrix QNA
; systems
;------------------------- Autopatch Tape # 12 -------------------------
; UPD ID= 2089, SNARK:<6.1.MONITOR>IPNIDV.MAC.13, 3-Jun-85 14:47:00 by MCCOLLUM
;TCO 6.1.1406 - Update copyright notice.
; UPD ID= 1706, SNARK:<6.1.MONITOR>IPNIDV.MAC.12, 31-Mar-85 13:30:42 by PAETZOLD
;TCO 6.1.1302 - Fix ARPCDS to return the buffer on a send failure.
; UPD ID= 1598, SNARK:<6.1.MONITOR>IPNIDV.MAC.11, 7-Mar-85 15:40:43 by PAETZOLD
;Document BUGxxx's, also turn off IPNDSW.
; UPD ID= 1579, SNARK:<6.1.MONITOR>IPNIDV.MAC.10, 1-Mar-85 15:49:14 by PAETZOLD
;Fix up some comments and typeos found when reading through this module.
;More TCO 6.1.1126 - Do not destroy PI state in IPNDSW stuff and fix section
;problem in NIPSTO.
; UPD ID= 1576, SNARK:<6.1.MONITOR>IPNIDV.MAC.9, 27-Feb-85 16:09:27 by PAETZOLD
;TCO 6.1.1225 - Add IPNDSW stuff and rewrite NIPSTO. Make sure NBQUE
;zero in NIPQUE. Document BUGxxx's
; UPD ID= 1418, SNARK:<6.1.MONITOR>IPNIDV.MAC.8, 29-Jan-85 11:37:27 by PAETZOLD
;TCO 6.1.1158 - Decrease scheduler latency when requesting INTFRK from interrupt context.
; UPD ID= 1415, SNARK:<6.1.MONITOR>IPNIDV.MAC.7, 28-Jan-85 15:12:52 by PAETZOLD
;Remove IPNISC. It was a bad idea.
; UPD ID= 1395, SNARK:<6.1.MONITOR>IPNIDV.MAC.6, 22-Jan-85 22:34:06 by PAETZOLD
;Make IPNISC conditional on NIBUGX
; UPD ID= 1292, SNARK:<6.1.MONITOR>IPNIDV.MAC.5, 9-Jan-85 11:22:14 by PAETZOLD
;Add IPNISC BUGINF in CKSTAT for NISRV reported KLNI state change.
; UPD ID= 1037, SNARK:<6.1.MONITOR>IPNIDV.MAC.4, 12-Nov-84 15:25:17 by PAETZOLD
;TCO 6.1041 - Move ARPANET to XCDSEC
; UPD ID= 306, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.80, 16-Oct-84 16:37:11 by PRATT
;Use INTXPB + CRC bytes for setting input packet size
; UPD ID= 293, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.79, 24-Sep-84 13:56:47 by PURRETTA
;Update copyright notice.
; UPD ID= 280, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.78, 8-Sep-84 14:55:32 by PAETZOLD
;Ping all known Ethernet Internet hosts on network up state change.
; UPD ID= 269, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.77, 5-Sep-84 10:10:42 by PRATT
;Don't lose ARP buffers when port has been closed
; UPD ID= 260, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.76, 28-Aug-84 16:37:51 by PRATT
;Also remove comments about physically contigous buffers
; UPD ID= 259, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.75, 27-Aug-84 11:48:57 by PRATT
;Now that we do BSD style xmits, GETNIB/RETNIB don't use 1822 buffers
; UPD ID= 240, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.74, 22-Aug-84 11:07:46 by PRATT
;Use NISRV's UN block on re-posting an ARP buffer that got an error
; UPD ID= 239, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.73, 21-Aug-84 21:36:16 by PRATT
;Zero UNBNFI/UNBFRI after the UN block free space is released
; UPD ID= 236, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.72, 16-Aug-84 11:26:42 by PAETZOLD
;Fix a typo in the previous edit.
; UPD ID= 234, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.71, 15-Aug-84 16:17:51 by PAETZOLD
;Fix up CBDRCK to work around NISRV deficiency.
; UPD ID= 219, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.70, 18-Jul-84 09:43:41 by PRATT
;Fix typo if datagram too long error (currently we do nothing anyway)
;Don't run NIPSRV if NIPON is off
; UPD ID= 215, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.69, 17-Jul-84 10:12:57 by PRATT
;If IPNI hasn't initialized, don't issue IPUNBP buginfs.
; UPD ID= 212, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.68, 16-Jul-84 17:28:32 by PRATT
;Fix IPDWNS problem with very short packets at the end of a page
; If we have a packet less than the ethernet minimum packet size,
; use a 2 MSD style transmit
;Try to prevent KNIFQE/IPIBLP semi-deadly embrace
;Don't type so many IPIBLP's, buginf only every 4th occurance
;Some systems are sending oversize ARP packets, expand AR.MAX and AR.WRD
;Make sure GHTCT1 is legit when we have bad or non-exsistent ght files
; UPD ID= 211, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.67, 11-Jul-84 14:04:27 by PRATT
;Detect trailer encapsulated datagrams and BUGINF
; UPD ID= 207, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.66, 29-Jun-84 13:41:28 by PRATT
;Fix lost UNPID word caused by multiple UN blocks
;Remove extraneous code in arpupd
; UPD ID= 206, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.65, 28-Jun-84 08:49:24 by PRATT
;Use NIPSHT on line state change when klni went down
;Do a CALL to callback routines and put callback function code on the stack
;Make callback routines skip return or not. If no skip, save error code
;Fix up ARPUPD to use reverse XBLTs to update the GHT
;If error posting an input buffer or when channel is shutting down,
; we can't call RETNIB because it's not resident. Instead place
; the buffer back on queue of free input buffers
;Handle address change callbacks differently:
; . If no arp, shut down ipni by setting NIPSHT
; . If arp, invalidate all ght entries
;Trim excess fat and make code more efficient:
; . Reduce # of ght entries by not putting our hosts info in the ght
; . Handle errors in NISEND slightly different
; . Be more efficient in picking up and checking the ethernet address
; . Found sequences of instructions which could be optimized
; . Do away with arp enabled/disabled messages
; . Do away with IPFERR, it's a thing of the past.
; . Get rid of nifcnt and nipadr
; UPD ID= 200, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.64, 17-Jun-84 20:08:49 by PAETZOLD
;Change NIRELB CALL to a CALLRET in NILCAL.
; UPD ID= 195, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.63, 17-Jun-84 14:28:27 by PAETZOLD
;Fix a typo in the "Tested" code from edit 184.
; UPD ID= 189, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.62, 16-Jun-84 18:29:12 by PAETZOLD
;Do not call NIPRST at datagram callback level since context will be unknown.
;Solution is to set a flag and call NIPRST from INTFRK context in NIPSRV.
; UPD ID= 184, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.61, 15-Jun-84 13:00:40 by PRATT
;Maintain a queue of free UN blocks, remove now unecessary nosked's
;Don't jump to nipkld from nioff
; UPD ID= 183, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.59, 12-Jun-84 13:14:14 by PRATT
;Send all queued output packets at once
;Remove debugging macros
;Put edit 160 back plus some changes to the sequential search code
;Start fixing the cases where the error code gets lost
;Change some PIOFF/PION's to just go NOSKED/OKSKED
;Don't lose ght flags when updating our hosts ethernet address
; UPD ID= 162, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.58, 3-Jun-84 17:26:24 by PAETZOLD
;remove previous edit.
; UPD ID= 160, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.57, 1-Jun-84 21:53:27 by PRATT
;Make some symbols global for IPOPR
;Give additional info on IPIBLP buginfs
;Fix problem with lots of IPRANF buginfs
;Better line state change code
;If # of ght entries is small, do sequential search, not binary
;Fix Intsrc to not loop if ghtcnt is zero
; UPD ID= 154, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.56, 31-May-84 10:58:44 by PAETZOLD
;Do not change NETON. Reflect state changes in NTRDY.
; UPD ID= 146, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.55, 30-May-84 14:24:09 by PAETZOLD
;NIPLKB and NIPULK in IPFREE now. Fix the SUBTTLs.
; UPD ID= 135, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.54, 15-May-84 13:53:45 by PRATT
;Make sure ARP request opcode is set on requests
;It would be nice if I bump ghtcnt after adding a new entry
;Go NOSKED when updating the ght
; UPD ID= 133, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.53, 15-May-84 00:55:19 by PRATT
;Fix NISEND to get the -lclpkt(rid) to pick up the packet length
; UPD ID= 132, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.52, 14-May-84 23:16:59 by PRATT
;Fix ILULK2 bug. Keep other forks from modifying the UN block during transmits.
; UPD ID= 128, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.51, 14-May-84 15:23:11 by PRATT
;Don't return GHT sequence error on number of entries is zero
; UPD ID= 127, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.50, 14-May-84 13:06:08 by PRATT
;Change some rescd's to swapcd's since no longer called during interrupts
;Don't let NIPNFI buffer count go negative if no input buffers
;Same thing goes for ARPNFI if no arp buffers
; UPD ID= 116, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.47, 14-May-84 10:47:48 by PRATT
;No need to preserve T1 in NIPUNB. Define and use GH2MDL. More cleanup.
; UPD ID= 115, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.46, 14-May-84 10:18:40 by PRATT
;Preserve error code over call to nipkil if ght error in restart code
; UPD ID= 114, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.45, 14-May-84 09:07:08 by PRATT
;If no entry for IPNI in Internet.Address file, don't bring net up
; UPD ID= 110, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.44, 12-May-84 18:26:02 by PRATT
;Use different entry point for killing ARP from NIPKIL than from IPOPR
; UPD ID= 109, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.43, 12-May-84 18:13:21 by PRATT
;CLRBLK smashes the acs, call it later in the code in NIHSPC
; UPD ID= 107, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.42, 12-May-84 18:09:34 by PRATT
;If ARPON is on, make ARPINI always succeed (for IPOPR)
;Make ARPKIL global for IPOPR
; UPD ID= 104, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.41, 12-May-84 17:34:09 by PRATT
;Fix ARPUPD to point at insertion point in ght area 2 + entry size
; UPD ID= 93, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.40, 12-May-84 09:50:32 by PRATT
;Leave in hook to send ICMP msg on datagram too long error
;Add ENDxx. macros to close off trvars and stkvars
;Make restart code be more forgiving on ght errors
; UPD ID= 92, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.39, 11-May-84 18:12:13 by PRATT
;Use CLRBLK after calls to GETBLK in various places
; UPD ID= 91, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.38, 11-May-84 16:58:20 by PRATT
;Fix routines which skip return when the callers didn't expect it
; UPD ID= 90, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.37, 11-May-84 16:39:43 by PRATT
;Correct error status does not come from UNSST on callback, use T3 directly
; UPD ID= 89, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.36, 11-May-84 14:14:09 by PRATT
;Fix some typos
; UPD ID= 88, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.35, 11-May-84 14:07:56 by PRATT
;Don't process ARP during interrupt level, let the Internet fork do it
;Make NIPSTO more efficient with it's ac's
; UPD ID= 87, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.34, 10-May-84 16:08:05 by PRATT
;Fix ARP problem that put our ARP buffers in NISRV's portal list
;Use a send buffer during ARP replies, don't re-use the rcv buffer
; UPD ID= 85, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.33, 10-May-84 09:36:18 by PRATT
;Fix "small ght" problem, and general cleanup
; UPD ID= 83, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.32, 9-May-84 13:46:16 by PRATT
;Point at -lclpkt(rid) when calling RETNIB on errors
; UPD ID= 82, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.31, 9-May-84 13:03:45 by PRATT
;Use UNPID not UNPRO in read portal counters
; UPD ID= 81, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.30, 8-May-84 16:03:38 by PRATT
;Fix ARPOST/ARPCDR if post errors
;INTSRC must be resident since it's called during ARP receives
;GETRPC, ARPKIL and ARPBUF can be in swapcd
; UPD ID= 80, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.29, 8-May-84 15:38:27 by PRATT
;Don't call IPFERR if sends fail, datagram not sent buginf will suffice
; UPD ID= 77, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.28, 8-May-84 15:22:49 by PRATT
;Release input buffer if error during post. Count # of buffers posted
; UPD ID= 76, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.27, 7-May-84 16:07:16 by PRATT
;Buffer threshold for 1822 buffers. Don't init NIPNIB from NIPINI
; UPD ID= 73, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.26, 7-May-84 09:35:02 by PRATT
;Better error handling for ght's. If no ght entry for this host, build one
; UPD ID= 72, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.25, 5-May-84 11:48:16 by PRATT
;Remove the debugging code
; UPD ID= 71, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.24, 5-May-84 11:29:11 by PRATT
;Call NIOFF only from NIPKIL, Move NIPHNG to IPFERR
; UPD ID= 70, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.23, 4-May-84 15:48:54 by PRATT
;Set ARPENA from setting in STG
; UPD ID= 69, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.22, 4-May-84 15:45:27 by PRATT
;Even more debugging code for ILULK2's
; UPD ID= 68, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.21, 4-May-84 15:40:53 by PRATT
;Allow GH%DMB, host does not have ARP, use ght address
; UPD ID= 63, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.20, 3-May-84 13:54:13 by PAETZOLD
;IPLTRK calls need IPLDSW control
; UPD ID= 62, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.19, 2-May-84 21:36:18 by PRATT
;Fix gh.gcf, intsrc, nisend, and nipcka for various problems
;Add more debugging code, add prblem macro
; UPD ID= 58, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.18, 2-May-84 13:51:06 by PRATT
;If using ARP, make sure Ethernet address in GHT is valid
; UPD ID= 57, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.17, 2-May-84 12:57:10 by PRATT
;Fix ipferr startup and niplkb/nipulk smashed ac problems
; UPD ID= 48, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.16, 1-May-84 16:05:17 by PRATT
;Fix getblk/retblk problems in NIHINI
; UPD ID= 47, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.15, 1-May-84 15:29:26 by PRATT
;In UNSET, clear 1 location less than UN.LEN
; UPD ID= 46, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.14, 1-May-84 14:59:37 by PRATT
;Use ARPENA, not ARPON in the check ethernet address code
; UPD ID= 44, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.13, 1-May-84 13:26:07 by PRATT
;Add debugging code to NIPSTO, NISEND, and IPCBDS
; UPD ID= 41, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.12, 30-Apr-84 10:34:34 by PRATT
;Fix ILULK2 bughalts if NISRV returns an error in NISEND. More cleanup.
; UPD ID= 40, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.11, 24-Apr-84 14:34:41 by PRATT
;Add read portal counters for ARP
; UPD ID= 39, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.10, 24-Apr-84 13:08:42 by PRATT
;Add Address Resolution Protocol... ARP
; UPD ID= 36, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.9, 10-Apr-84 15:33:10 by PRATT
;Change NIPON from being "off and on" to "off and degrees of on"
; UPD ID= 35, SNARK:<TCPIP.5.4.MONITOR>IPNIDV.MAC.8, 10-Apr-84 13:17:58 by PRATT
;Remove local loopback code. Fix problem with sending to ourself.
;Clean up code. Begin source code control using ALU.
;TCPNI demo'd to management Apr 9, 1984.
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
;OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1976, 1985.
;ALL RIGHTS RESERVED.
SEARCH ANAUNV,PROLOG,NIPAR
TTITLE (IPNIDV,IPNIDV,< - Internet Ethernet Interface>)
IFNDEF REL6,<REL6==1> ; default is release 6
IFNDEF IPNDSW,<IPNDSW==:0> ; default is no nisrv debuging stuff
IF1 <IFN IPNDSW,<PRINTX Assembling Debuging NI queuing routines>>
SALL
.DIRECTIVE FLBLST
SUBTTL Definitions
;Special AC definitions
SRV==Q1 ;TYPE OF SERVICE
ARP==Q2 ;ADDRESS OF ARP PACKET
NCT==P1 ;ADDRESS OF OUR NCT
UNB==P2 ;UN BLOCK ADDRESS
RID==P3 ;REQUEST ID (BUFFER ADDRESS)
CPKT==P3 ;ICMP PACKET POINTER
;Internal error codes for debugging
NI.ER1==610001 ;NIPBFR COULDN'T GET A BUFFER
NI.ER2==610002 ;ETHERNET ADDRESS CHANGED
NI.ER3==610003 ;ILLEGAL NISRV CALLBACK VECTOR
NI.ER5==610005 ;COULDN'T GET A UN BLOCK
NI.ER6==610006 ;COULDN'T GET FREE SPACE FOR PORTAL COUNTERS
NI.ER7==610007 ;GHT FULL, ARP PACKET NOT INSERTED
NI.ER8==610010 ;IPNIDV NOT INITIALIZED YET
NI.ER9==610011 ;KLNI STOPPED FOR SOME REASON
;NI "ON" flags, each successive value implies all of the previous
NI.ON==1 ;Portal open (but not necessarily ready)
NI.RDY==3 ;Interface is ready for use
;Type of service. Used in selecting the UN block, callback dispatches, etc
NI.INT==1 ;INTERNET
NI.ARP==2 ;ARP
NI.TRL==3 ;TRAILER ENCAPSULATED PACKETS
;Ethernet protocol types (UNPRO in UN block)
IPROTO==^D2048 ;INTERNET
APROTO==^D2054 ;ARP
TPROTO==^D4096 ;TRAILER ENCAPSULATED PACKET
TRMAXP==3 ;OPEN PORTALS FOR (0,512,1024) BYTE PACKETS
SUBTTL Miscellaneous Definitions
EMINPL==^D46 ;MINIMUM ETHERNET PACKET LENGTH
MINPKT==EMINPL+4 ;MINIMUM ETHERNET PACKET LENGTH PLUS CRC BYTES
GH.EN1==.NIEN1-1 ;GHTAR2 ETHERNET ADR HIGH ORDER BYTES
GH.EN2==.NIEN2-1 ;GHTAR2 ETHERNET ADR LOW ORDER BYTES
GH.GCF==.NIGCF-1 ;GHTAR2 GATEWAY CONTROL FLAGS
GH2MDL==NIHMDL-1 ;LENGTH OF AN AREA 2 ENTRY
NI.HOP==.NBLD1 ;ROUTING ADRESS IS KEPT IN THE LEADER
SRCMAX==^D10 ;MAX ENTRIES IN GHT BEFORE USING BINARY SEARCH
AR.TNB==^D10 ;GET TOTAL OF 10 ARP BUFFERS
UN.TNB==7 ;GET TOTAL OF 7 UN BLOCKS
MSD1==UN.LEN+1 ;1ST MSD IS AT END OF UN BLOCK
MSD2==MSD1+MD.LEN+1 ;2ND MSD IS AT THE END OF THE 1ST MSD
MS.LEN==<MD.LEN+1>*2 ;SIZE OF BOTH MSD'S TOGETHER
SUBTTL ARP Packet Definitions
ARPQUE==0 ;TYPE AND POINTER OFFSET
ARPPKT==1 ;BEGINNING OF THE ARP PACKET
ARPCRC==7 ;ETHERNET CRC BYTES
DEFSTR ARTYP,ARPQUE,4,1 ;0=SEND BFR, 1=RECEIVE BFR
DEFSTR ARPNT,ARPQUE,35,30 ;POINTER TO NEXT BUFFER
DEFSTR AR$HD,ARPPKT,15,16 ;HARDWARE ADDRESS TYPE
AR.ETH==1 ; ETHERNET IS TYPE 1
DEFSTR AR$PR,ARPPKT,31,16 ;INTERNET PROTOCOL TYPE
DEFSTR AR$HL,ARPPKT+1,7,8 ;BYTE LENGTH OF HARDWARE ADDRESS
AR.HLN==6 ; ETHERNET ADDRESSES ARE 6 BYTES
DEFSTR AR$PL,ARPPKT+1,15,8 ;BYTE LENGTH OF PROTOCOL ADDRESS
AR.PLN==4 ; INTERNET ADDRESSES ARE 4 BYTES
DEFSTR AR$OP,ARPPKT+1,31,16 ;OPCODE
AR.REQ==1 ; REQUEST
AR.REP==2 ; REPLY
DEFSTR AR$S1,ARPPKT+2,31,32 ;SENDER HARDWARE ADDRESS (WORD 1)
DEFSTR AR$S2,ARPPKT+3,15,16 ;SENDER PROTOCOL ADDRESS (WORD 2)
DEFSTR AR$P1,ARPPKT+3,31,16 ;SENDER PROTOCOL ADDRESS (WORD 1)
DEFSTR AR$P2,ARPPKT+4,15,16 ;SENDER PROTOCOL ADDRESS (WORD 2)
DEFSTR AR$R1,ARPPKT+4,31,16 ;TARGET HARDWARE ADDRESS (WORD 1)
DEFSTR AR$R2,ARPPKT+5,31,32 ;TARGET HARDWARE ADDRESS (WORD 2)
DEFSTR AR$TA,ARPPKT+6,31,32 ;TARGET PROTOCOL ADDRESS
DEFSTR ACRC,ARPCRC,31,32 ;CRC (NOT PART OF THE ARP PACKET)
AR.WRD==ARPCRC+2 ;NUMBER OF WORDS IN AN ARP PACKET + 1
AR.LEN==<AR.WRD-2>*4 ;LENGTH IN BYTES OF AN ARP PACKET
AR.MAX==AR.LEN+4 ;MAX BUFFER SIZE MUST INCLUDE CRC
; If AR.LEN is less than MINPKT (Ethernet minimum packet size
; plus 4 bytes for the CRC) we must make the ARP packets atleast
; that size.
IFL AR.LEN-EMINPL,<
AR.WRD==<MINPKT/4>+4 ;WORD SIZE OF ARP PACKET (PLUS A COUPLE)
AR.LEN==EMINPL ;BYTES IN ARP PACKET ARE ETHERNET MINIMUM
;**;[7227] Change 1 line at ARP definitions WCM 14-Jan-86
AR.MAX==MINPKT+20 ;[7227]MAX BFR SIZE WITH ETHERNET CRC (PLUS 20)
>
SUBTTL NI Debuging Stuff
IFN IPNDSW,<
IFE REL6,<RESCD>
IFN REL6,<XRESCD>
RS IPNQUE,1 ;HEAD OF QUEUE OF BUFFERS GIVEN TO NISRV
IPNENQ: ;BUFFER ADDRESS IN T1
SAVET ;SAVE ACS
CONI PI,T4 ;GET PI STATE
PIOFF ;AND STOP THE MACHINE
HRRZS T1 ;ZERO THE LEFT HALF
MOVEI T2,IPNQUE ;GET ADDRESS OF THE HEAD OF THE QUEUE
IPNENL: ;QUEUE CHECKING LOOP
LOAD T2,NBQUE,(T2) ;GET THE NEXT ITEM
JUMPE T2,IPNENN ;NOT FOUND...GOOD
CAMN T1,T2 ;IS THIS OUR ITEM?
BUG.(HLT,IPNHIT,IPNIDV,SOFT,<Already queued buffer being queued to NISRV>,,<
Cause: The monitor has detected an inconsistency in the handling of NISRV
related internet buffers. This is conditional code which is only
enabled during debugging.
>)
SETSEC T2,INTSEC ;SETUP THE CORRECT SECTION
JRST IPNENL ;KEEP LOOKING
IPNENN: ;HERE WHEN THE BUFFER WAS NOT FOUND
LOAD T2,NBQUE,+IPNQUE ;GET THE OLD HEAD
STOR T1,NBQUE,+IPNQUE ;THIS IS THE NEW HEAD
SETSEC T1,INTSEC ;SETUP THE SECTION NUMBER
STOR T2,NBQUE,(T1) ;MAKE THE REST OF THE LIST COME OFF US
TXNE T4,<PIPION> ;WAS PI SYSTEM ON?
PION ;YES SO TURN IT BACK ON
RET ;AND RETURN
IPNDEQ: ;BUFFER ADDRESS IN T1
SAVET ;SAVE ACS
CONI PI,T4 ;GET PI STATE
PIOFF ;AND STOP THE MACHINE
HRRZS T1 ;ZERO THE LEFT HALF
MOVEI T2,IPNQUE ;GET THE HEAD OF THE QUEUE
IPNDEL: ;QUEUE CHECKING LOOP
MOVE T3,T2 ;SAVE THE OLD ITEM
LOAD T2,NBQUE,(T2) ;GET THE NEXT ITEM
SKIPN T2 ;NOT FOUND...BAD
BUG.(HLT,IPNMIS,IPNIDV,SOFT,<Buffer not queued to NISRV being dequeued>,,<
Cause: The monitor has detected an inconsistency in the handling of NISRV
related internet buffers. This is conditional code which is only
enabled during debugging.
>)
CAMN T1,T2 ;IS THIS OUR ITEM?
JRST IPNDEF ;FOUND....GOOD
SETSEC T2,INTSEC ;SETUP THE CORRECT SECTION
JRST IPNDEL ;KEEP LOOKING
IPNDEF: ;HERE WHEN THE ITEM WAS FOUND
SETSEC T2,INTSEC ;SETUP THE SECTION NUMBER
LOAD T2,NBQUE,(T2) ;GET THIS ITEMS QUEUE POINTER
STOR T2,NBQUE,(T3) ;OLD ITEM POINTS TO THIS ITEM
TXNE T4,<PIPION> ;WAS PI SYSTEM ON?
PION ;YES SO TURN IT BACK ON
RET ;AND RETURN
> ;END OF IFN IPNDSW
SUBTTL NISRV Callback Dispatch Tables
IFE REL6,<RESCD>
IFN REL6,<XRESCD>
CBTAB: NCTDSP IPNDSP ;INTERNET
NCTDSP ARPDSP ;ARP
NCTDSP TRLDSP ;TRAILER ENCAPSULATED PACKETS
IFE REL6,<XXXSEC==<MSEC1,,0>>
IFN REL6,<XXXSEC==<XCDSEC,,0>>
;Internet service
IPNDSP: TABBEG NU.OPN,NU.MAX,<XXXSEC!ICBVCT> ;UNKNOWN CALLBACKS BUGCHK
TABENT NU.CLO,<XXXSEC!RSKP> ;CLOSE COMPLETED
TABENT NU.RCV,<XXXSEC!IPCBDR> ;RECEIVED A DATAGRAM
TABENT NU.XMT,<XXXSEC!IPCBDS> ;DATAGRAM SENT
TABENT NU.RPC,<XXXSEC!IPCBRC> ;READ PORTAL COUNTERS
TABENT NU.RCI,<XXXSEC!IPCBLS> ;CHANNEL STATE CHANGE
TABENT NU.SCA,<XXXSEC!IPCBAC> ;ADDRESS CHANGE
TABEND
;Arp service
ARPDSP: TABBEG NU.OPN,NU.MAX,<XXXSEC!ICBVCT> ;UNKNOWN CALLBACKS BUGCHK
TABENT NU.CLO,<XXXSEC!RSKP> ;CLOSE COMPLETED
TABENT NU.RCV,<XXXSEC!ARPCDR> ;RECEIVED A DATAGRAM
TABENT NU.XMT,<XXXSEC!ARPCDS> ;DATAGRAM SENT
TABENT NU.RPC,<XXXSEC!ARPCRP> ;READ PORTAL COUNTERS
TABENT NU.RCI,<XXXSEC!RSKP> ;CHANNEL STATE CHANGE
TABENT NU.SCA,<XXXSEC!RSKP> ;ADDRESS CHANGE
TABEND
;Trailer encapsulation service
TRLDSP: TABBEG NU.OPN,NU.MAX,<XXXSEC!ICBVCT> ;UNKNOWN CALLBACKS BUGCHK
TABENT NU.CLO,<XXXSEC!RSKP> ;CLOSE COMPLETED
TABENT NU.RCV,<XXXSEC!TRLCDR> ;RECEIVED A DATAGRAM
TABENT NU.RCI,<XXXSEC!RSKP> ;CHANNEL STATE CHANGE
TABENT NU.SCA,<XXXSEC!RSKP> ;ADDRESS CHANGE
TABEND
SUBTTL Initialization Routines
;NIPINI - INITIALIZATION
;
; Called from MNTINI when initializing all of the networks known
; to Multinet.
;
; NCT/ NCT address
;
; Returns + 1 always
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
NIPINI::MOVEM NCT,NIPNCT ;SAVE OUR NCT FOR THE CALLBACK ROUTINE
SETZM HSTGDM(NCT) ;CANCEL GOING DOWN MESSAGES
RET
;NICBAK - CALLBACK DISPATCH
;
; Routine that NISRV calls so that we can do a callback
; dispatch for all types of service.
;
; T1/ callback function code
; T2/ address of the UN block
; T3/ 0 if function succesfull or error code
;
; Returns + 1 always
IFE REL6,<RESCD>
IFN REL6,<XRESCD>
NICBAK: SAVEAC <T1,SRV,ARP,RID,NCT,UNB>
LOAD SRV,UNUID,(T2) ;GET USERID
HRRZS SRV ;BUT USE ONLY TYPE OF SERVICE PORTION
ADD T1,CBTAB-1(SRV) ;POINT AT DISPATCH ADDRESS
CALL @-1(T1) ;DISPATCH
MOVEM T1,NIPERR ;ON ERROR - SAVE ERROR CODE AWAY
RET
;Illegal callback vector from NISRV
ICBVCT: BUG. (CHK,IPFBCV,IPNIDV,SOFT,<IPNI: Illegal callback vector>,<<T1,CODE>>,<
Cause: NISRV has passed an illegal or unknown callback vector to the
internet ethernet software.
>)
MOVEI T1,NI.ER3 ;SET UP ERROR
RET
SUBTTL Initialization Routines - Restart
;NIPRST - RESTART
;
; Call here when we want to open the Internet portal.
;
; NCT/ NCT address
;
; Returns + 1 always
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
NIPRST::SKIPN INTON ;HAS INTERNET BEEN INITIALIZED ?
RET ;NO. NOT READY YET.
SKIPG T1,NTLADR(NCT) ;SEE IF WE HAVE HOST NUMBER YET
RET ;NO. NOT READY YET.
SETZM NTTOUT(NCT) ;CLEAR OUTPUT HUNG TIMEOUT
CALL NIRINI ;INITIALIZE US IF NEEDED
JRST NRSTER ;COULDN'T
MOVEI T1,NI.RDY
MOVEM T1,NIPON ;INTERFACE IS READY
AOS NTSTCH(NCT) ;CAUSE CHANGE IN STATE TO BE NOTED
GTAD
MOVEM T1,NTXUPP(NCT) ;SAVE TIME WHEN IT CAME UP
SETOM NTRDY(NCT) ;INDICATE FULLY UP
SETOM NTORDY(NCT) ;ALLOW OUTPUT
SETZM NTOB(NCT) ;NO OUTPUT IN PROGRESS
SKIPN ARPENA ;IS ARP ENABLED ?
IFSKP.
CALL ARPINI ;YES, START IT UP
BUG.(CHK,IPARPE,IPNIDV,SOFT,<ARP did not initialize>,<<T1,ERROR>>,<
Cause: The ethernet ARP (Address resolution protocol) portal did not initialize.
This is probably a temporary resource allocation problem.
>)
ENDIF.
SKIPN TRLENA ;WANT TO ENABLE TRAILER DETECTION ?
IFSKP.
CALL TRLINI ;YES
BUG.(CHK,IPTRLE,IPNIDV,SOFT,<Trailer detection code did not initialize>,<<T1,ERROR>>,<
Cause: The ethernet trailer encapsulation detection portals did not initialize.
This is probably a temporary resource allocation problem.
>)
ENDIF.
CALL INTUP ;INTERFACE IS UP
CALL NIPSTO ;START OUTPUT IF NEEDED
AOS JB0FLG ;NOTE NETWORK CHANGE
CALL WERHER ;TELL EVERYONE THAT WE ARE NOW HERE
RET
;Here to save away the error
NRSTER: MOVEM T1,NIPERR ;SAVE THE ERROR CODE FOR LATER
CALL NIPHNG ;MAKE IT LOOK LIKE THE NI IS SHUTDOWN
RET
SUBTTL Initialization Routines - Driver Initialization
;NIRINI - INITIALIZE THE DRIVER
;
; Called from the network restart code to initialize IPNIDV.
;
; Returns + 1 on error with T1/ error code
; + 2 on success
NIRINI: SAVEAC <UNB,SRV>
SKIPE GHTAR1 ;HOST TABLES INIT'D ?
IFSKP.
CALL NIHINI ;SEE IF WE CAN READ THE GHT
IFNSK.
BUG.(INF,IPHTNI,IPNIDV,SOFT,<Error while reading GHT>,<<T1,ERROR>>,<
Cause: The monitor detected a problem when attempting to read the
SYSTEM:INTERNET-ETHERNET-MAPPINGS.BIN file during initialization.
>)
CAIN T1,IPHNSP ;WAS THERE SPACE FOR THE GHT ?
IFSKP.
SKIPE ARPENA ;YES - ARP GOING TO BE USED ?
JRST RST2 ;YES - ALLOW US TO GO ON
ENDIF.
CALL NIPKIL ;DON'T ALLOW THE INTERFACE TO COME UP
RETBAD ;GET BACK THE ERROR CODE
ENDIF.
ENDIF.
RST2: CALL NIPGIB ;GRAB A BUNCH OF INPUT BUFFERS
MOVE T1,NIPON ;GET "ON" FLAGS
CAIL T1,NI.ON ;PORTAL ALREADY OPEN ?
IFSKP.
CALL NIOPEN ;NO - GO TRY TO OPEN IT
RETBAD ;COULDN'T
ENDIF.
CALL INTUNB ;GET A UN BLOCK
RETBAD ;COULDN'T
CALL NISTAT ;GET THE STATUS OF KLNI
JRST NIRST2 ;ERROR. RELEASE THE UN BLOCK
CALL NIPPIB ;INITIALIZE INPUT BUFFERS
JRST NIRST2 ;ERROR. RELEASE THE UN BLOCK
CALL RETUNB ;RELEASE THE UN BLOCK WE'VE BEEN USING
RETSKP
;Here when we got an error, put the UN block on the free queue
NIRST2: CALL RETUNB ;MAKE UN BLOCK AVAILABLE
RETBAD
SUBTTL Initialization Routines - Open NISRV Portal
;NIOPEN - OPEN NI PORTAL
;
; Called here from the restart code to open a portal
;
; Returns + 1 on error
; + 2 on success
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
NIOPEN: TRVAR <UNBLK>
MOVEI T1,UN.LEN ;RESERVE WORDS FOR A UN BLOCK
CALL GETBLK ;GET THEM
JUMPE T1,[RETBAD <NI.ER5>] ;COULDN'T
MOVEM T1,UNBLK ;SAVE UN BLOCK FOR LATER
MOVE UNB,T1 ;COPY IT
MOVEI SRV,NI.INT ;TYPE OF SERVICE IS INTERNET
MOVEI T1,IPROTO ;INTERNET ETHERNET PROTOCOL TYPE
CALL UNSET ;SET UP THE UN BLOCK
MOVX T1,NU.OPN ;OPEN NI PORT FUNCTION
MOVE T2,UNB ;POINT AT THE UN BLOCK
CALL DLLUNI ;CALL NI DRIVER
JRST NIOPN1 ;ERROR. RETURN UN BLOCK
SKIPE UNBNFI ;HAVE SOME UN BLOCKS YET ?
IFSKP.
LOAD T1,UNPID,(UNB) ;NO - USING THIS PORTAL ID,
CALL GUNBLK ;GET SOME UN BLOCKS
RETBAD ;COULDN'T
ENDIF.
MOVEI T1,NI.ON
MOVEM T1,NIPON ;IPNI PORTAL IS OPEN
CALL NIOPN2 ;GO RELEASE THE UN BLOCK WE GOT
RETSKP
;Here when we got an error opening the portal
NIOPN1: MOVEM T1,NIPERR ;SAVE THE ERROR
CALL NIOPN2 ;RELEASE THE UN BLOCK
RETBAD <>,<MOVE T1,NIPERR> ;RESTORE ERROR CODE
;Here to return the UN block we just got.
NIOPN2: MOVE T1,UNBLK ;GET UN BLOCK ADR
CALLRET RETBLK ;AND RELEASE THE SPACE
ENDTV. ;END OF NIOPEN TRVAR
SUBTTL Status Checks for Multinet
;NIPSTA - STATUS CHECK
;
; This routine is called from Multinet to check the status of
; the KLNI.
;
; NCT/ NCT address
;
; Returns + 1 on error
; + 2 on success
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
NIPSTA::SAVEAC <SRV,UNB>
SKIPN UNBNFI ;DO WE HAVE ANY UN BLOCKS YET ?
RETBAD ;NO - CAN'T CHECK STATUS UNTIL WE DO
CALL INTUNB ;YES - SET UP POINTER TO UN BLOCK
RETBAD ;IGNORE THE ERROR UNTIL WE'RE INIT'D
CALL NISTAT ;GET THE STATUS
RETBAD <>,<CALL RETUNB> ;IGNORE THE ERROR
CALL RETUNB ;RELEASE THE UN BLOCK
RETSKP
;IPCBLS - LINE STATE CHANGE
;
; This is an unsolicated callback which occurs when NISRV has
; detected a state change in the NI.
;
; Alternate entry point CKSTAT is called from NIPSTA to check
; the status returned in the UN block.
;
; T2/ UN block address
; T3/ 0 or NISRV error code
;
; Returns + 1 on error
; + 2 on success
IFE REL6,<RESCD>
IFN REL6,<XRESCD>
IPCBLS: MOVE NCT,NIPNCT ;GET THE NCT ADDRESS
MOVE UNB,T2 ;SET UP WITH NISRV'S UN BLOCK
CALL CKSTAT ;CHECK THE STATUS
IFNSK.
SETOM NIPSHT ;FLAG CHANGE TO SHUT KLNI DOWN
RETBAD <NI.ER9>
ENDIF.
SKIPN NIPON ;STATUS IS UP. ARE WE INIT'D
RETBAD ;NO
AOS NIPRSF ;TELL THE INTERNET FORK TO RESTART IPNI
AOS INTFLG ;WE WANT THE INTERNET FORK TO RUN
AOS PSKD1 ;MAKE THE SCHEDULER NOTICE THIS IF IN NULL JOB
RETSKP ;GIVE A GOOD RETURN
SUBTTL KLNI Status Check Routines
;NISTAT - CHECK STATUS OF KLNI
;
; NISTAT is called from the restart code and from the ARP start
; up code to check the status of the NI after the channel has
; been opened.
;
; UNB/ UN block address (for CKSTAT)
; NCT/ NCT address
;
; Returns + 1 from NIPHNG on error
; + 2 from CKSTAT on success
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
NISTAT: SETZM NTERRF(NCT) ;CLEAR NOTICES OF ERRORS
MOVE T1,NIPON ;GET "ON" FLAGS
SKIPE INTON ;HAS INTERNET BEEN STARTED ?
CAIGE T1,NI.ON ; AND HAVE WE DONE THE OPEN YET ?
CALLRET NIPHNG ;NO - WAIT
MOVX T1,NU.RCI ;READ CHANNEL STATUS
MOVE T2,UNB ;POINT AT UN BLOCK
CALL DLLUNI ;CALL NISRV
JRST NISTR1 ;HANDLE THE ERROR
JRST CKSTAT ;GO CHECK THE STATUS WORDS
;Here when no UN block was available
NISTER: MOVEI T1,NI.ER8 ;SET THE ERROR CODE
NISTR1: MOVEM T1,NIPERR ;SAVE IT
CALLRET NIPHNG ;SLOW DOWN RETRIES FOR A WHILE
;Here to check the status of the KLNI.
CKSTAT: LOAD T3,UNCAR,(UNB) ;GET CURRENT ETHERNET ADDRESS
LOAD T4,UNCAR,+1(UNB) ;GET 2ND HALF TOO
DMOVEM T3,ETHADR ;SAVE THEM
LOAD T1,UNSTA,(UNB) ;GET THE CHANNEL STATUS
TXNE T1,UNRUN ;CHANNEL RUNNING OKAY ?
RETSKP ;YES
LOAD T1,UNSST,(UNB) ;GET SECONDARY STATUS
MOVEM T1,ICHNST ;SAVE IT
CALL NIPHNG ;FINISH UP ERROR RECOVERY
RETBAD
SUBTTL Output Routines
;NIPHDR - BUILD HEADER
;
; Called from Multinet to build a header for the local transport
; layer. In our case, the only essential information is the host
; number of the next node which can route the packet.
;
; T1/ local address to send to
; T2/ address of buffer
; NCT/ NCT address
;
; Returns + 1 always
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
NIPHDR::MOVEM T1,NI.HOP(T2) ;STORE DESTINATION ADDRESS
RET
SUBTTL Output Routines - Start Output
;NIPSTO - START OUTPUT
;
; Called to send an output buffer.
;
; NCT/ NCT address
; NTIOBO/ pointer to the list of internet buffers to send
; NTIOBI/ tail end of the list
;
; Returns +1 always
IFE REL6,<RESCD>
IFN REL6,<XRESCD>
NIPSTO::SAVEAC <SRV,UNB,RID> ;START OUTPUT
PIOFF ;STOP THE MACHINE
SKIPN NTOB(NCT) ;OUTPUT IN PROGRESS?
SKIPN RID,NTIOBO(NCT) ;ANY INTERNET OUTPUT WAITING?
JRST NIPSTX ;NO WORK TO DO OR ALLREADY IN PROGRESS
NIPOS1: ;THIS IS THE LOOP FOR POSTING ALL THE BUFFERS
SETOM NTOB(NCT) ;FLAG THAT OUTPUT IS IN PROGRESS
LOAD T1,NBQUE,(RID) ;GET THE SUCCESSOR BUFFER TO THIS ONE
SKIPE T1 ;DOES IT HAVE A SUCCESSOR?
IFSKP.
SETZM NTIOBI(NCT) ;NO SO RESET THE TAIL
ELSE.
SETSEC T1,INTSEC ;YES SO SET THE SECTION NUMBER
ENDIF.
MOVEM T1,NTIOBO(NCT) ;SAVE THE NEW HEAD
SETZRO NBQUE,(RID) ;DEQUEUE BUFFER FROM ITS OLD CHAIN
PION ;BUFFER IS DEQUEUED SO GIVE BACK THE MACHINE
MOVEI SRV,NI.INT ;TYPE OF SERVICE IS INTERNET
CALL NISEND ;NO. SEND TO NISRV
JRST NIPSTR ;HMMMM. ERROR.
SETZM NTTOUT(NCT) ;CLEAR OUTPUT HUNG TIMEOUT
PIOFF ;LOOKS THAT WAY, SO STOP THE MACHINE
SKIPE RID,NTIOBO(NCT) ;ANY INTERNET OUTPUT WAITING?
JRST NIPOS1 ;TRY FOR MORE
NIPSTR: SETZM NTOB(NCT) ;RESET OUTPUT IN PROGRESS FLAG
NIPSTX: PION ;GIVE BACK THE MACHINE
RET ;AND RETURN
SUBTTL Output Routines - Send Packet
;NISEND - SEND PACKET TO NISRV
;
; Set up the UN block and gives the packet to NISRV. For IP packets that
; are smaller than the Ethernet minimum, an MSD style transmit is done.
;
; NCT/ NCT address
; RID/ address of buffer
;
; Returns + 1 on error
; + 2 on success
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
NISEND:
IFN IPNDSW,<
MOVE T1,RID ;PUT ADDRESS IN ITS PLACE
CALL IPNENQ> ;LINK THIS BUFFER AS QUEUED
XMOVEI T2,-LCLPKT(RID) ;POINT TO RIGHT LOCATION TO PICK UP PIDH
LOAD T3,PIDH,(T2) ;GET THE DESTINATION HOST #
CAMN T3,NTLADR(NCT) ;DESTINED FOR US ?
CALLRET NILCAL ;YES
MOVE T2,NI.HOP(RID) ;GET THE ROUTING ADDRESS
CALL INTSRC ;GO FIND HOST # IN GHT
CALLRET NIUNKA ;UNKNOWN ROUTING ADDRESS, CHECK IT
SKIPN ARPON ;IS ARP ON ?
IFSKP.
CALL NIVLDA ;YES - VALIDATE THE ETHERNET ADDRESS
CALLRET NIRELB ;ADDRESS NOT VALID, ARP MSG SENT
ENDIF.
CALL INTUNB ;GET A UN BLOCK TO USE
CALLRET NISND1 ;NO UN BLOCK, DROP THE PACKET AND BUGINF
DMOVE T3,GH.EN1(T2) ;GET BOTH WORDS OF ETHERNET ADDRESS
STOR T3,UNDAD,(UNB) ;SAVE THEM IN THE UN BLOCK
STOR T4,UNDAD,+1(UNB)
STOR RID,UNRID,(UNB) ;SAVE BUFFER ADR AS REQUEST ID
XMOVEI T2,-LCLPKT(RID) ;POINT TO RIGHT LOCATION TO PICK UP LENGTH
LOAD T1,PIPL,(T2) ;GET PACKET LENGTH
CAIGE T1,EMINPL ;LESS THAN THE MINIMUM ETHERNET REQUIREMENT?
IFSKP.
STOR T1,UNBSZ,(UNB) ;NO - DON'T NEED MSD'S - SAVE LENGTH FOR NISRV
XMOVEI T3,MAXLDR(RID) ;POINTER TO IP PACKET
TXO T3,<OWGP. 8,> ;FORM BYTE POINTER TO BUFFER
STOR T3,UNBFA,(UNB) ;SAVE IT AWAY
ELSE.
SETZRO UNBSZ,(UNB) ;YES - NEED MSD'S - ZERO THE UN BLOCK BYTE COUNT
XMOVEI T3,MSD1(UNB) ;GET POINTER TO FIRST MSD
XMOVEI T4,MSD2(UNB) ;GET POINTER FOR 2ND MSD
STOR T3,UNBFA,(UNB) ;SAVE POINTER TO 1ST MSD IN UN BLOCK
STOR T1,MDBYT,(T3) ;SAVE PACKET BYTE COUNT IN MSD 1
MOVEI T2,EMINPL ;GET MINIMUM ETHERNET PACKET SIZE
SUB T2,T1 ;COMPUTE # OF BYTES NEEDED FOR PADDING
STOR T2,MDBYT,(T4) ;SAVE PAD BYTE COUNT IN 2ND MSD
XMOVEI T2,MAXLDR(RID) ;POINTER TO IP PACKET
STOR T2,MDALA,(T3) ;SAVE AS BUFFER ADDRESS IN MSD 1
ENDIF.
MOVX T1,NU.XMT ;SET FUNCTION CODE TO TRANSMIT
MOVE T2,UNB ;POINT AT UN BLOCK
CALL DLLUNI ;SEND THE BUFFER
CALLRET NISND2 ;GO RELEASE THE UN BLOCK AND HANDLE ERROR
CALL RETUNB ;GO RELEASE THIS UN BLOCK
RETSKP
SUBTTL Output Routines - Local Message Handling
;NILCAL - LOCAL LOOPBACK
;
; Called from NISEND to handle a message to ourself. We reserve
; a input buffer and copy the IP packet into it, queue it, and
; release the old packet. This routine is needed because the
; KLNI only has one CRC generator and two are needed to send and
; receive a packet at the same time.
;
; RID/ address of the outgoing IP packet
; NCT/ address of the NCT
;
; Returns via NIRELB
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
NILCAL: STKVAR <BFA>
CALL NIPGIB ;MAKE SURE WE HAVE ENOUGH BUFFERS
CALL NIPBFR ;GET A BUFFER TO USE
JUMPE T1,[MOVEI T1,NI.ER1 ;NO BUFFER ERROR
CALLRET NISND1]
MOVEM T1,BFA ;SAVE THE NEW BUFFER ADDRESS
XMOVEI T2,-LCLPKT(RID) ;POINT AT PACKET HEADER BEGINNING
LOAD T1,PIPL,(T2) ;HEADER LENGTH IN BYTES
ADDI T1,3+PKTELI*4 ;PACKET SIZE IN BYTES, ROUNDED UP
ASH T1,-2 ;PACKET SIZE IN FULL WORDS
XMOVEI T2,MAXLDR(RID) ;POINT TO BEGINNING OF BUFFER
MOVE T3,BFA ;DESTINATION IS THE POSTED RCV BUFFER'S
ADDI T3,MAXLDR ; DATA AREA
CALL XBLTA ;COPY IP HEADERS
MOVE T1,BFA ;POINT AT RCV BUFFER
CALL NIPQUE ;GIVE THE BUFFER TO INTERNET
CALLRET NIRELB ;RELEASE OLD BUFFER
ENDSV.
;Here to release the current output buffer
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
NISND2: CALL RETUNB ;RETURN THE UN BLOCK
NISND1: SKIPA T3,T1 ;WANT THE ERROR STATUS
NIRELB: SETZ T3, ;DON'T WANT ANY ERROR STATUS
MOVE T1,RID ;GET BUFFER ADDRESS
CALLRET CBDS1 ;GO RELEASE THE BUFFER
SUBTTL Output Routines - Datagram Sent Callback
;IPCBDS - DATAGRAM SENT
;
; Uses the request ID in the UN block which is the address of
; the sent buffer and places it on the free buffer list.
;
; Alternate entry point CBDS1 is called from NISEND when NISRV
; returned an error at the time of the send.
;
; Alternate entry point CDSERR is called from ARPCDS.
;
; T1/ buffer address if called at CBDS1
; T2/ UN block address
; T3/ 0 if function succesfull or error code
;
; Returns + 1 on error
; + 2 on success
IFE REL6,<RESCD>
IFN REL6,<XRESCD>
IPCBDS: MOVE UNB,T2 ;SAVE UN BLOCK ADDRESS
LOAD T1,UNRID,(UNB) ;GET THE BUFFER ADDRESS TO RELEASE
LOAD SRV,UNUID,(UNB) ;GET USERID
HRRZS SRV ;BUT USE ONLY TYPE OF SERVICE PORTION
CBDS1: MOVE T2,T1 ;COPY FOR INDEXING
PIOFF ;STOP THE MACHINE
IFN IPNDSW,<CALL IPNDEQ> ;UNLINK THIS BUFFER
EXCH T1,INTNFB ;PUT ON FREE LIST
STOR T1,NBQUE,(T2) ;HANG OLD LIST OFF OF THIS NEW HEAD
PION ;GIVE BACK THE MACHINE
AOS INTFLG ;GET INTERNET GATEWAY TO NOTICE IT
AOS PSKD1 ;MAKE THE SCHEDULER NOTICE THIS IF IN NULL JOB
SKIPN T1,T3 ;NO, GET THE CHANNEL STATUS
RETSKP ;NO ERRORS DETECTED
CDSERR: AOS NIOCNT ;BUMP THE OUTPUT ERROR COUNT
BUG.(CHK,IPDWNS,IPNIDV,SOFT,<Datagram was not sent>,<<T1,ERROR>,<SRV,SERVICE>>,<
Cause: The internet ethernet software passed a buffer to NISRV to be sent and
and an error was returned. This usually indicates that the KLNI has
changed state and IPNIDV has not yet been notified. This should be
a temporary condition.
>)
MOVEM T1,NIPERR
RETBAD
SUBTTL Input Routines - Post Receive Buffer
;NIPOST - POST AN INTERNET INPUT BUFFER
;
; This routine gives NISRV a receive buffer. The buffer must be
; resident. Note, this routine assumes that there is room for 4
; bytes of CRC at the end.
;
; T1/ address of input buffer
; UNB/ address of the UN block
;
; Returns + 1 if error returned from NISRV, NIPERR has error code
; + 2 on success
IFE REL6,<RESCD>
IFN REL6,<XRESCD>
NIPOST: SKIPN T1 ;ZERO IF NIPBFR COULDN'T GET A BUFFER
RETBAD <NI.ER1> ;RETURN THE ERROR
IFN IPNDSW,<CALL IPNENQ> ;LINK THIS BUFFER AS QUEUED
MOVE T3,INTXPB ;GET SIZE OF INTERNET PACKET
ADDI T3,4 ;ADD IN CRC
STOR T3,UNBSZ,(UNB) ;SAVE IT AS RECEIVE BUFFER SIZE
STOR T1,UNRID,(UNB) ;SAVE INPUT BUFFER ADR AS REQUEST ID
ADDI T1,MAXLDR ;POINT PAST LEADER FOR START OF IP HEADER
TXO T1,<OWGP. 8,> ;FORM BYTE POINTER TO BUFFER
STOR T1,UNBFA,(UNB) ;SAVE AS THE BUFFER ADDRESS
MOVX T1,NU.RCV ;POST RECEIVE BUFFER FUNCTION
MOVE T2,UNB ;GET UN BLOCK ADR
CALL DLLUNI ;NO. CALL NISRV
CALLRET POSTER ;NISRV RETURNED ERROR
AOS NICNTP ;INC # OF BUFFERS POSTED RIGHT NOW
RETSKP ;SUCCESS
;Here when NISRV returned an error from posting a new receive buffer
;Called from NIPOST or ARPOST.
POSTER: MOVEM T1,NIPERR ;SAVE THE ERROR
LOAD T2,UNUID,(UNB) ;GET THE USERID
HRRZS T2 ;KEEP ONLY THE SERVICE TYPE
SKIPN NIPON ;INTERNET UP ?
BUG. (CHK,IPPSTE,IPNIDV,SOFT,<Couldn't post a buffer>,<<T1,ERROR>,<T2,SERVICE>>,<
Cause: The internet ethernet software tried to post a receive buffer to NISRV
and received an error return. This usually indicates that the KLNI has
changed state and IPNIDV has not yet been notified. This should be
a temporary condition.
>)
CAIN T2,NI.INT ;INTERNET SERVICE POSTING ERROR ?
IFSKP.
IFN IPNDSW,<MOVE T1,RID ;PUT ADDRESS IN ITS PLACE
CALL IPNDEQ> ;UNLINK THIS BUFFER
LOAD T2,UNRID,(UNB) ;YES - GET BUFFER ADDRESS BACK
CALL NIPQIB ;PUT BUFFER BACK ON FREE QUEUE
ENDIF.
RETBAD <>,<MOVE T1,NIPERR> ;PICK UP ERROR CODE BEFORE RETURNING
SUBTTL Input Routines - Datagram Received Callback
;IPCBDR - DATAGRAM RECEIVED
;
; The NI received a datagram with IP's protocol type. The
; address is available in UNRID of the UN block.
;
; T2/ UN block address
; T3/ 0 if function succesfull or error code
; UNRID/ address of buffer
;
; Returns + 1 on error
; + 2 on success
IFE REL6,<RESCD>
IFN REL6,<XRESCD>
IPCBDR: STKVAR <UNBLK,STS>
SOS NICNTP ;DECREMENT # OF BUFFERS POSTED NOW
MOVEM T2,UNBLK ;SAVE THE UN BLOCK ADR
MOVEM T3,STS ;SAVE THE ERROR STATUS
LOAD T1,UNRID,(T2) ;GET THE ADDRESS OF THE BUFFER
IFN IPNDSW,<CALL IPNDEQ> ;DEQUEUE THIS BUFFER
JUMPN T3,CBDRCK ;PROBLEMS ?
CALL NIPQUE ;GIVE THE BUFFER TO INTERNET
CALL NIPBFR ;GET ANOTHER BUFFER
MOVE UNB,UNBLK ;PICK UP THE UN BLOCK TO USE
CALL NIPOST ;POST IT
RETBAD ;GOT AN ERROR
RETSKP ;GIVE GOOD RETURN
; Here when an error was detected. If the channel is not shutting
; down, bump the error count and re-post the buffer. If the
; channel is shutting down, put the buffer on the free queue.
;
; T1/ address of the buffer
; T3/ error status
CBDRCK: ;HERE ON ERRORS FROM IPCBDR
AOS NIICNT ;BUMP THE INPUT ERROR COUNTER
CAIE T3,UNRDL% ;DATAGRAM TOO LONG ?
JRST CBDRC2 ;NO
CALL NIICMP ;YES GO SEND AN ICMP ERROR MESSAGE
MOVE UNB,UNBLK ;GET THE UNBLOCK
LOAD T1,UNRID,(UNB) ;GET BUFFER ADDRESS AGAIN
CALL NIPOST ;POST IT
RETBAD <>,<MOVE T1,STS> ;GOT AN ERROR BUT USE ORIGINAL ERROR CODE
RETSKP ;GIVE GOOD RETURN
CBDRC2: ;HERE WHEN ERROR WAS NOT DATAGRAM TOO LONG
MOVE T2,T1 ;PUT ADDRESS WHERE NIPQIB WANTS IT
CALL NIPQIB ;PUT ON FREE BUFFER QUEUE
RETSKP ;TAKE GOOD RETURN
ENDSV. ;END OF IPCBDR STKVAR
SUBTTL Address Change Callback
;IPCBAC - ADDRESS CHANGE CALLBACK
;
; This is an unsolicated callback which occurs when NISRV has
; been asked to change it's Ethernet address.
;
; T2/ UN block address
; T3/ 0 or NISRV error code
;
; Returns + 1 on error with error code in T1
; or when GHT does not agree with NISRV
; + 2 on success
IFE REL6,<RESCD>
IFN REL6,<XRESCD>
IPCBAC: MOVE NCT,NIPNCT ;GET THE NCT ADDRESS
MOVE UNB,T2 ;USE NISRV'S UN BLOCK
LOAD T3,UNCAR,(UNB) ;GET HIGH ORDER WORD OF ETHERNET ADR
LOAD T4,UNCAR,+1(UNB) ;GET LOW ORDER BYTES
CAMN T4,ETHADR+1 ;MATCH KNOWN LOW ORDER WORD
CAME T3,ETHADR ;YES - MATCH KNOWN HIGH ORDER WORD
IFNSK. ;NO. GHT DID NOT MATCH KLNI ADDRESS
SKIPN ARPENA ;IS ARP ENABLED ?
IFSKP.
DMOVEM T3,ETHADR ;YES - UPDATE OUR ADDRESS INFORMATION
SETOM NIPGTF ;RE-INIT THE GHT, OUR ADDRESS IS INVALID
RETSKP
ENDIF.
BUG.(INF,IPETHA,IPNIDV,SOFT,<Ethernet address change, IPNI shutting down>,,<
Cause: The internet ethernet software has received an address changed
callback from NISRV and the ARP protocol is disabled. The ARP
protocol is needed to handle this situation. Internet ethernet
service has been terminated.
>)
SETOM NIPSHT ;FLAG THE SHUTDOWN
RETBAD <NI.ER2>
ENDIF.
RETSKP
SUBTTL Shutdown and Error Routines
;NIPKIL - SHUTDOWN
;
; Called from MNETDV to shut down both Internet and ARP
; communications with NISRV.
;
; NCT/ NCT address
;
; Returns + 1 always (T1 IS PRESERVED)
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
NIPKIL::SAVEAC <SRV,UNB>
MOVE T1,NTRDY(NCT) ;RECORD IF ANYTHING CHANGED
IOR T1,NTORDY(NCT)
SETZM NTTOUT(NCT) ;CLEAR OUTPUT HUNG TIMEOUT
JUMPE T1,NIPKLD ;NOTHING CHANGED SO EXIT QUIETLY
SETZM NTRDY(NCT) ;NI OFF
SETZM NTORDY(NCT) ;OUTPUT OFF
AOS NTSTCH(NCT) ;JUST CHANGED STATE
AOS JB0FLG ;NOTE THE NETWORK CHANGE
CALL NIOFF ;SHUT DOWN THE INTERNET PROTOCOL
SETZM NIPON ;INTERNET NOT ON ANYMORE
CALL RUNBLK ;RELEASE THE UN BLOCKS
SETZM NIPSHT ;CLEAR NEED TO SHUTDOWN FLAG
SKIPN ARPON ;ARP ON ?
RET ;NO
CALL ARPKL1 ;YES - SHUT IT OFF TOO
JFCL ;IGNORE THE ERROR
NIPKLD: RET
;Here to shut off Internet communications over the NI
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
NIOFF: MOVE T1,NIPON ;GET "ON" FLAGS
CAIGE T1,NI.ON ;PORTAL OPEN OR BETTER ?
RET
CALL INTUNB ;SET UP UN POINTER
JRST NIOFF1 ;IF NO UN BLOCK, DON'T TRY THE CLOSE
MOVX T1,NU.CLO ;NI CLOSE FUNCTION
MOVE T2,UNB ;GET UN BLOCK ADDRESS
CALL DLLUNI ;DO THE CLOSE
JFCL ;ERROR
CALL RETUNB ;RETURN THE UN BLOCK
NIOFF1: RET
;Set the error flags, turn off ready
IFE REL6,<RESCD>
IFN REL6,<XRESCD>
NIPHNG: SETOM NTERRF(NCT) ;YES, FLAG AN ERROR
SETZM NTRDY(NCT) ;MAKE THE NETWORK NOT READY
MOVE T1,TODCLK ;GET TIME NOW
ADDI T1,^D60*^D1000 ;TIMEOUT IN ONE MINUTE
MOVEM T1,NTTOUT(NCT) ;SET INTERFACE HUNG TIMEOUT
RET
SUBTTL Internet Fork Background Service
;NIPSRV - GENERAL BACKGROUND SERVICE
;
; Called from the Internet fork to service miscellaneous
; requests.
;
; Returns + 1 always
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
NIPSRV::SAVEAC <NCT,UNB,RID> ;SAVE THE NCT AC
SKIPE NCT,NIPNCT ;GET OUR NCT
SKIPN NIPON ;IPNI UP YET ?
RET ;HASN'T INITIALIZED YET
SKIPE NIPGTF ;SHOULD GHT BE INVALIDATED ?
CALL NIHINV ;YES
SKIPE NIPSHT ;SHOULD WE SHUT DOWN THE KLNI ?
CALL NIPKIL ;YES - SO TURN EVERYTHING OFF
SKIPN NIPRSF ;NEED TO RESTART IPNI?
IFSKP.
CALL NIPRST ;YES - SO RESET IPNI NOW
SETZM NIPRSF ;AND RESET THE FLAG
ENDIF.
CALL INTUNB ;GET A UNB BLOCK
RET ;COULDN'T
CALL NIPPIB ;SEE IF ANY INPUT BUFFERS WATNED
JFCL ;IGNORE THE ERROR, BUGINFS HAVE BEEN ISSUED
CALL RETUNB ;RETURN THE UN BLOCK
SKIPE NTLOBO(NCT) ;ANY ARP MESSAGES TO PROCESS
CALL ARPPRC ;YES
SKIPE NIPSRQ ;ANY REQUESTS FOR READ PORTAL COUNTERS ?
CALL NIPRPC ;YES
SKIPE ARPSRQ ;ANY REQUEST FOR ARP COUNTERS ?
CALL ARPRPC ;YES
RET
SUBTTL Miscellaneous Subroutines
;NIVLDA - VALIDATE THE ETHERNET ADDRESS
;
; Called by NISEND to check the Ethernet address in the ght to
; see if it has been validated by ARP (if ARP is being used) or
; to see if the remote host does ARP.
;
; T2/ GHT area 2 addres of the entry
;
; Returns + 1 if address not valid, ARP message sent
; + 2 if address is valid, use it
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
NIVLDA: MOVE T1,GH.GCF(T2) ;GET THE GATEWAY CONTROL FLAGS
TXNE T1,GH%ARP!GH%DMB ;VALIDATED BY ARP OR HOST DOESN'T DO ARP
RETSKP ;YES
CALL ARPSND ;FORCE ARP TO VALIDATE IT
JFCL ;IGNORE THE ERROR
RETBAD
;NIUNKA - UNKNOWN INTERNET ADDRESS
;
; Called from NISEND when we found that we didn't have the
; routing address in our GHT.
;
; RID/ address of the buffer
;
; Returns via NIRELB routine
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
NIUNKA: SKIPN ARPON ;IS ARP ON ?
JRST NSND2A ;NO - BYPASS THE ARP CODE
CALL ARPSND ;YES - GENERATE AN ARP PACKET
JFCL ;IGNORE THE ERROR
NSND2A: MOVE T2,NI.HOP(RID) ;GET THE ROUTING ADDRESS
XMOVEI T1,-LCLPKT(RID) ;POINT TO RIGHT LOCATION TO PICK UP PIDH
LOAD T3,PIDH,(T1) ;GET THE DESTINATION HOST #
SKIPN ARPON ;ARP BEING USED ?
CAMN T3,T2 ;DOES IT MATCH ROUTING ADDRESS
SKIPA
BUG.(INF,IPRANF,IPNIDV,SOFT,<Routing address not found>,<<T2,RTE>,<T3,DEST>>,<
Cause: The internet ethernet software has been asked to forward a message
to an internet host whose ethernet address translation is not known.
This situation is normally handled by the ARP protocol which is not
enabled if this BUGINF occurs.
>)
CALLRET NIRELB ;RELEASE THE BUFFER
;NIPQUE - QUEUE UP THE RECEIVE BUFFER FOR INTERNET FORK
;
; Called from the datagram received callback or from the local
; loopback routine to queue up a buffer for input to Internet.
;
; T1/ Address of the buffer
;
; Returns + 1 always
IFE REL6,<RESCD>
IFN REL6,<XRESCD>
NIPQUE: SETZRO NBQUE,(T1) ;MAKE SURE POINTER FOR THIS BUFFER IS CLEAR
PIOFF ;DON'T ALLOW US TO BE INTERRUPTED
MOVE T3,INTIBI ;QUEUE FOR INTERNET GATEWAY
JUMPN T3,CBDRQ1
MOVEM T1,INTIBO ;ONLY THIS ITEM
SKIPA
CBDRQ1: STOR T1,NBQUE,(T3)
MOVEM T1,INTIBI ;NEW POINTER
AOS INTFLG ;CAUSE INTERNET TO NOTICE IT.
AOS PSKD1 ;MAKE THE SCHEDULER NOTICE THIS IF IN NULL JOB
PION
RET
;NIICMP - SEND ICMP FRAGMENTATION MESSAGE
;
; Called from IPCBDR when a datagram has been received which is
; is too long for our input buffers. This routine (in the
; future) needs to queue up a request to the Internet fork to
; send a parameter problem/fragmentation needed ICMP message.
;
; SAVEAC <PKT> ;SAVE PKT
; XMOVEI PKT,-LCLPKT(T1) ;PUT WHERE ICMERR WANTS BUFFER ADDRESSES
; MOVX T1,<DU%FRG,,ICM%PP> ;FRAGMENTATION NEEDED, PARAMETER PROBLEM
; CALL ICMERR ;GENERATE ICMP ERROR
;
; T1/ address of the input buffer
; Returns + 1 always
IFE REL6,<RESCD>
IFN REL6,<XRESCD>
NIICMP: RET ;JUST A STUB FOR NOW
SUBTTL Buffer Management Routines
;NIPGIB - GET INPUT BUFFERS.
;
; Called from the Internet fork to get a bunch of input buffers
; to be used for incoming IP packets over the Ethernet.
;
; Returns + 1 always
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
NIPGIB: MOVE T1,NIPNFI ;NUMBER OF FREE INPUT BUFFERS
NIPGB1: CAML T1,NIPNIB ;BELOW DESIRED LEVEL?
RET ;NO - DO NOTHING
CALL GETNIB ;GET A BUFFER
JUMPE T1,NIPGB3 ;ZERO ADDRESS, NONE AVAILABLE
SETZRO PKTFLG,(T1) ;CLEAR ALL INTERNAL CONTROL FLAGS
SETONE PFSIZ,(T1) ;INDICATE IT'S A FULL SIZE PACKET
XMOVEI T2,LCLPKT(T1) ;GET POINTER TO LOCAL HEADERS
MOVE T3,MAXWPM ;MAX WORDS
STOR T3,NBBSZ,(T2) ;SAVE AS BUFFER SIZE
SETZRO NBQUE,(T2)
CALL INTLKB ;MAKE SURE BUFFER IS RESIDENT
CALL NIPQIB ;GO QUEUE THE INPUT BUFFER
JRST NIPGB1 ;GO TRY FOR MORE
;Here to queue up an input buffer
IFE REL6,<RESCD>
IFN REL6,<XRESCD>
NIPQIB: MOVE T1,T2 ;COPY FOR QUEUEING
PIOFF
EXCH T2,NIPFRI ;ADD TO LIST OF FREE INPUT BUFFERS
STOR T2,NBQUE,(T1) ;OLD LIST IS SUCCESSOR OF THIS BUF
AOS T1,NIPNFI ;BUMP THE COUNT TO MATCH
PION
RET
;Here when no buffers available
NIPGB3: MOVE T1,NIPNFI ;GET NUMBER OF BUFFERS AVAILABLE
CAIGE T1,NNIPTH ;BELOW THE THRESHOLD LEVEL ?
BUG.(CHK,IPNBFA,IPNIDV,SOFT,<No IPNI input buffers available.>,<<T1,BFRCNT>>,<
Cause: The internet ethernet software has attemted to assign an input
buffer and internet free space is exhausted.
>)
RET
;NIPPIB - POST A BUNCH OF INPUT BUFFERS
;
; Called in make sure we have enough input buffers posted to
; NISRV.
;
; Returns + 1 on error
; + 2 on success
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
NIPPIB: CALL NIPGIB ;MAKE SURE WE HAVE ENOUGH BUFFERS
PIB1: MOVE T1,NIPNIB ;GET # OF BUFFERS WE SHOULD HAVE
LSH T1,-1 ;MAKE # OF BUFFERS THAT WE WANT TO BE POSTED
CAMG T1,NICNTP ;REACHED THAT LEVEL ?
RETSKP ;YES
CALL NIPBFR ;GET A RECEIVE BUFFER READY
CALL NIPOST ;GO POST THE RECIEVE BUFFER
RETBAD
JRST PIB1 ;TRY TO GET MORE
;NIPBFR - GET AN INPUT BUFFER
;
; Returns + 1 always with T1 containing the buffer address
IFE REL6,<RESCD>
IFN REL6,<XRESCD>
NIPBFR: PIOFF
SOSL T1,NIPNFI ;COUNT DOWN NUMBER OF FREE INTERNET BUFS
SKIPN T2,NIPFRI ;GET POINTER TO BUFFER TO USE
IFNSK.
AOS NIPNFI ;DON'T HAVE BUFFERS. DON'T LET IT GO NEGATIVE
PION
MOVE T2,NIPFRI ;MAKE SURE WE GET POINTER
AOS T3,IPBLPC ;COUNT OCCURANCES OF IPIBLP'S
IDIVI T3,4 ;ONLY BUGINF EVERY MULTIPLE OF 4 TIMES
SKIPN T4 ;BUGINF TIME ?
BUG.(CHK,IPIBLP,IPNIDV,SOFT,<IPNI input buffer list problem>,<<T1,CNT>,<T2,BFR>,<T3,BCNT>>,<
Cause: The internet ethernet software has attempted to queue an input
buffer and none were available. This indicates that the
internet asynchronous fork is not making buffers available fast enough.
>)
SETZ T1, ;FLAG TO NIPOST THAT WE HAVE NO BUFFER
AOS INTFLG ;TRY TO GET INTERNET FORK TO RUN AGAIN
AOS PSKD1 ;MAKE THE SCHEDULER NOTICE THIS IF IN NULL JOB
RET ;TRY TO RECOVER
ENDIF.
LOAD T1,NBQUE,(T2) ;NEXT INTERNET FREE BUFFER
SETSEC T1,INTSEC ;YES SO SET THE SECTION NUMBER
SETZRO NBQUE,(T2) ;CLEAR LIST POINTER
MOVEM T1,NIPFRI ;BECOMES HEAD OF LIST
PION
MOVE T1,T2 ;PUT THE ADDRESS WHERE IT'S EXPECTED
RET
SUBTTL UN Block Management Routines
;GUNBLK - GET UN BLOCKS
;
; Called to get a buffer which will contain a set number of
; UN blocks.
;
; T1/ portal id
;
; Returns + 1 on error
; + 2 on success T1/ beginning address of the buffer
; T2/ number of UN blocks available
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
GUNBLK: STKVAR <ULOC,CNTDWN,PID>
MOVEM T1,PID ;SAVE THE PORTAL ID
MOVEI T1,UN.TNB*<UN.LEN+MS.LEN+1> ;SIZE FOR "n" UN BLOCKS
CALL GETBLK ;GET THE SPACE NEEDED
SKIPE T1 ;DID WE GET ONE ?
IFSKP.
BUG. (CHK,IPNUNS,IPNIDV,SOFT,<No space for UN blocks>,,<
Cause: The monitor attempted to assign some internet free space for
UN blocks and none was available.
>)
RET
ENDIF.
MOVEM T1,IUNBLK ;SAVE THE POINTER TO THIS BLOCK
MOVEM T1,ULOC ;SAVE THE POINTER TO THE FIRST BLOCK
MOVEI T2,UN.TNB ;GET NUMBER OF UN BLOCKS
MOVEM T2,CNTDWN ;SAVE IT AWAY
GUNGB1: MOVE T2,UNBNFI ;GET NUMBER OF FREE UN BLOCKS
CAML T2,CNTDWN ;GOT ENOUGH YET ?
RETSKP ;YES
MOVE T1,ULOC ;GET POINTER TO ADR OF UN BLOCK
PIOFF
MOVE T2,T1 ;COPY THE POINTER
EXCH T2,UNBFRI ;ADD TO LIST OF FREE UN BLOCKS
MOVEM T2,(T1) ;OLD LIST IS SUCCESSOR OF THIS BUF
AOS UNBNFI ;BUMP THE COUNT TO MATCH
PION
XMOVEI UNB,1(T1) ;GET ADDRESS OF UN BLOCK
MOVEI SRV,NI.INT ;TYPE OF SERVICE IS INTERNET
MOVEI T1,IPROTO ;INTERNET ETHERNET PROTOCOL TYPE
MOVE T2,PID ;GET THE PORTAL ID
CALL UNSET ;SET UP THE UN BLOCK
CALL MSDSET ;SET UP THE MSD PORTION OF THE UN BLOCKS
MOVEI T1,UN.LEN+MS.LEN+1 ;OFFSET TO NEXT POINTER
ADDM T1,ULOC ;ADD TO CURRENT POINTER
JRST GUNGB1 ;DO IT ALL AGAIN
ENDSV. ;END OF GUNBLK STKVAR
;RUNBLK - RELEASE UN BLOCKS
;
; Called when killing IPNI, this code releases the space used
; for UN blocks.
;
; Returns + 1 always
RUNBLK: SETZM UNBNFI ;CLEAR UN BLOCK COUNTER
SETZM UNBFRI ;CLEAR UN BLOCK LIST
MOVE T1,IUNBLK ;GET THE POINTER TO THE LARGE BLOCK
CALL RETBLK ;RELEASE THE BLOCK
RET
;UNSET - SET UP UN BLOCK
;
; Sets up the static parameters for the UN block.
;
; T1/ protocol type
; T2/ portal id
; SRV/ type of service
; UNB/ address of the UN block
;
; Returns + 1 always
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
UNSET: SASUBR <PROTO,PID> ;SAVE PROTOCOL TYPE AND PORTAL ID
MOVE T1,UNB ;GET OUR UN BLOCK AREA
MOVEI T2,UN.LEN ;ZERO OUT THE FULL BLOCK
CALL CLRBLK ;ZERO THE BLOCK
XMOVEI T2,NICBAK ;SET THE CALL BACK ROUTINE
STOR T2,UNCBA,(UNB) ;SAVE IT
MOVX T2,<SIXBIT/NIP/> ;GET OUR HANDLE
HRR T2,SRV ;ADD TYPE OF SERVICE TO USERID
STOR T2,UNUID,(UNB) ;SAVE IT
SETZRO UNCHN,(UNB) ;NI UNIT 0
SETZRO UNPMS,(UNB) ;NO PI LEVEL MASK NEEDED
SETZRO UNPTR,(UNB) ;UNDAD WILL ALWAYS BE THE ACTUAL ADRESS
MOVE T1,PID ;GET PORTAL ID BACK
STOR T1,UNPID,(UNB) ;SAVE PORTAL ID
MOVE T2,PROTO ;GET THE ETHERNET PROTOCOL TYPE
STOR T2,UNPRO,(UNB) ;SAVE IT
MOVEI T1,UNA.EV ;BUFFERS ARE EXEC VIRTUAL ADDRESSES
STOR T1,UNADS,(UNB) ;SAVE IT FOR NISRV
RET
ENDSV. ;END OF UNSET STKVAR
;MSDSET - SET UP MSD PORTIONS OF THE UN BLOCK
;
; Called here from GUNBLK to set up the MSD's that are built
; into the UN block.
;
; The MSD's are used only when the length of the TCP/IP packet
; is less than the minimum Ethernet packet size. The 1st MSD
; points the actual TCP/IP packet and the second points to the
; padding bytes to extend the packet to the minimum size.
;
; UNB/ address of the UN block
;
; Returns + 1 always
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
MSDSET: XMOVEI T1,MSD1(UNB) ;POINTER TO THE 1ST MSD
XMOVEI T2,MSD2(UNB) ;POINTER TO THE 2ND MSD
STOR T2,MDNXT,(T1) ;LINK 2ND MSD POINT TO 1ST MSD
SETZRO MDNXT,(T2) ;END OF MSD CHAIN IS THE 2ND MSD
MOVX T3,<POINT 8,0> ;MAKE POINTER TO BE USED WITH MDALA
STOR T3,MDAUX,(T1) ;SET UP IN THE 1ST MSD
STOR T3,MDAUX,(T2) ;SET UP IN THE 2ND MSD
XMOVEI T3,PDBYTS ;POINTER TO THE PADDING BYTES
STOR T3,MDALA,(T2) ;SET UP IN 2ND MSD
MOVX T3,VMC.XC ;ADDRESSES ARE EXEC VIRTUAL
STOR T3,MDVMC,(T1) ;SET UP IN 1ST MSD
STOR T3,MDVMC,(T2) ;SET UP IN 2ND MSD
RET
;INTUNB - GET AN INTERNET UN BLOCK POINTER
;
; Called wherever we need to retrieve a pointer to an Internet
; UN block.
;
; Returns + 1 on error
; + 2 on success UNB/ adress of UN block or 0 if not set
IFE REL6,<RESCD>
IFN REL6,<XRESCD>
INTUNB: PIOFF
SOSL UNBNFI ;COUNT DOWN NUMBER OF FREE INTERNET BUFS
SKIPN UNB,UNBFRI ;GET POINTER TO BUFFER TO USE
IFNSK.
AOS UNBNFI ;NO BUFFERS AVAILABLE. DON'T LET COUNT GO NEG.
PION ;MAKE SURE INTERRUPTS ARE BACK ON
SKIPE NIPON ;IF NOT ON, DON'T BUGINF
BUG.(CHK,IPUNBP,IPNIDV,SOFT,<Free UN block queue problem>,,<
Cause: The monitor attempted to assign a UN block and none were available.
>)
RETBAD <NI.ER5>
ENDIF.
MOVE T1,(UNB) ;NEXT UN BLOCK
SETZM (UNB) ;CLEAR LIST POINTER
MOVEM T1,UNBFRI ;BECOMES HEAD OF LIST
PION ;MAKE SURE INTERRUPTS ARE BACK ON
AOS UNB ;MAKE IT POINT TO REAL UN BLOCK START ADR
RETSKP
;RETUNB - RETURN UN BLOCK TO FREE QUEUE
;
; Called whenever we are done with the current UN block. This
; routine puts it back on the free queue list.
;
; UNB/ UN block address
;
; Returns + 1 always
IFE REL6,<RESCD>
IFN REL6,<XRESCD>
RETUNB: SAVEAC <T1>
PIOFF
SOS T1,UNB ;COPY AND POINT AT QUEUE INFO OF UN BLOCK
EXCH T1,UNBFRI ;ADD TO LIST OF FREE INPUT BUFFERS
MOVEM T1,(UNB) ;OLD LIST IS SUCCESSOR OF THIS BUF
AOS UNBNFI ;BUMP THE COUNT TO MATCH
PION
RET
SUBTTL Gateway Host Table Routines
;NIHINI - GHT table initialization.
;
; NIHINI is called at system startup, or by the IPOPR% jsys.
; This will read the Internet-Ethernet host number translation
; table file and set up 2 areas which will be pointed at by
; GHTAR1 and GHTAR2.
;
; Area 1 will contain in sequential order, the Internet host
; numbers. It is used by the INTSRC routine for determining the
; offset for that host into area 2 of the ght.
;
; Area 2 contains the per host data such as Ethernet addresses
; and gateway control flags.
;
; Returns + 1 on error, error code in T1
; + 2 on success
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
NIHINI::TRVAR <TMPLEN,LSTNUM,INTJFN,GHTPT1,GHTPT2,GHTCT1,INTCKS,<INTBLK,NIHMDL>>
SAVEAC <P1,P2,P3>
CALL NIHSPC ;GET AND SET UP NEW GHT SPACE
RETBAD <>,<MOVEM T1,NIPERR> ;NO SPACE ERROR
CALL NIHOPN ;OPEN THE FILE AND READ HEADER
RETBAD <>,<CALL NIHERR> ;GOT AN ERROR. CODE IN T1
MOVE T1,GHTCT1 ;GET NUMBER OF ENTRIES IN THE FILE
CAMG T1,NIMAXH ;DON'T LET THEM HAVE TOO MANY HOSTS
IFSKP.
MOVEI T1,IPHEMX ;EXCEEDED MAX. SET THE ERROR CODE
CALL NIHERR ;HANDLE THE ERROR
RETBAD ;TAKE ERROR RETURN
ENDIF.
SETZ P3, ;INIT CHECKSUM
SETOM LSTNUM ;INIT LAST HOST NUMBER SEEN
CALL NICHK1 ;READ THE FILE AND BUILD GHT
RETBAD <>,<CALL NIHERR> ;GOT AN ERROR
CAMN P3,INTCKS ;COMPUTED CHECKSUM MATCH THE FILES ?
IFSKP.
MOVEI T1,IPHCHK ;NO. SET THE ERROR CODE
CALL NIHERR ;HANDLE THE ERROR
RETBAD ;TAKE ERROR RETURN
ENDIF.
CALL NIHFIN ;UPDATE GHTAR1 AND 2, CLOSE THE FILE
RETSKP ;GIVE GOOD RETURN
;NICHK1 - READ, CHECK, AND BUILD GHT
;
; Called from NIHINI to read the GHT file, build, and verify the
; GHT. NOTE: The Internet host # must be offset 0 in the data.
;
; P1/ area 1 pointer into ght
; P2/ area 2 pointer into ght
;
; Returns + 1 on error
; + 2 on success
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
NICHK1: MOVE T1,INTJFN ;PICK UP THE JFN
MOVE T2,[POINT 36,INTBLK] ;PUT DATA INTO TEMP AREA
MOVEI T3,NIHMDL ;READ HOST MAX DATA LENGTH WORDS
SIN ;READ A WORD FROM THE FILE
ERJMP NICHK3 ;SHOULDN'T HAVE EOF YET. ERROR.
XMOVEI T1,INTBLK ;GET GLOBAL ADDRESS OF TEMP AREA
IOR T1,[EP. 0(T2)] ;MAKE INDIRECT WORD
SETZ T2, ;STARTING INDEX
NICHK2: ADD P3,@T1 ;COMPUTE A SIMPLE CHECKSUM
CAIGE T2,NIHMDL-1 ;END?
AOJA T2,NICHK2 ;NO, STEP COUNT AND LOOP
MOVE T1,INTBLK ;GET THE INTERNET NUMBER
CAMG T1,LSTNUM ;GREATER THAN LAST HOST NUMBER ?
RETBAD <IPHSEQ> ;SEQUENCE ERROR
MOVEM T1,LSTNUM ;UPDATE THE LAST NUMBER
MOVE T2,NIPNCT ;GET OUR NCT ADDRESS
CAME T1,NTLADR(T2) ;IS THIS OUR ADDRESS ?
IFSKP.
SOS GHTCT1 ;YES - DON'T COUNT THIS ENTRY THEN
JRST NICHK4 ;DON'T UPDATE GHT
ENDIF.
MOVEM T1,(P1) ;SAVE INTERNET NUMBER IN AREA 1
AOS P1 ;MAKE IT POINT TO NEXT ENTRY
XMOVEI T2,INTBLK ;POINT AT TEMP AREA AGAIN
ADDI T2,.NIINT+1 ;GET PAST THE INTERNET NUMBER
MOVEI T1,GH2MDL ;LENGTH OF AREA 2 ENTRIES
MOVE T3,P2 ;POINT AT THE DATA AREA OF THE GHT (AREA 2)
CALL XBLTA ;XFER IT
ADDI P2,GH2MDL ;BUMP INDEX INTO AREA 2
NICHK4: MOVNI T2,NIHMDL ;GET NEGATIVE LENGTH OF THE ENTRY
ADDB T2,TMPLEN ;SUBTRACT FROM WORDS LEFT
JUMPL T2,[RETBAD <IPHCNT>] ;ARG COUNT IS WRONG IF NEGATIVE
JUMPG T2,NICHK1 ;LOOP UNTIL DONE
RETSKP
;Here when premature end of file
NICHK3: SKIPE GHTCT1 ;DO WE HAVE ANY ENTRIES IN THE FILE?
RETBAD <IPHCNT> ;YES - RETURN THE ERROR
RETSKP ;NO - ALL IS WELL, EOF IS NOT PREMATURE
;NIHOPN - OPEN GHT FILE
;
; Called from NIHINI this code opens the GHT file and starts
; reading the header information.
;
; Returns + 1 on error, error code in T1
; + 2 on success, P3/ updated checksum
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
NIHOPN: STKVAR <<HDRS,NIHMHL>>
MOVX T1,GJ%SHT!GJ%OLD ;FILE MUST EXIST.
HRROI T2,[ASCIZ/SYSTEM:INTERNET-ETHERNET-MAPPINGS.BIN/]
GTJFN% ;LOOK FOR THE FILE
ERJMP R ;ERROR
MOVEM T1,INTJFN ;SAVE THE JFN
MOVX T2,^D36B5!OF%RD ;36 BIT READ ACCESS
OPENF% ;OPEN UP THE JFN
ERJMP R ;ERROR
MOVEM T1,INTJFN ;SAVE THE JFN
MOVEI T2,HDRS ;POINT TO TEMP HEADER STORAGE
IOR T2,[POINT 36,] ;FORM BYTE POINTER TO HEADERS
MOVEI T3,NIHMHL ;READ THE WHOLE HEADER
SIN
ERJMP R ;ERROR
XMOVEI T1,HDRS ;POINT AT TEMP HEADER AREA AGAIN
MOVE T2,.NICHK(T1) ;GET THE FILE CHECKSUM
MOVEM T2,INTCKS ;AND SAVE IT AWAY
MOVE T2,.NILEN(T1) ;GET NUMBER OF WORDS LEFT
MOVEM T2,GHTLEN ;SAVE THE COUNT
MOVEM T2,TMPLEN
IDIVI T2,NIHMDL ;MAKE SURE COUNT IS MULTIPLE OF PER HOST LENGTH
JUMPN T3,[RETBAD <IPHCNT>] ;IF REMAINDER, THEN COUNT IS BAD
MOVEM T2,GHTCT1 ;SAVE # OF ENTRIES
RETSKP
ENDSV. ;END OF NIHOPN STKVAR
;NIHSPC - GET AND SET UP NEW GHT SPACE
;
; Called from NIHINI to get Internet free space for a new ght.
;
; Returns + 1 on error, error code in T1
; + 2 on success, address of block in T1
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
NIHSPC: STKVAR <GHSIZ>
MOVE T1,NIMAXH ;GET MAX HOSTS IN GHT
IMULI T1,NIHMDL+1 ;COMPUTE SPACE FOR AREA 2
ADD T1,NIMAXH ;NOW ADD IN SPACE FOR AREA 1
MOVEM T1,GHSIZ ;SAVE THE SIZE
CALL GETBLK ;GET A BLOCK IP FREE SPACE
JUMPE T1,[RETBAD <IPHNSP>] ;RETURN NO SPACE ERROR TO CALLER
MOVE T2,GHSIZ ;GET BUFFER SIZE
CALL NIPLKB ;LOCK THE GHT
MOVEM T1,GHTPT1 ;SAVE THE POINTER TO THE NEW GHT
MOVE P1,T1 ;COPY AREA 1 POINTER
MOVE P2,T1 ;GET ADR OF AREA 1
ADD P2,NIMAXH ;CALCULATE ADR OF AREA 2
MOVEM P2,GHTPT2 ;SAVE AS TEMPORARY POINTER TO AREA 2
CALL CLRBLK ;CLEAR OUT THE BLOCK (USES T1 AND T2)
RETSKP
ENDSV. ;END OF NIHSPC STKVAR
;NIHREL - RELEASE OLD GHT STORAGE
;
; Called from NIHINI to release any storage used by an old ght.
;
; T1/ Address of the block
;
; Returns + 1 always
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
NIHREL: MOVE T2,NIMAXH ;GET MAX HOSTS IN GHT
IMULI T2,NIHMDL+1 ;COMPUTE SPACE FOR AREA 2
ADD T2,NIMAXH ;NOW ADD IN SPACE FOR AREA 1
CALL NIPULK ;UNLOCK THE SPACE
CALL RETBLK ;RELEASE IT
RET
;NIHFIN - FINISH UP GHT PROCESSING
;
; Called from NIHINI and NIHERR to update the GHTAR1 and GHTAR2
; locations and to close the file.
;
; GHTPT1/ new pointer to area 1 of the ght
; GHTPT2/ new pointer to area 2 of the ght
; GHTCT1/ number of entries in the ght
; INTJFN/ jfn of the ght file
;
; Returns + 1 always
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
;**;[7450] Replace 6 lines with 16 lines at NIHFIN JMP Apr 9 87
NIHFIN: NOSKED ;[7450] MAKE SURE NO ONE INTERFERES
SKIPE GHTLOK ;[7450] IS GHT STABLE ?
IFSKP. ;[7450]
MOVE T1,GHTPT2 ;[7450] YES - GET TEMPORARY POINTER
MOVEM T1,GHTAR2 ;[7450] EQUALS NEW POINTER TO AREA 2
MOVE T1,GHTCT1 ;[7450] GET COUNT BACK
MOVEM T1,GHTCNT ;[7450] SAVE IT AS THE REAL COUNT
MOVE T1,GHTPT1 ;[7450] GET THE NEW AREA
EXCH T1,GHTAR1 ;[7450] AND EXCHANGE WITH THE OLD ONE
ELSE. ;[7450]
OKSKED ;[7450] NO - GHT IS BEING UPDATED
MOVEI T1,1 ;[7450] WAIT A SECOND
DISMS ;[7450]
JRST NIHFIN ;[7450] TRY AGAIN
ENDIF. ;[7450]
OKSKED ;[7450] ALL IS SAFE AGAIN
SKIPE T1 ;IS THE OLD POINTER ZERO ?
CALL NIHREL ;NO. RELEASE THE OLD TABLE SPACE
SKIPE T1,INTJFN ;GET OUR JFN AGAIN
CLOSF ;CLOSE THE FILE IF WE HAD A JFN
ERJMP .+1 ;WHO CARES IF ERROR HERE
SKIPN NIPON ;IS IPNI CODE INIT'D YET
IFSKP.
MOVE NCT,NIPNCT ;GET OUR NCT
CALL INTUNB ;GET THE INTERNET UN BLOCK
RETBAD
CALL RETUNB ;RETURN THE UN BLOCK
ENDIF.
RET
;NIHERR - ERROR IN PROCESSING THE GHT FILE
;
; Called here from any number of places while processing the GHT
; file. Since IPNIDV requires a GHT, this routine will leave the
; existing GHT in place, or if no GHT has been assigned, it will
; use the space that we've just gotten for the GHT.
;
; T1/ error code
;
; Returns + 1 always with error code in T1
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
NIHERR: MOVEM T1,NIPERR ;SAVE THE ERROR CODE
SETZM GHTCT1 ;TEMPORARY COUNT IS NO GOOD
SKIPN T1,GHTAR1 ;HAVE CURRENT GHT POINTER ?
IFSKP.
MOVE T1,GHTPT1 ;YES - KEEP REAL GHT, RELEASE THE NEW ONE
CALL NIHREL ;RELEASE THE SPACE
ELSE.
CALL NIHFIN ;NO GHT, CLOSE FILE AND UPDATE GHTxxx
ENDIF.
MOVE T1,NIPERR ;GET THE ERROR CODE BACK
RET
ENDTV. ;END OF NIHINI TRVAR
;NIHINV - INVALIDATE ALL GHT ENTRIES
;
; Called by the NIPSRV whenever an address change callback has
; occured which changes our ethernet address to something new
; and arp is turned on. This routine turns off the GH%ARP flag
; in the flags word of each ght area 2 entry.
;
; Returns + 1 always
IFE REL6,<RESCD>
IFN REL6,<XRESCD>
NIHINV: MOVX T3,GH%ARP ;GOING TO TURN OFF THIS FLAG
PIOFF ;NO INTERRUPTIONS
MOVE T1,GHTCNT ;GET NUMBER OF ENTRIES
MOVE T2,GHTAR2 ;GET POINTER TO AREA 2
ADDI T2,GH.GCF ;POINT AT EACH ENTRIES FLAG WORD
NINV1: ANDCAM T3,(T2) ;TURN OFF THIS ENTRY'S FLAG
ADDI T2,GH2MDL ;POINT TO THE NEXT
SOJG T1,NINV1 ;DECREMENT ENTRY COUNTER AND TRY NEXT IF MORE
NINV2: PION ;ALLOW THE REST OF THE MACHINE
SETZM NIPGTF ;CLEAR FLAG THAT GOT US HERE
CALL WERHER ;TELL KNOWN HOSTS OUR NEW ADDRESS
RET
SUBTTL Internet to Ethernet Address Translation
;INTSRC - INTERNET HOST NUMBER SEARCH
;
; Search for the entry in the gateway host table that matches
; the Internet host number in T2.
;
; T2/ Internet host # to search for
;
; Returns + 1 if not found, T1/ area 1 adr where entry could be inserted
; T2/ area 2 adr where entry could be inserted
; + 2 on success, T1/ area 1 address of entry that matched
; T2/ area 2 address of entry that matched
IFE REL6,<RESCD>
IFN REL6,<XRESCD>
INTSRC: SAVEAC <P1,P2,P3> ;SAVE LOW, MIDDLE, AND HIGH
SETZB P1,P2 ;INIT LOW (AND MIDDLE) TO ZERO
MOVE T1,GHTAR1 ;GET POINTER TO AREA1
SKIPN P3,GHTCNT ;GET TABLE LENGTH IF ANY, AND MAKE IT HIGH
CALLRET ISNFND ;NO ENTRIES, NOT FOUND THEN
CAIGE P3,SRCMAX ;USE SEQUENTIAL OR BINARY SEARCH
CALLRET SEQSRC ;SEQUENTIAL
;**;[7450] Insert 1 line at INTSRC+6L JMP Apr 8 87
SOS P3 ;[7450] MAKE IT OFFSET TO LAST ENTRY
ISRCH: MOVE P2,P3 ;BUILD MIDDLE BY TAKING THE HIGH
SUB P2,P1 ;SUBTRACT THE LOW
LSH P2,-1 ;HALVING IT
ADD P2,P1 ;AND ADDING THE LOW
MOVE T1,GHTAR1 ;GET GHT ADR
ADD T1,P2 ;POINT TO GHT(MIDDLE)
CAMN T2,(T1) ;DOES MIDDLE ENTRY MATCH THE HOST #
CALLRET ISFND ;FOUND IT
CAMG T2,(T1) ;HOST # .GT. MIDDLE ?
IFSKP.
MOVEI P1,1(P2) ;YES. LOW = MIDDLE + 1
;**;[7450] Insert 2 lines at ISRCH+10.L JMP Apr 8 87
AOS T1 ;[7450] ADJUST TO CORRECT INSERTION POINT
AOS P2 ;[7450] IN CASE LAST EXAMINED IS LT HOST
JRST ISCHK ;CHECK FOR ALL ENTRIES HAVING BEEN SEARCHED
ENDIF.
JUMPE P2,ISNFND ;IF MIDDLE IS ZERO, DONE - NOT FOUND
MOVEI P3,-1(P2) ;NO. HIGH = MIDDLE - 1
ISCHK: CAML P3,P1 ;HIGH AND LOW MEET YET ?
JRST ISRCH ;NO. WE HAVE MORE CHECKING TO DO
CALLRET ISNFND ;ENTRY NOT FOUND
SUBTTL Internet Address Translation - High Speed Sequential Search
;SEQSRC - USE SEQUENTIAL SEARCH FOR CHECKING GHT
;
; Search backwards for the entry in the gateway host table that
; matches the Internet host number in T2.
;
; T1/ Pointer to area 1 of ght
; T2/ Internet host # to search for
; P3/ Number of entries in the table
;
; Returns + 1 if not found, T1/ area 1 adr where entry could be inserted
; T2/ area 2 adr where entry could be inserted
; + 2 on success, T1/ area 1 address of entry that matched
; T2/ area 2 address of entry that matched
IFE REL6,<RESCD>
IFN REL6,<XRESCD>
SEQSRC: MOVEI P2,-1(P3) ;GET THE OFFSET OF THE LAST ENTRY
SEQSR1: MOVE P3,T1 ;GET AREA 1 POINTER
ADD P3,P2 ;ADD IN THE OFFSET TO BEGINNING OF THE TABLE
CAME T2,(P3) ;DO THE ENTRIES MATCH
IFSKP.
ADD T1,P2 ;YES - FOUND IT. UPDATE GHT 1 POINTER
CALLRET ISFND
ENDIF.
CAMG T2,(P3) ;HOST # LESS THAN THIS ENTRY
SOJGE P2,SEQSR1 ;YES - POINT TO PREVIOUS ENTRY
AOS P2 ;POINT TO ENTRY WHERE THIS HOST CAN BE INSERTED
ADD T1,P2 ;UPDATE GHT 1 POINTER
CALLRET ISNFND ;NOT FOUND
;Here when the host we were looking for is in the ght
IFE REL6,<RESCD>
IFN REL6,<XRESCD>
ISFND: MOVE T2,P2 ;GET MATCHING ENTRY
IMULI T2,GH2MDL ;MAKE OFFSET INTO AREA 2
ADD T2,GHTAR2
RETSKP ;FOUND
;Here when the host we were looking for was not in the ght
IFE REL6,<RESCD>
IFN REL6,<XRESCD>
ISNFND: MOVE T2,P2 ;GET ENTRY WHERE IT SHOULD BE
IMULI T2,GH2MDL ;MAKE OFFSET INTO AREA 2
ADD T2,GHTAR2
RET ;NOT FOUND
SUBTTL Ethernet Internet Host Pinger
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
WERHER: ; Here to ping all hosts in GHTAR1
SKIPN T1,GHTCNT ; Get the count of entries
RET ; If none then we are all done
MOVE T2,GHTAR1 ; Get area one address
WERHE1: ; Top of pinging loop
MOVE T3,(T2) ; Get an internet address
CALL SNDNOP ; Send him a NOP
SOSLE T1 ; Done them all yet?
AOJA T2,WERHE1 ; No so do the next one
RET ; and return to caller
SNDNOP: ; Here to send a nop to adr in T3
SAVEAC <T1,T2,P1,PKT,CPKT>
STKVAR <SNOPA>
MOVEM T3,SNOPA ; Save the target address
MOVEI T1,<PKTELI+<<MINIHS+3>/4>+2> ;Echo packet size
CALL GETBLK ; Get some free space
SKIPN PKT,T1 ; Did we get the space?
RET ; No so we are all done
MOVEI T2,<PKTELI+<<MINIHS+3>/4>+2> ;Echo packet size
CALL CLRBLK ; Zero out the block
MOVE T1,[BYTE (8)105,0,0,<8+MINIHS>]
MOVEM T1,PKTELI+.IPKVR(PKT) ; Set version, length
MOVEI T1,3 ; Ping "lifetime"
STOR T1,PITTL,(PKT) ; Set time to live field
MOVEI T1,.ICMFM ; Protocol is ICMP
STOR T1,PIPRO,(PKT) ; Set protocol type field
MOVEI CPKT,<<MINIHS+3>/4>+PKTELI ; Min. Internet header size
ADD CPKT,PKT ; Pointer to ICMP Section
MOVE P1,NIPNCT ; Get out NCT
MOVE T1,SNOPA ; Get the destination address
STOR T1,PIDH,(PKT) ; Make it go there
MOVE T2,NTLADR(P1) ; Get our address on the NI
STOR T2,PISH,(PKT) ; That will be the source address
MOVEI T3,ICM%EC ; Message type is ECHO
STOR T3,CMTYP,(CPKT) ; Set into ICMP message type field
SETZRO CMCOD,(CPKT) ; Clear code word
SETONE CMID,(CPKT) ; (Make field non-zero)
AOS T1,ICMSID ; Get an Id
STOR T1,CMSEQ,(CPKT) ; Set ICMP sequence number
STOR T1,PISID,(PKT) ; Set IP sequence number
CALL ICMCKS ; Compute checksum of the packet
STOR T1,CMCKS,(CPKT) ; Insert in packet
CALL SNDGAT ; Send it off
RET ; and return
SUBTTL Address Resolution Protocol - Initialization
;ARPINI - INITIALIZE ARP
;
; Called when the Address Resolution Protocol is to be used.
; Enables the Arp multicast address "-1".
;
; Returns + 1 on errors with T1/ error code
; + 2 on success
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
ARPINI::SAVEAC <SRV,NCT,ARP,UNB,RID>
SKIPE ARPON ;IS ARP ALREADY ON ?
JRST ARPIN1 ;YES - DON'T REPORT ANY ERROR, GIVE SUCCESS
MOVE NCT,NIPNCT ;GET THE NCT ADDRESS
MOVE T1,NIPON ;GET "ON" FLAGS
CAIGE T1,NI.ON ;MUST ATLEAST HAVE IPNI PORTAL RUNNING
RETBAD <IPARP1> ;CAN'T START ARP UNTIL THEN
CALL ARPOPN ;OPEN THE PORTAL
RETBAD ;COULDN'T
MOVE UNB,AUNBLK ;GET THE ARP UN BLOCK
CALL ARPGIB ;GET AND SET UP BUFFERS
RETBAD ;COULDN'T
SETONE UNDAD,(UNB) ;DESTINATION IS BROADCAST (ALL ONES)
SETONE UNDAD,+1(UNB)
SETZRO UNRSP,(UNB) ;NO RESPONSE CALLBACK
MOVX T1,NU.EMA ;SET FUNCTION CODE TO ENABLE MULTICAST
MOVE T2,UNB ;POINT AT UN BLOCK
CALL DLLUNI ;ENABLE IT
RETBAD ;COULDN'T
CALL NISTAT ;GET THE STATUS AND HARDWARE ADDRESS
RETBAD ;COULDN'T
SETOM ARPENA ;LET INTERNET KNOW THAT IT IS ENABLED
SETOM ARPON ;ARP IS NOW ON
ARPIN1: RETSKP
SUBTTL Address Resolution Protocol - Open NISRV Portal
;ARPOPN - OPEN A PORTAL FOR ARP SERVICE
;
; Called from the ARP start up code to open a portal. This
; routine grabs some Internet free space and locks it for a UN
; block. It then sets up the UN block and does an OPEN function.
;
; NCT/ address of the nct
;
; Returns + 1 on error, error code in T1
; + 2 on success
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
ARPOPN: SKIPE UNB,AUNBLK ;GET UN BLOCK ADR FOR THIS TYPE OF SERVICE
JRST ARPO1 ;ALREADY HAVE ONE
MOVEI T1,UN.LEN ;GET SPACE FOR A UN BLOCK
CALL GETBLK ;GET IT FROM THE IP FREE SPACE
IFE. T1 ;GOT A BUFFER IF NON-ZERO
BUG.(CHK,IPFNSP,IPNIDV,SOFT,<No free space for UN block for ARP>,,<
Cause: The monitor attempted to assign some free space for the storage
of ARP UN blocks and none was available.
>)
RETBAD <NI.ER5> ;FATAL ERROR FOR IPNI
ENDIF.
MOVEM T1,AUNBLK ;SAVE UN BLOCK POINTER, UPDATE UNB
MOVE UNB,T1 ;PUT IT WHERE IT SHOULD BE
MOVEI T2,UN.LEN ;UN BLOCK LENGTH
CALL NIPLKB ;LOCK IT
ARPO1: MOVEI T1,APROTO ;GET PROTO TYPE FOR ARP
SETZ T2, ;NO PORTAL ID SET YET
MOVEI SRV,NI.ARP ;SET THE SERVICE TYPE
CALL UNSET ;SET UP THE UN BLOCK
MOVX T1,NU.OPN ;OPEN NI PORT FUNCTION
MOVE T2,UNB ;POINT AT THE UN BLOCK
CALL DLLUNI ;CALL NI DRIVER
RET ;TAKE ERROR RETURN. NI ERROR CODE IN T1
RETSKP
SUBTTL Address Resolution Protocol - Buffer Routines
;ARPGIB - GET AND INITIALIZE BUFFERS
;
; Called to get both input and output buffers for ARP.
;
; Returns + 1 on error, T1/ error code
; + 2 on success
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
ARPGIB: STKVAR <SWITCH,CNTDWN>
SETZM SWITCH ;INIT SO THAT THE 1ST BUFFER IS FOR INPUT
CALL ARPBUF ;GET A BUFFER
JUMPE T1,[RETBAD] ;DIDN'T GET A BUFFER IF 0
MOVEM T1,ABUFFR ;SAVE ADDRESS OF THIS BIG BUFFER
LSH T2,-1 ;ONLY 1/2 OF THE BUFFERS ARE FOR INPUT
MOVEM T2,CNTDWN ;SAVE NUMBER OF BUFFERS WE GOT
MOVE ARP,T1 ;SAVE THE BUFFER POINTER
SETZM ARPNFI ;CLEAR OUT THE OLD COUNT
SETZM ARPFRI ;AND THE OLD POINTER
ARPGB1: MOVE T1,ARPNFI ;GET NUMBER OF FREE BUFFERS
CAML T1,CNTDWN ;BELOW DESIRED LEVEL?
RETSKP ;NO
SETZRO ARPNT,(ARP) ;CLEAR POINTER TO NEXT
SETCMM SWITCH ;COMPLIMENT THE "USE BUFFER FOR INPUT"
SKIPN SWITCH ;SHOULD BUFFER BE USED FOR INPUT ?
IFSKP.
SETONE ARTYP,(ARP) ;FLAG AS AN INPUT BUFFER
MOVE T1,ARP ;YES - GET THE BUFFER ADDRESS
CALL ARPOST ;POST IT
RETBAD ;COULDN'T
ELSE.
CALL ARPQIT ;PUT BUFFER ON THE FREE LIST QUEUE
MOVX T2,AR.ETH ;NO - SET UP CONSTANT DATA FOR SEND BUFFERS
STOR T2,AR$HD,(ARP) ;SET HARDWARE TYPE AS ETHERNET
MOVX T2,IPROTO ;SET ETHERNET PROTOCOL TYPE TO INTERNET
STOR T2,AR$PR,(ARP)
MOVX T2,AR.HLN ;SET HARDWARE ADDRESS LENGTH FOR ETHERNET
STOR T2,AR$HL,(ARP)
MOVX T2,AR.PLN ;SET PROTOCOL ADDRESS LENGTH FOR INTERNET
STOR T2,AR$PL,(ARP)
MOVX T2,AR.REQ ;OPCODE IS REQUEST
STOR T2,AR$OP,(ARP)
ENDIF.
ADDI ARP,AR.WRD ;POINT TO ADDRESS IF NEXT BUFFER
JRST ARPGB1 ;SEE IF ENOUGH
ENDSV. ;END OF ARPGIB STKVAR
;ARPQIT - PUT BUFFER ON FREE QUEUE
;
; Here from ARPGIB to put the buffer on the free queue
;
; ARP/ address of the buffer
;
; Returns + 1 always
IFE REL6,<RESCD>
IFN REL6,<XRESCD>
ARPQIT: PIOFF
MOVE T2,ARP
EXCH T2,ARPFRI ;ADD TO LIST OF FREE INPUT BUFFERS
STOR T2,ARPNT,(ARP) ;OLD LIST IS SUCCESSOR OF THIS BUF
AOS ARPNFI ;BUMP THE COUNT TO MATCH
PION
RET
;ARPBUF - GET A BUFFER
;
; Called to get a buffer. One buffer should hold aprox 16 ARP
; packets based on a MAXWPM set to 370 words as buffer size.
;
; Returns + 1 always, T1/ beginning address of the buffer
; T2/ number of ARP buffers available
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
ARPBUF: SKIPN T1,ABUFFR ;ALREADY HAVE A BUFFER ?
IFSKP.
SUBI T1,MAXLDR ;YES - POINT AT BEGINNING
JRST ARPBF1
ENDIF.
CALL NIPBFR ;GET A BUFFER
SKIPE T1 ;DID WE GET ONE ?
IFSKP.
BUG. (CHK,IPNARP,IPNIDV,SOFT,<No buffer space for ARP>,,<
Cause: The monitor attempted to assign a buffer for use by ARP and
none were available.
>)
RET
ENDIF.
ARPBF1: LOAD T2,NBBSZ,(T1) ;GET BUFFER SIZE
SUBI T2,LCLPKT+MAXLDR ;DON'T INCLUDE LEADER SIZE
ADDI T1,MAXLDR ;FOR CONSISTENCY WITH OTHER BUFFERS
IDIVI T2,AR.WRD ;GET NUMBER OF BUFFERS
CAIL T2,AR.TNB ;GET ENOUGH BUFFERS ?
RET ;YES
BUG. (INF,IPFRAB,IPNIDV,SOFT,<Fewer than required ARP buffers assigned>,,<
Cause: The monitor has assigned a buffer for use by ARP but further analysis
shows that the buffer is not large enough for the number of messages
ARP wants to allow.
>)
RET
;ARPBFR - GET AN INPUT BUFFER
;
; Returns + 1 always with T1 containing the buffer address
IFE REL6,<RESCD>
IFN REL6,<XRESCD>
ARPBFR: PIOFF
SOSL ARPNFI ;COUNT DOWN NUMBER OF FREE INTERNET BUFS
SKIPN T2,ARPFRI ;GET POINTER TO BUFFER TO USE
IFNSK.
AOS ARPNFI ;NO BUFFERS AVAILABLE. DON'T LET COUNT GO NEG.
PION ;MAKE SURE INTERRUPTS ARE BACK ON
BUG.(CHK,IPABFL,IPNIDV,SOFT,<ARP input buffer list fouled>,,<
Cause: The internet ethernet software has detected that the buffer list for
the ARP protocol is smashed. This probably indicates a software
problem.
>)
SETZ T1, ;FLAG TO NIPOST THAT WE HAVE NO BUFFER
RETBAD ;TRY TO RECOVER
ENDIF.
LOAD T1,ARPNT,(T2) ;NEXT INTERNET FREE BUFFER
SETSEC T1,INTSEC ;YES SO SET THE SECTION NUMBER
SETZRO ARPNT,(T2) ;CLEAR LIST POINTER
MOVEM T1,ARPFRI ;BECOMES HEAD OF LIST
PION ;MAKE SURE INTERRUPTS ARE BACK ON
MOVE T1,T2 ;PUT THE ADDRESS WHERE IT'S EXPECTED
RET
SUBTTL Address Resolution Protocol - Send ARP Message
;ARPSND - BUILD AND SEND AN ARP MESSAGE
;
; Called from the NISEND routine when it found out that the
; Internet routing host number was not found in the GHT. We
; discard the IP datagram by putting it on the Internet free
; queue and generate an ARP packet requesting the Ethernet
; address of that Internet host.
;
; Alternate entry point ARPSD1 is called from ARPRCV to send a
; reply ARP packet. It sets up the variable data of ARP packet
; and UN block. The UN block address is that specified by NISRV.
;
; RID/ address of the IP buffer
;
; Returns + 1 on error, T1/ error code
; + 2 on success
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
ARPSND: SAVEAC <SRV,ARP,NCT,UNB,RID>
MOVE NCT,NIPNCT ;GET THE NCT ADDRESS
MOVE UNB,AUNBLK ;GET THE UN BLOCK POINTER
CALL ARPBFR ;GET A BUFFER TO USE
JUMPE T1,R ;NONE AVAILABLE IF ZERO, ARPBFR BUGINF'D
MOVE ARP,T1
MOVE T2,NI.HOP(RID) ;PROTOCOL TARGET ADR IS INTERNET ROUTING ADR
STOR T2,AR$TA,(ARP)
MOVX T2,AR.REQ ;OPCODE IS REQUEST
STOR T2,AR$OP,(ARP)
ARPSD1: DMOVE T2,ETHADR ;GET OUR CURRENT ETHERNET ADDRESS
LSH T2,-4 ;SHIFT RIGHT BECAUSE ETHADR IS FULL WORD
STOR T2,AR$S1,(ARP) ; AND AR$S1 IS 32 BITS. SAVE IT
LSH T3,-^D20 ;SHIFT RIGHT BECAUSE ETHADR+1 IS FULL WORD
STOR T3,AR$S2,(ARP) ; AND AR$S2 IS 16 BITS. SAVE IT
MOVE T2,NTLADR(NCT) ;GET OUR INTERNET HOST NUMBER
LSHC T2,-^D16 ;HIGH 2 BYTES IN T2
LSH T3,-^D20 ;LOW 2 BYTES IN T3
STOR T2,AR$P1,(ARP)
STOR T3,AR$P2,(ARP)
NOSKED ;DON'T LET OTHERS IN HERE
XMOVEI T2,ARPPKT(ARP) ;POINT AT DATA PORTION OF BUFFER
TXO T2,<OWGP. 8,> ;FORM BYTE POINTER TO BUFFER
STOR T2,UNBFA,(UNB) ;SAVE THE BYTE POINTER AWAY AS BUFFER ADR
STOR ARP,UNRID,(UNB) ;SAVE BUFFER ADR AS REQUEST ID
MOVEI T1,AR.LEN ;GET ARP PACKET LENGTH
STOR T1,UNBSZ,(UNB) ;SAVE LENGTH FOR NISRV
MOVX T1,NU.XMT ;SET FUNCTION CODE TO TRANSMIT
MOVE T2,UNB ;POINT AT UN BLOCK
CALL DLLUNI ;SEND THE BUFFER
RETBAD <>,<OKSKED> ;NI RETURNED ERROR
OKSKED ;OKAY FOR OTHERS
RETSKP
SUBTTL Address Resolution Protocol - Post ARP Receive Buffer
;ARPOST - POST AN ARP INPUT BUFFER
;
; This routine gives NISRV a receive buffer. The buffer must
; be resident.
;
; T1/ address of input buffer
; UNB/ address of the UN block
;
; Returns + 1 if error returned from NISRV
; + 2 on success
IFE REL6,<RESCD>
IFN REL6,<XRESCD>
ARPOST: SKIPN T1 ;ZERO IF NIPBFR COULDN'T GET A BUFFER
RETBAD <NI.ER1> ;RETURN THE ERROR
MOVEI T3,AR.MAX ;GET MAX PACKET SIZE
STOR T3,UNBSZ,(UNB) ;SAVE IT AS RECEIVE BUFFER SIZE
STOR T1,UNRID,(UNB) ;SAVE INPUT BUFFER ADR AS REQUEST ID
ADDI T1,ARPPKT ;POINT PAST HEADER FOR START OF ARP PACKET
TXO T1,<OWGP. 8,> ;FORM BYTE POINTER TO BUFFER
STOR T1,UNBFA,(UNB) ;SAVE AS THE BUFFER ADDRESS
MOVX T1,NU.RCV ;POST RECEIVE BUFFER FUNCTION
MOVE T2,UNB ;GET UN BLOCK ADR
CALL DLLUNI ;CALL NISRV
CALLRET POSTER ;NISRV RETURNED ERROR
RETSKP ;SUCCESS
;ARPKIL - SHUTDOWN ARP
;
; Called from the IPOPR to shut off ARP communications.
;
; Alternate entry point ARPKL1 is called from NIPKIL. This
; leaves ARPENA on for later use of ghts.
;
; Returns + 2 always
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
ARPKIL::SETZM ARPENA ;CLEAR THE ENABLE FLAG
ARPKL1: MOVE UNB,AUNBLK ;GET THE ARP UN BLOCK
MOVX T1,NU.CLO ;NI CLOSE FUNCTION
MOVE T2,UNB ;GET UN BLOCK ADDRESS
CALL DLLUNI ;DO THE CLOSE
JFCL
SETZM ARPON ;CLEAR ARP ON FLAG
RETSKP
SUBTTL ARP Datagram Sent Callback
;ARPCDS - ARP DATAGRAM SENT
;
; Called when the ARP packet has been sent. It puts the buffer
; back on the free buffer list.
;
; T2/ UN block address
; T3/ 0 if function succesfull or error code
; UNRID/ address of buffer
;
; Returns + 1 on error
; + 2 on success
IFE REL6,<RESCD>
IFN REL6,<XRESCD>
ARPCDS: MOVE UNB,T2 ;SAVE UN BLOCK ADDRESS
LOAD ARP,UNRID,(UNB) ;GET THE BUFFER ADDRESS TO RELEASE
MOVE T2,ARP ;COPY FOR INDEXING
PIOFF
EXCH T2,ARPFRI ;ADD TO LIST OF FREE INPUT BUFFERS
STOR T2,ARPNT,(ARP) ;OLD LIST IS SUCCESSOR OF THIS BUF
AOS ARPNFI ;BUMP THE COUNT TO MATCH
PION
SKIPE T1,T3 ;DID WE HAVE AN ERROR?
CALLRET CDSERR ;YES SO PROCESS IT
RETSKP ;NO ERROR SO SUCCESS RETURN
SUBTTL ARP Datagram Received Callback
;ARPCDR - DATAGRAM RECEIVED
;
; The NI received an ARP datagram. The address is available
; in UNRID of the UN block.
;
; T2/ UN block address
; T3/ 0 if function succesfull or error code
; UNRID/ address of buffer
;
; Returns + 1 on error
; + 2 on success
IFE REL6,<RESCD>
IFN REL6,<XRESCD>
ARPCDR: LOAD T1,UNRID,(T2) ;GET THE ADDRESS OF THE BUFFER
JUMPN T3,[CAIN T3,UNRAB% ;CHANNEL SHUTTING DOWN ?
RETBAD <>,<MOVE T1,T3> ;YES - DO NOTHING
AOS NIICNT ;NO. BUMP THE INPUT ERROR COUNTER
MOVE UNB,T2 ;USE NISRV UN BLOCK TO REPOST BUFFER
CALLRET ARPOST] ;USE THIS BUFFER OVER
MOVE NCT,NIPNCT ;GET OUR NCT
PIOFF ;DON'T ALLOW US TO BE INTERRUPTED
MOVE T3,NTLOBI(NCT) ;QUEUE FOR PROCESSING BY INTERNET FORK
JUMPN T3,ACDRQ1 ;ANYTHING ELSE ON THE LIST ?
MOVEM T1,NTLOBO(NCT) ;ONLY THIS ITEM IN THE LIST
SKIPA
ACDRQ1: STOR T1,ARPNT,(T3) ;LINK IT IN
MOVEM T1,NTLOBI(NCT) ;NEW POINTER
AOS INTFLG ;CAUSE INTERNET TO NOTICE IT.
AOS PSKD1 ;MAKE THE SCHEDULER NOTICE THIS IF IN NULL JOB
PION
RETSKP ;GIVE GOOD RETURN
SUBTTL ARP Processing by the Internet Fork
;ARPPRC - ARP PACKET PROCESSOR
;
; Called by NIPSRV by the internet fork to process any ARP
; packets that have been sent to us. After the packet has
; been processed, the input buffer is given back to NISRV.
;
; NTLOBO/ Local network (ARP) list head pointer
; NTLOBI/ Tail pointer
;
; Returns + 1 always
IFE REL6,<RESCD>
IFN REL6,<XRESCD>
;**;[7450] Change some comments in the ARPRO1 code JMP Apr 8 87
;**;[7450] Also insert 1 line at ARPRO1+8L and +10 L JMP Apr 8 87
ARPPRC: SAVEAC <SRV,ARP,RID,NCT,UNB>
MOVE NCT,NIPNCT ;GET OUR NCT ADDRESS
MOVE UNB,AUNBLK ;GET THE ARP UN BLOCK POINTER
ARPRO1: SKIPN ARP,NTLOBO(NCT) ;[7450] ANY ARP PACKETS TO PROCESS ?
RET ;NO
PIOFF ;NO INTERRUPTS
LOAD T2,ARPNT,(ARP) ;GET ITS SUCCESSOR
SKIPN T2 ;SKIP IF NOT LAST ONE
SETZM NTLOBI(NCT) ;YES. MAKE QUEUE NULL
MOVEM T2,NTLOBO(NCT) ;[7450] UPDATE ARP QUEUE POINTER
SETZRO ARPNT,(ARP) ;[7450] DEQUEUE PACKET FROM ITS OLD CHAIN
PION ;ALLOW INTERRUPTS AGAIN
SETOM GHTLOK ;[7450] LOCK THE GHT FROM OUTSIDE UPDATES
CALL ARPRCV ;GO PROCESS THE PACKET
JFCL ;ERROR. IGNORE IT
SETZM GHTLOK ;[7450] OKAY TO UNLOCK THE GHT NOW
MOVE T1,ARP ;GET PACKET ADDRESS BACK
CALL ARPOST ;RE-POST IT
RETBAD
JRST ARPRO1 ;GO TRY FOR ANOTHER
SUBTTL ARP Incoming Packet Processing
;ARPRCV - PROCESS INCOMING ARP PACKETS
;
; Called to process an incoming ARP packet. Provided that the
; packet is accepted, this routine updates the GHT with
; information about the host that sent the packet. If the packet
; is a request for us, we will generate a reply message.
;
; ARP/ address of the buffer
; UNB/ address of the UN block
; NCT/ NCT address
;
; Returns + 1 on error with T1/ error code
; + 2 on success
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
ARPRCV: TRVAR <AREA1,AREA2,SPADR,<SHADR,2>>
SAVEAC <ARP> ;SAVE THE CURRENT ARP POINTER
LOAD T1,AR$HD,(ARP) ;GET HARDWARE TYPE
LOAD T2,AR$PR,(ARP) ;GET PROTOCOL TYPE
CAIN T1,AR.ETH ;IS IT ETHERNET HARDWARE ?
CAIE T2,IPROTO ;YES - IS IT INTERNET PROTOCOL
RET ;NO, IGNORE THE PACKET
LOAD T1,AR$HL,(ARP) ;GET LENGTH OF HARDWARE ADDRESS
LOAD T2,AR$PL,(ARP) ;GET LENGTH OF PROTOCOL ADDRESS
CAIN T1,AR.HLN ;HARDWARE ADR LENGTH SAME AS OUR'S ?
CAIE T2,AR.PLN ;YES - PROTOCOL LENGTH SAME AS OUR'S ?
RET ;NO, IGNORE THE PACKET
LOAD T1,AR$S1,(ARP) ;GET ETHERNET ADR (WORD 1) OF SENDER
LSH T1,4 ;SHIFT LEFT, OUR ADR IS LEFT ADJUSTED
LOAD T2,AR$S2,(ARP) ; AND THE 2ND WORD
LSH T2,^D20 ;ALIGN THE 2ND WORD TO THE LEFT
DMOVEM T1,SHADR ;SAVE AWAY THE NEW DATA
LOAD T1,AR$P1,(ARP) ;GET WORD 1 OF INTERNET ADDRESS
LOAD T2,AR$P2,(ARP) ;GET WORD 2 OF INTERNET ADDRESS
DPB T1,[POINT 16,T2,19] ;FORM REAL INTERNET ADDRESS IN T2
MOVEM T2,SPADR ;SAVE SENDER PROTOCOL ADDRESS
CALL INTSRC ;THIS HOST IN THE GHT ?
JRST ARPRC1 ;NO, POSSIBLE ENTRY INSERTION NEEDED
MOVE T3,T2 ;COPY GHT POINTER
DMOVE T1,SHADR ;GET SENDERS HARDWARE ADDRESS
DMOVEM T1,GH.EN1(T3) ;SAVE AS ETHERNET ADDRESS
MOVX T1,GH%ARP ;GET UPDATED BY ARP FLAG
IORM T1,GH.GCF(T3) ;SET IT IN THE GHT
SETZB T1,T2 ;NO INSERT OF ENTRY NEEDED NOW
ARPRC1: MOVEM T1,AREA1 ;SAVE AREA 1 POINTER
MOVEM T2,AREA2 ;SAVE AREA 2 POINTER
CALL ARPRC2 ;NEXT STEP, PROCESS OPCODE
RETBAD ;GO AN ERROR OR IGNORE PACKET
RETSKP
;ARPRC2 - STEP 2 OF PROCESSING INCOMING ARP PACKETS
;
; This routine checks to see if the ARP packet was actually sent
; to us and checks to see if it was a request. If it was to us,
; and the insert flag is on, we add the information to the GHT.
; If the packet is a request, we send a reply.
;
; AREA1/ 0 if merge was done or adr of ght area 1 if insertion needed
; AREA2/ 0 if merge was done or adr of ght area 2 if insertion needed
; SPADR/ sender protocol address
; SHADR/ sender hardware address
; ARP/ address of ARP packet
; NCT/ NCT address
; UNB/ address of the UN block given to us by NISRV
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
ARPRC2: LOAD T1,AR$TA,(ARP) ;GET THE TARGET INTERNET ADDRESS
CAME T1,NTLADR(NCT) ;WAS THE PACKET FOR US ?
RET ;NO, IGNORE IT
SKIPE AREA2 ;SHOULD THIS INFORMATION BE INSERTED ?
CALL ARPUPD ;YES, UPDATE THE GHT
LOAD T1,AR$OP,(ARP) ;GET THE OPCODE
CAIE T1,AR.REQ ;IS IT A REQUEST ?
RET ;NO, WE'RE DONE WITH THE PACKET NOW
CALLRET ARPRC3 ;YES, GO REPLY TO IT
;ARPRC3 - STEP 3 IN PROCESSING AN ARP PACKET
;
; Here to send a reply ARP packet
;
; ARP/ address of the ARP packet
; SPADR/ sender protocol address
; UNB/ address of the UN block given to us by NISRV
;
; Returns + 1 if packet is to be ignored
; + 2 on success
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
ARPRC3: CALL ARPBFR ;GET SEND BUFFER TO USE
JUMPE T1,R ;NONE AVAILABLE IF ZERO, ARPBFR BUGINF'D
MOVE ARP,T1
MOVE T1,SPADR ;GET THE INTERNET ADDRESS OF SENDER
STOR T1,AR$TA,(ARP) ;SAVE THIS AS THE TARGET ADDRESS
MOVEI T1,AR.REP ;SET OPCODE TO REPLY
STOR T1,AR$OP,(ARP)
CALL ARPSD1 ;SET UP REST OF ARP, UN BLOCK AND SEND IT
RETBAD
RETSKP
SUBTTL ARP GHT Updating
;ARPUPD - UPDATE THE GHT
;
; Called from ARPRC2, this routine inserts an entry into
; the ght.
;
; AREA1/ adr of ght area 1 where entry is to be inserted
; AREA2/ adr of ght area 2 where entry is to be inserted
; SPADR/ sender protocol address
; SHADR/ sender hardware address
;
; Returns + 1 always
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
ARPUPD: MOVE T3,GHTCNT ;GET # OF ENTRIES IN THE GHT
CAML T3,NIMAXH ;ANY MORE ROOM ?
CALLRET ARPMAX ;NO
;**;[7450] Delete 1 line at ARPUPD+3 JMP Apr 9 87
MOVE T2,GHTAR1 ;GET ADDRESS OF AREA ONE
ADD T2,GHTCNT ;GET ADDRESS OF END OF AREA ONE
MOVN T1,T2 ;WE ARE GOING TO DO A REVERSE XBLT
ADD T1,AREA1 ;DETERMINE THE REAL COUNT
XMOVEI T3,1(T2) ;DESTINATION IS ONE GREATER THAN SOURCE
XBLT. T1, ;SHUFFLE AREA ONE WITH REVERSE XBLT
MOVE T1,AREA2 ;GET ADR OF AREA 2 ENTRY
MOVE T2,GHTCNT ;GET CURRENT NUMBER OF GHT ENTRIES
IMULI T2,GH2MDL ;GET CURRENT LENGTH OF AREA 2
ADD T2,GHTAR2 ;DETERMINE LAST ADR IN AREA 2
SUB T1,T2 ;GET NEGATIVE COUNT FOR REVERSE XBLT
XMOVEI T3,GH2MDL(T2) ;GET DEST ADR FOR REVERSE XBLT
XBLT. T1, ;SHUFFLE AREA TWO
MOVE T1,SPADR ;GET SENDERS INTERNET ADDRESS
MOVE T2,AREA1 ;GET THE ADDRESS WHERE TO INSERT
MOVEM T1,(T2) ;INSERT THE ADDRESS
DMOVE T1,SHADR ;GET ETHERNET ADDRESS OF SENDER
MOVE T3,AREA2 ;GET THE ADDRESS WHERE TO INSERT
DMOVEM T1,GH.EN1(T3) ;INSERT IT
AOS GHTCNT ;BUMP THE COUNT
;**;[7450] Delete 1 line from ARPUPD+25 JMP Apr 8 87
MOVX T1,GH%ARP ;GET UPDATED BY ARP FLAG
IORM T1,GH.GCF(T3) ;SET IT IN THE GHT
RET
;Here when the entry could not be inserted.
ARPMAX: BUG.(INF,IPGHTF,IPNIDV,SOFT,<ARP information not inserted, GHT is full>,,<
Cause: The internet ethernet ARP software has attempted to add another
internet/ethernet address translation to the GHT and the GHT was
full. This problem could be avoided by increasing NIMAXH.
>)
RETBAD <NI.ER7>
ENDTV. ;END OF ARPRCV ARPVAR TRVAR
SUBTTL Trailer Encapsulation Handling
;TRLINI - INITIALIZE TRAILER ENCAPSULATION
;
; Called here from the restart code to open portal for the
; trailer encapsultion protocol types.
;
; Returns + 1 on error
; + 2 on success
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
TRLINI: TRVAR <UNBLK,PROTO>
SKIPE TRLON ;ALREADY ON ?
RETSKP ;YES
MOVEI T1,UN.LEN ;RESERVE WORDS FOR A UN BLOCK
CALL GETBLK ;GET THEM
JUMPE T1,[RETBAD <NI.ER5>] ;COULDN'T
MOVEM T1,UNBLK ;SAVE UN BLOCK FOR LATER
MOVE UNB,T1 ;COPY IT
MOVEI T1,TPROTO ;1ST INTERNET TRAILERS PROTOCOL TYPE
MOVEM T1,PROTO ;SAVE IT
TROPN3: MOVEI SRV,NI.TRL ;TYPE OF SERVICE IS TRAILERS
CALL UNSET ;SET UP THE UN BLOCK
MOVX T1,NU.OPN ;OPEN NI PORT FUNCTION
MOVE T2,UNB ;POINT AT THE UN BLOCK
CALL DLLUNI ;CALL NI DRIVER
JRST TROPN1 ;ERROR. RETURN UN BLOCK
CALL NIPBFR ;GET A BUFFER FOR THIS PROTOCOL TYPE
CALL TRPOST ;POST IT
JRST TROPN1 ;ERROR
AOS T1,PROTO ;BUMP TO NEXT HIGHER TRAILER SIZE
CAIG T1,TRMAXP+TPROTO ;OPENED ENOUGH TYPES ?
JRST TROPN3 ;YES
SETOM TRLON ;PORTALS ARE OPEN
CALL TROPN2 ;GO RELEASE THE UN BLOCK WE GOT
RETSKP
;Here when we got an error opening the portal
TROPN1: MOVEM T1,TRLERR ;SAVE THE ERROR
CALL TROPN2 ;RELEASE THE UN BLOCK
RETBAD <>,<MOVE T1,TRLERR> ;RESTORE ERROR CODE
;Here to return the UN block we just got.
TROPN2: MOVE T1,UNBLK ;GET UN BLOCK ADR
CALLRET RETBLK ;AND RELEASE THE SPACE
ENDTV. ;END OF NIOPEN TRVAR
;TRPOST - POST AN TRAILER ENCAPSULATION INPUT BUFFER
;
; This routine gives NISRV a receive buffer. The buffer must
; be resident.
;
; T1/ address of input buffer
; UNB/ address of the UN block
;
; Returns + 1 if error returned from NISRV
; + 2 on success
IFE REL6,<RESCD>
IFN REL6,<XRESCD>
TRPOST: SKIPN T1 ;ZERO IF NIPBFR COULDN'T GET A BUFFER
RETBAD <NI.ER1> ;RETURN THE ERROR
LOAD T3,NBBSZ,(T1) ;GET BUFFER SIZE
SUBI T3,LCLPKT+MAXLDR ;DON'T INCLUDE LEADER SIZE
LSH T3,2 ;MAKE WORDS INTO BYTES
STOR T3,UNBSZ,(UNB) ;SAVE IT AS RECEIVE BUFFER SIZE
STOR T1,UNRID,(UNB) ;SAVE INPUT BUFFER ADR AS REQUEST ID
ADDI T1,MAXLDR ;POINT PAST LEADER FOR START OF IP HEADER
TXO T1,<OWGP. 8,> ;FORM BYTE POINTER TO BUFFER
STOR T1,UNBFA,(UNB) ;SAVE AS THE BUFFER ADDRESS
MOVX T1,NU.RCV ;POST RECEIVE BUFFER FUNCTION
MOVE T2,UNB ;GET UN BLOCK ADR
CALL DLLUNI ;NO. CALL NISRV
CALLRET POSTER ;NISRV RETURNED ERROR
RETSKP ;SUCCESS
;TRLCDR - TRAILER ENCAPSULTED DATAGRAM RECEIVED
;
; The NI received a trailer encapsulted datagram, we don't accept
; those messages. We will buginf and then toss the message.
;
; T2/ UN block address
; T3/ 0 if function succesfull or error code
; UNRID/ address of buffer
;
; Returns + 1 on error
; + 2 on success
IFE REL6,<RESCD>
IFN REL6,<XRESCD>
TRLCDR: MOVE UNB,T2 ;COPY THE UN BLOCK POINTER
LOAD T1,UNSAD,(UNB) ;GET THE ETHER ADDRESS OF SENDER
LOAD T2,UNSAD,+1(UNB)
LOAD T3,UNPRO,(UNB) ;GET THE PROTO TYPE
BUG.(INF,IPTENC,IPNIDV,SOFT,<Received a trailer encapsulated packet>,<<T1,ETH1>,<T2,ETH2>,<T3,PROTO>>,<
Cause: The monitor has received a trailer encapsulation IP datagram
over the Ethernet.
Description:
A system on the Ethernet is using trailer encapsulation
formats for the transmission of IP datagrams. TOPS-20 (and
most other operating systems) does not support trailer
encapsulation. Some Berkeley Unix and VMS TCP/IP
implementations support trailer encapsulation in an effort to
enhance their Internet performance characteristics.
Action: Stop the indicated systems from using trailer encapsulation.
Additional Data:
Ethernet address of host sending trailer encapsulation in octal and
the protocol type received.
>)
LOAD T1,UNRID,(UNB) ;GET THE ADDRESS OF THE BUFFER
CALL TRPOST ;POST IT
RETBAD ;GOT AN ERROR
RETSKP ;GIVE GOOD RETURN
SUBTTL Read Portal Counters
;ARPRPC - READ ARP PORTAL COUNTERS
;
; Reads the portal counters for ARP. Information is returned
; by the RPC callback.
;
; Returns + 1 always. If error is returned from NISRV, ARPSRQ/ -1
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
ARPRPC: SAVEAC <NCT,SRV,UNB>
MOVE UNB,AUNBLK ;GET UN BLOCK POINTER
JUMPE UNB,[RETBAD <>,<SETOM ARPSRQ>] ;NO UN BLOCK SET UP YET
XMOVEI T1,ARPTRS ;USE THE ARP BLOCK
CALL GETRPC ;GET THE COUNTERS
RETBAD <>,<SETOM ARPSRQ> ;NO UN BLOCK SET UP YET
RET
;ARPCRP - READ ARP PORTAL COUNTERS CALLBACK
;
; This is callback occurs when NISRV has completed a read
; counters function. It clears the ARPSRQ flag which signals the
; completion of the RPC. If NISRV returns an error, ARPSRQ is
; set to -1.
;
; T2/ UN block address
; T3/ 0 or NISRV error code
IFE REL6,<RESCD>
IFN REL6,<XRESCD>
ARPCRP: SKIPE T1,T3
RETBAD <>,<SETOM ARPSRQ> ;ERROR DETECTED ?
SETZM ARPSRQ ;SIGNAL SUCCESSFUL COMPLETION
RETSKP
;NIPRPC - READ INTERNET PORTAL COUNTERS
;
; Called by the NIPSRV background routine to service a user
; IPOPR request to return the portal counters. All information
; is returned in the block pointed to by the NICTRS word.
;
; Returns + 1 always. If error is returned from NISRV, NIPSRQ/ -1
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
NIPRPC: SAVEAC <NCT,SRV,UNB>
CALL INTUNB ;GET UN BLOCK POINTER
RETBAD <>,<SETOM NIPSRQ> ;NO UN BLOCK SET UP YET
XMOVEI T1,NICTRS ;USE THE INTERNET COUNTERS BLOCK
CALL GETRPC ;GET PORTAL COUNTERS
SETOM NIPSRQ ;NO UN BLOCK SET UP YET
CALL RETUNB ;RETURN THE UN BLOCK
RET
;IPCBRC - READ INTERNET PORTAL COUNTERS CALLBACK
;
; This is callback occurs when NISRV has completed a read
; counters function. It clears the NIPSRQ flag which signals the
; completion of the RPC. If NISRV returns an error, NIPSRQ is
; set to -1.
;
; T2/ UN block address
; T3/ 0 or NISRV error code
IFE REL6,<RESCD>
IFN REL6,<XRESCD>
IPCBRC: SKIPE T1,T3
RETBAD <>,<SETOM NIPSRQ> ;ERROR DETECTED ?
SETZM NIPSRQ ;SIGNAL SUCCESSFUL COMPLETION
RETSKP
;GETRPC - GET PORTAL COUNTERS
;
; Used by both Internet and Arp, this routine tells NISRV to
; return the portal counter information.
;
; T1/ address that points to the block to put counter data
; UNB/ address of the UN block
;
; Returns + 1 on errors
; + 2 on success
IFE REL6,<SWAPCD>
IFN REL6,<XSWAPCD>
GETRPC: SASUBR <CTRBLK> ;SAVE T1 - POINTER TO COUNTER BLOCK
SKIPE (T1) ;ALREADY HAVE SPACE ?
JRST RPC1 ;YES
MOVEI T1,PC.LEN ;GET SPACE FOR PORTAL COUNTERS
CALL GETBLK ;GET IT FROM THE IP FREE SPACE
IFE. T1 ;GOT A BUFFER IF NON-ZERO
RPCERR: BUG.(CHK,IPNSPC,IPNIDV,SOFT,<No free space for portal counters>,<<SRV,SERVICE>>,<
Cause: The internet ethernet software has attempted to read the counters for
a portal and no internet free space was available.
>)
RETBAD <NI.ER6>
ENDIF.
MOVE T2,CTRBLK ;GET POINTER TO THE BLOCK
MOVEM T1,(T2) ;SAVE POINTER TO PORTAL COUNTER BLOCK
MOVEI T2,PC.LEN ;LENGTH OF THE BLOCK
CALL NIPLKB ;LOCK THE COUNTER BLOCK
CALL CLRBLK ;CLEAR OUT THE BLOCK
RPC1: SETZRO UNZRO,(UNB) ;NEVER CLEAR COUNTERS
LOAD T1,UNPID,(UNB) ;GET OUR PORTAL ID
STOR T1,UNSPI,(UNB)
MOVE T1,CTRBLK ;PUT DATA IN OUR COUNTER STORAGE
STOR T1,UNBFA,(UNB)
MOVX T1,PC.LEN ;NUMBER OF COUNTER WORDS
STOR T1,UNBSZ,(UNB)
MOVX T1,NU.RPC ;READ PORTAL COUNTERS FUNCTION
MOVE T2,UNB ;POINT AT UN BLOCK
CALL DLLUNI ;ASK NISRV
RETBAD ;NISRV RETURNED AN ERROR
RETSKP
TNXEND
END