;;; -*- Mode:Lisp; Readtable:CL; Package:USER; Base:10; Patch-File:T -*-
;;; Patch file for System version 123.108
;;; Reason:
;;;  ip:setup-my-internet-address and chaos:setup-my-address now deal with the case that the
;;;  Internet and Chaos addresses change -- the *network-interfaces* must be updated so that
;;;  ARP works right.
;;; Written 10-Nov-87 11:06:16 by pld at site LMI Cambridge
;;; while running on Orson Welles from band 2
;;; with Experimental System 123.107, Experimental Local-File 73.0, Experimental FILE-Server 22.0, Experimental Unix-Interface 11.0, Experimental Tape 18.0, Experimental KERMIT 34.0, Experimental ZMail 71.0, Experimental Lambda-Diag 15.0, microcode 1754, SDU Boot Tape 3.12, SDU ROM 8.



; From modified file DJ: L.NETWORK.IP-TCP.KERNEL; IP.LISP#274 at 10-Nov-87 11:06:17
#10R INTERNET#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "INTERNET")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; KERNEL; IP  "

(defun setup-my-internet-address ()
  "Reads :network-names site option and sets up *network-list*.
Return two values: a list of our Internet addresses and a list of corresponding Subnet Masks"
  (declare (values address-list subnet-mask-list))
  (flet ((find-subnet-mask (address)
	   ;;given address and *network-list*, return subnet-mask
	   (multiple-value-bind (network-number mask)
	       (ip-network-number-and-mask address)
	     (let ((found (assoc network-number *network-list*)))
	       (if found
		   (cdr found)
		 mask)))))
    (let* ((network-addresses (send si:local-host :network-addresses))
	   (internet-addresses (getf network-addresses :internet))
	   (network-names (global:get-site-option :network-names))
	   (subnet-masks nil))
      (setq *network-list* nil)
      (dolist (network network-names)
	(dolist (domain (second network))
	  (when (eq (first domain) :internet)
	    (let* ((network-number (parse-internet-address (second domain)))
		   (subnet-mask (if (third domain)
				    (parse-internet-address (third domain))
				  (ip-subnet-mask network-number))))
	      (push (cons network-number subnet-mask) *network-list*)))))
      (setq subnet-masks (mapcar #'find-subnet-mask internet-addresses))
      (let ((old-internet-address (and *ip-stream* (ip-enabled *ip-stream*) (first (ip-addresses *ip-stream*))))
	    (new-internet-address (first internet-addresses)))
	(cond ((eql old-internet-address new-internet-address)
	       ;;No change (no IP before and none now, or had same IP address)  -- nothing to do
	       )
	      ((null old-internet-address)
	       ;;Didn't used to have an IP address but now we do.  Can't do anything here, as this function
	       ;;can be called either from (net:configure) or the site initialization list.  In the first
	       ;;case, IP will be started.  In the second, the user must do a (net:configure).
	       )
	      ((null new-internet-address)
	       ;;Used to have an IP address but now we don't -- disable IP
	       (send *ip-stream* :close))
	      (t
	       ;;We used to have an IP address and we still do -- but it has changed.  We must change the
	       ;;addresses in the Network Interfaces so that ARP will work right
	       (dolist (ni net:*network-interfaces*)
		 (unless (eq (net:ni-interface ni) :loopback)
		   (delete-from-alist :internet (net:ni-address-alist ni))
		   (push (list :internet new-internet-address) (net:ni-address-alist ni))))
	       (setf (ip-addresses *ip-stream*)
		     (substitute new-internet-address old-internet-address (ip-addresses *ip-stream*)))
	       ;;Must also reset all the transport protocols -- existing connections are to the old address
	       (dolist (tp (ip-protocols *ip-stream*))
		 (send (cdr tp) :reset)))))
      (values internet-addresses subnet-masks))))

))

; From modified file DJ: L.NETWORK.CHAOS; CHSNCP.LISP#399 at 10-Nov-87 11:19:55
#10R CHAOS#: 
(COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "CHAOS")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; CHAOS; CHSNCP  "

(defun setup-my-address ()
  (let ((old-address (and (boundp 'my-address) my-address)))
    (select-processor
      (:cadr
	(setq my-address (%unibus-read my-number-register)))	;Full address of this host.
      ((:lambda :explorer)
       (let ((names-for-this-machine (multiple-value-list (si:get-pack-name)))
	     my-name)
	 (cond ((and (= si:processor-type-code si:lambda-type-code)
		     (variable-boundp si:*my-proc-number*))
		(setq my-name (nth si:*my-proc-number* names-for-this-machine)))
	       (t
		(setq my-name (car names-for-this-machine))))
	 (without-interrupts
	   (setq my-address #o3412)		; FLAG THAT ADDRESS IS BAD
	   (when (stringp my-name)
	     (let ((host (si:parse-host my-name t nil)))
	       (when host
		 (setq my-address (send host :network-address :chaos))))))
	 )))
    (cond ((eql old-address my-address))	;Chaos address unchanged
	  ((null old-address))			;Didn't used to have address but now we do
	  ((null my-address)			;Used to have an Chaos address but now we don't -- disable Chaos
	   (when *chaos-stream*
	     (send *chaos-stream* :close)))
	  (t
	   ;;We used to have an Chaos address and we still do -- but it has changed.  We must change the
	   ;;addresses in the Network Interfaces so that ARP will work right
	   (dolist (ni net:*network-interfaces*)
	     (net:delete-from-alist :chaos (net:ni-address-alist ni))
	     (push (list :chaos my-address) (net:ni-address-alist ni)))
	   (when *chaos-stream*
	     (setf (chaos-addresses *chaos-stream*)
		   (substitute my-address old-address (chaos-addresses *chaos-stream*)))))
	  ))
  (setq my-subnet (chaos-subnet-number-from-address my-address))	;Subnet of this host.
  (let ((existing-host (si:get-host-from-address my-address :chaos)))
    (setq si:local-host
	  (if (and existing-host (eq (send existing-host :system-type) :lispm))
	      existing-host
	    (si:make-unnamed-host :lispm `(:chaos (,my-address)))))))

))
