;;; -*- Mode:Lisp; Readtable:CL; Package:USER; Base:10; Patch-File:T -*-
;;; Patch file for System version 123.206
;;; Reason:
;;;  (ip:setup-my-internet-address) was not returning correct subnet masks
;;;  in the presence of real subnets!
;;; Written 23-Feb-88 15:10:40 by pld at site Gigamos Cambridge
;;; while running on Jack Flanders from band 2
;;; with Experimental System 123.204, Experimental Local-File 73.3, Experimental FILE-Server 22.1, Experimental Unix-Interface 11.0, Experimental KERMIT 34.3, Experimental ZMail 71.0, Experimental Lambda-Diag 15.0, Experimental Tape 21.1, Experimental Site Data Editor 8.4, microcode 1755, SDU Boot Tape 3.12, SDU ROM 8.



; From modified file DJ: L.NETWORK.IP-TCP.KERNEL; IP.LISP#285 at 23-Feb-88 15:10:41
#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
	   (dolist (elt *network-list* (ip-subnet-mask address))
	     (let ((mask (cdr elt)))
	       (when (= (logand (car elt) mask) (logand address mask))
		 (return 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))))

))
