;;; -*- Mode:Lisp; Readtable:CL; Package:USER; Base:10; Patch-File:T -*-
;;; Patch file for System version 123.223
;;; Reason:
;;;  If CHAOS:RECEIVE-INT-PKT gets a packet not for this machine, it forwards it.
;;;  If this machine does not talk directly to a network (e.g. slot 4 with 3com
;;;  owned by slot 0), it should not forward it to the ethernet owner -- it should
;;;  drop it.  This situation occurs when the slot 0 knows who slot 4 is, but slot
;;;  4 doesn't yet know.  Packets end up bouncing back and forth at a high rate...
;;; Written 7-Apr-88 13:43:39 by pld at site LMI
;;; while running on Opus from band 2
;;; with Experimental System 123.221, Experimental Local-File 73.4, Experimental FILE-Server 22.2, Experimental Unix-Interface 11.0, Experimental KERMIT 34.3, Experimental ZMail 71.0, Experimental Lambda-Diag 15.0, Experimental Tiger 27.0, Experimental Site Data Editor 9.0, Experimental Tape 22.0, microcode 1755, SDU Boot Tape 3.14, SDU ROM 8, Beta II/site/patch.



; From modified file OPUS: L.NETWORK.CHAOS; CHSNCP.LISP#405 at 7-Apr-88 13:43:40
#10R CHAOS#: 
(COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "CHAOS")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; CHAOS; CHSNCP  "

(DEFUN RECEIVE-INT-PKT (INT-PKT &optional broadcast-p &AUX (OP (PKT-OPCODE INT-PKT)) CONN ACKN)
  (COND ((and (NOT (ZEROP (LDB (byte 8 0) (AREF INT-PKT 0))))
	      (memq *header-version-action* '(:NOTIFY :RESPECT)))
	 (if (eq *header-version-action* :notify)
	     (tv:notify nil "Got non-zero header version from address: #o~O"
			(pkt-source-address int-pkt)))
	 (NET:FREE-PACKET INT-PKT))
	((= OP RUT-OP)
	 (DO ((I FIRST-DATA-WORD-IN-PKT (+ I 2))
	      (N (floor (PKT-NBYTES INT-PKT) 4) (1- N))
	      (GATEWAY (PKT-SOURCE-ADDRESS INT-PKT))
	      (N-SUBNETS (ARRAY-LENGTH ROUTING-TABLE))
	      (SUBNET) (COST))
	     ((ZEROP N) (NET:FREE-PACKET INT-PKT))
	   (SETQ SUBNET (AREF INT-PKT I) COST (AREF INT-PKT (1+ I)))
	   (WHEN (AND (< SUBNET N-SUBNETS)
		      ( COST (AREF ROUTING-TABLE-COST SUBNET))
		      (NULL (AREF ROUTING-TABLE-TYPE SUBNET)))
	     (SETF (AREF ROUTING-TABLE SUBNET) GATEWAY)
	     (SETF (AREF ROUTING-TABLE-COST SUBNET) COST))))
	((AND (= OP BRD-OP) (ZEROP (PKT-DEST-ADDRESS INT-PKT)))
	 (RECEIVE-BRD INT-PKT))
	((/= (PKT-DEST-ADDRESS INT-PKT) MY-ADDRESS)	;Packet to be forwarded
	 (COND ((neq si:*ethernet-hardware-controller* si:*my-op*)
		;;If we don't talk directly to network, don't forward.  If we are slot 4 and don't yet
		;;know who we are, whereas slot 0 does know, we will receive packets that we (improperly)
		;;believe are not for us.  Drop them, don't bounce them back to slot 0.
		(net:free-packet int-pkt))
	       (broadcast-p
		(net:free-packet int-pkt))
	       ((OR (= (PKT-FWD-COUNT INT-PKT) 17)
		    (> (PKT-NBYTES INT-PKT) MAX-DATA-BYTES-PER-PKT))
		(NET:FREE-PACKET INT-PKT)
		(INCF PKTS-OVER-FORWARDED))
	       (T (SETF (PKT-FWD-COUNT INT-PKT) (1+ (PKT-FWD-COUNT INT-PKT)))
		  (INCF PKTS-FORWARDED)
		  (TRANSMIT-INT-PKT INT-PKT nil nil nil))))
	(T (RECORD-INT-PKT-HEADER INT-PKT)
	   (AND (BIT-TEST #o200 OP) (INCF DATA-PKTS-IN))
	   (COND
	     ((= OP RFC-OP) (RECEIVE-RFC INT-PKT))
	     ((= OP LOS-OP) (RECEIVE-LOS INT-PKT))
	     ((= OP CLS-OP) (RECEIVE-CLS INT-PKT))
	     ((= OP MNT-OP) (NET:FREE-PACKET INT-PKT))
	     ((AND (OR (NULL (SETQ CONN (PKT-DEST-CONN INT-PKT)))
		       (/= (PKT-DEST-INDEX-NUM INT-PKT) (LOCAL-INDEX-NUM CONN))
		       (/= (PKT-SOURCE-ADDRESS INT-PKT) (FOREIGN-ADDRESS CONN)))
		   (NOT (SETQ CONN (CDR (ASSQ (PKT-DEST-INDEX-NUM INT-PKT)
					      DISTINGUISHED-PORT-CONN-TABLE)))))
	      (TRANSMIT-LOS-INT-PKT INT-PKT LOS-OP
				    (IF CONN "You are not connected to this index"
				      "No such index exists")))
	     ((PROG2 (SETF (TIME-LAST-RECEIVED CONN) (ZL:TIME))
		     (= OP OPN-OP))
	      (RECEIVE-OPN CONN INT-PKT))
	     ((= OP FWD-OP) (RECEIVE-FWD CONN INT-PKT))
	     ((= OP ANS-OP) (RECEIVE-ANS CONN INT-PKT))
	     ((= OP UNC-OP) (RECEIVE-UNC CONN INT-PKT))
	     ((NOT (OR (= OP SNS-OP) (= OP STS-OP)
		       (= OP EOF-OP) ( OP DAT-OP)))
	      (TRANSMIT-LOS-INT-PKT INT-PKT LOS-OP "Illegal opcode"))
	     ((NOT (= (PKT-SOURCE-INDEX-NUM INT-PKT) (FOREIGN-INDEX-NUM CONN)))
	      (IF (= OP SNS-OP) (NET:FREE-PACKET INT-PKT)	;Ignore SNS if not open
		(TRANSMIT-LOS-INT-PKT INT-PKT LOS-OP
				      "That is not your index number for this connection")))
	     ;; Below here can be SNS, STS, EOF, or DAT, all packets having ack fields.
	     ((NOT (EQ (STATE CONN) 'OPEN-STATE))
	      (IF (= OP SNS-OP) (NET:FREE-PACKET INT-PKT)	;Ignore SNS if not open
		(TRANSMIT-LOS-INT-PKT INT-PKT LOS-OP "Connection not open")))
	     (T
	      ;; Below here, this INT-PKT contains a normal acknowledgement field.
	      (SETQ ACKN (PKT-ACK-NUM INT-PKT))	;Acknowledgement field
	      (RECEIPT CONN ACKN)		;Clear receipted packets from send list
	      (COND ((OR (>= OP DAT-OP) (= OP EOF-OP))
		     (RECEIVE-EOF-OR-DAT CONN INT-PKT))
		    ((= OP SNS-OP) (RECEIVE-SNS CONN INT-PKT))
		    ((= OP STS-OP) (RECEIVE-STS CONN INT-PKT))
		    (T (FERROR NIL "should not get here"))))))))

))
