;;; -*- Mode:Lisp; Readtable:CL; Package:USER; Base:10; Patch-File:T -*-
;;; Patch file for System version 123.205
;;; Reason:
;;;  Don't trouble to enable the Share interface unless there are other processors.
;;; Written 19-Feb-88 16:06:31 by pld at site Gigamos Cambridge
;;; while running on Djinn from band 1
;;; with Experimental System 123.199, Experimental Local-File 73.3, Experimental FILE-Server 22.1, Experimental Unix-Interface 11.0, Experimental Tape 18.0, Experimental KERMIT 34.3, Experimental ZMail 71.0, Experimental Lambda-Diag 15.0, microcode 1754, SDU ROM 8.



; From modified file DJ: L.NETWORK.KERNEL; CONFIGURE.LISP#95 at 19-Feb-88 16:13:42
#10R NETWORK#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "NETWORK")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; KERNEL; CONFIGURE  "


(defun configure ()
  ;; If we are in the cold load, do a mini-configuration
  (when si:*in-cold-load-p*
    (cold-load-configure)
    (return-from configure t))

  ;; Clear out current network configuration
  (deconfigure)

  ;; Reset the int-pkts
  (initialize-network-buffers)
  
  ;; Put the network clock function onto the clock list
  (without-interrupts
    (pushnew 'net:network-clock sys:clock-function-list))
  
  ;; Start the device drivers
  (initializations 'network-driver-initialization-list t)
  
  ;; Start the protocol modules
  (when (eq si:*my-op* si:*ethernet-hardware-controller*)
    (arp:setup-arp))
  (chaos:setup-chaos)

  (let ((ip-address-p (ip:setup-ip)))
    (cond (ip-address-p
	   (icmp:setup-icmp)
	   (udp:setup-udp)
	   (tcp:setup-tcp))
	  (t
	   (tv:careful-notify nil t "This processor has no Internet Address")))
  
    (when si:*other-processors*
      ;;KLUDGE: share interface must be set up before chaos, as chaos enables itself on share device --
      ;;but share interface sets %processor-conf-chaos-address, so must reset it after chaos
      ;;has set its address
      (send si:share-interface :reset)
      ;; for all of our other processors, set up ARP translation for share interface
      (setq *processor-forwarding-alist* nil)
      (dolist (op si:*other-processors*)
	(push (cons op nil) *processor-forwarding-alist*)
	(dolist (domain '(:chaos :internet))
	  (let ((address (find-network-address-for-other-processor op domain)))
	    (when address
	      (add-address-info address domain si:share-interface op))))))

    (dolist (x (ni-address-alist *loopback-interface*))
      ;;For all protocols enabled on the loopback interface, set up address translations
      (when (second x)
	(add-address-info (second x) (first x) *loopback-interface* nil)))

    (when ip-address-p
      ;;Start the TCP/UDP server process and enable network services
      (tcp-application:initialize-tcp-server-process)
      (tcp-application:enable-all-network-services)
      (tcp-application:initialize-udp-rwho-server-process)))

  ;;Start the network receiver process
  (start-receiver)

  (setup-network-gauges)			;If Fancy-Landscape enabled, populate screen with gauges

  t)

))

; From modified file DJ: L.NETWORK.DRIVERS; SHARE.LISP#75 at 19-Feb-88 16:15:08
#10R SYSTEM-INTERNALS#: 
(COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "SYSTEM-INTERNALS")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; DRIVERS; SHARE  "

(defun setup-share-interface (tag &aux alist)
  (when (and si:*other-processors*
	     *share-code-ready*)
    
    (when share-interface
      (setq alist (net:ni-protocol-alist share-interface))
      (send share-interface :close))
    
    (setq share-interface
	  (make-share-interface :tag tag
				:interface :share
				:keyword :backplane
				:address *my-op*
				:point-to-point t
				:minimum-data-length 0
				:maximum-data-length
				    (* 4 (- page-size (length chaos-share-dev-qs)))
				:sent-header-length 0
				:rcvd-header-length 0
				:sent-trailer-length 0
				:rcvd-trailer-length 0
				:protocol-alist alist
				:reset-function 'share-reset
				:packet-ready-function 'share-packet-ready
				:get-next-packet-function 'share-get-next-packet
				:send-function  'share-send-int-pkt
				:gauge-name "Share"
				))
    
    (send share-interface :open)
    (send share-interface :enable)))

))

; From modified file DJ: L.NETWORK.KERNEL; ARP.LISP#129 at 19-Feb-88 16:15:46
#10R ARP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "ARP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; KERNEL; ARP  "

(defun processor-without-network-interface (address domain)
  "Return T if the specified ADDRESS in the specified address DOMAIN is on our bus and does not
control a network interface.  I.E. if we should accept packets for it."
  (and si:*share-code-ready*
       (boundp 'si:share-interface)
       si:share-interface
       (net:ni-enabled si:share-interface)
       (dolist (x (net:ni-address-translations si:share-interface))
	 (when (and (eq (net:at-protocol x) domain)
		    (= (net:at-protocol-address x) address))
	   (return (cdr (assoc (net:at-hardware-address x) net:*processor-forwarding-alist*)))))))

))

; From modified file DJ: L.NETWORK.IP-TCP.KERNEL; IP.LISP#285 at 19-Feb-88 16:16:07
#10R INTERNET#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "INTERNET")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; KERNEL; IP  "


(defun route (address &optional tos)
  "Given an internet address, choose the gateway to send a packet to"
  (declare (values gateway interface local-p))
  ;;If this is one of our addresses, return loopback interface
  (when (member address (ip-addresses *ip-stream*))
    (return-from route (values address *loopback-interface* t)))
  ;;If this is the address of host on same backplane, return share interface
  (and si:share-interface
       (arp:get-address-info address :internet nil si:share-interface nil)
       (return-from route (values address si:share-interface t)))
  ;;If address on directly connected network, send directly
  (dolist (interface *network-interfaces*)
    (let* ((ip-on-ni (assoc :internet (net:ni-network-alist interface) :test #'eq))
	   (my-network (second ip-on-ni))
	   (mask (third ip-on-ni)))
      (when ip-on-ni
	(cond ((net:ni-point-to-point interface)
	       ;;search address cache
	       (when (arp:get-address-info address :internet nil interface nil)
		 ;;The address is accessible on point-to-point link
		 (return-from route (values address interface nil))))
	      ((and mask (= (logand mask address) (logand mask my-network)))
	       ;;We are directly connected to that network.  Send the packet directly
	       (return-from route (values address interface nil)))))))
  ;;Else, search routing table
  (let ((network-number (ip-network-number-from-address address)))
    (dolist (x *network-list*)
      ;;For all known networks....
      (when (= (car x) (logand (cdr x) address))
	;;If this is one of them, pick out the real network number under subnet mask
	(return (setq network-number (car x)))))
    (do* ((list *route-table* (cdr list))
	  (item (car list) (car list))
	  (host-entry nil)			;Entry found for this host and any TOS
	  (network-entry)			;Entry found for this network and this TOS
	  (default-entry nil))			;Entry found for this network and any TOS
	 ((null list)
	  (let ((win (or host-entry network-entry default-entry)))
	    (when win
	      (return-from route (values (re-gateway win) (re-interface win) nil)))))
      (cond ((= (re-network item) address)	;Host specific entry matches
	     (cond ((eql tos (re-tos item))	;TOS matches
		    (return-from route (values (re-gateway item) (re-interface item) nil)))
		   ((null (re-tos item))	;TOS doesn't match, but this is generic
		    (setq host-entry item))))
	    ((= (re-network item) network-number)	;Network entry matches
	     (cond ((eql tos (re-tos item))	;TOS matches
		    (setq network-entry item))
		   ((null (re-tos item))	;TOS doesn't match but this is generic
		    (setq default-entry item)))))))
  ;;If all else fails, return default gateway
  (values *default-gateway* *default-interface* nil))

;;;Background process -- route table update, packet forwarding, etc.

))

; From modified file DJ: L.NETWORK.IP-TCP.KERNEL; IP.LISP#285 at 19-Feb-88 16:16:09
#10R INTERNET#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "INTERNET")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; KERNEL; IP  "


(defun local-host-p (address)
  (values (or (member address (ip-addresses *ip-stream*))
	      (and si:share-interface
		   (arp:get-address-info address :internet nil si:share-interface nil)))))

))
