;;; -*- Mode:Lisp; Readtable:CL; Package:USER; Base:10; Patch-File:T -*-
;;; Patch file for System version 123.80
;;; Reason:
;;;  IP segment identifiers and TCP local ports are both (mod 65536).  When IP and
;;;  TCP assign these resources, they perform this modulus arithmetic -- but they
;;;  store the numbers as (potentially large) integers.  This is confusing from
;;;  peek and no more expensive to store as small integers, so do it.
;;; Written 28-Oct-87 15:16:57 by pld at site LMI Cambridge
;;; while running on Jack Flanders from band 2
;;; with Experimental System 123.79, 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#271 at 28-Oct-87 15:16:59
#10R INTERNET#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "INTERNET")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; KERNEL; IP  "

(defun send-ip-packet (stream buffers header &optional int-pkt identifier
		       &aux gateway interface address (length 0))
  "Send IP packet(s) on behalf of a transport protocol given an IP header and a list of buffers"
  (declare (values fragments-sent identifier))
  (check-type stream ip-transport-protocol)
  (when (null buffers)
    (error "No buffers"))
  (unless (listp buffers)
    (setq buffers (ncons buffers)))
  (check-type header (satisfies ip-header-p))
  (dolist (b buffers)
    (check-type b (satisfies byte-array-or-string-p))
    (incf length (length b)))
  (cond (identifier
	 (check-type identifier (unsigned-byte 16)))
	(t
	 (setq identifier (tp-next-identification stream))
	 (setf (tp-next-identification stream) (mod (1+ identifier) #xffff))))
  ;;first, set the fields the user has no control over
  (setf (ih-version header) ip-version-number)
  (setf (ih-length header) (ih-ihl-bytes header))
  (setf (ih-flags header) (logand (ih-flags header) df-flag))
  (setf (ih-fragment-offset header) 0)
  (setf (ih-protocol header) (tp-type stream))
  (setf (ih-checksum header) 0)
  (unwind-protect
      (when (and (check-user-header header)
		 (multiple-value-setq (gateway interface)
		   (route (ih-dest-address header)))
		 (multiple-value-setq (address interface)
		   (send *ip-stream* :translate-address gateway interface)))
	(send-ip-packet-on-interface header
				     buffers
				     interface
				     (prog1 int-pkt (setq int-pkt nil))
				     identifier
				     length
				     address))
    (when int-pkt
      (free-packet int-pkt))))

))

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

(defun broadcast-ip-packet (stream buffers header &optional remote-network
			    &aux identifier gateway interface (length 0) (sent 0))
  "Send IP packet(s) on behalf of a transport protocol given an IP header and a list of buffers"
  (declare (values fragments-sent identifier))
  (check-type stream ip-transport-protocol)
  (when (null buffers)
    (error "No buffers"))
  (unless (listp buffers)
    (setq buffers (ncons buffers)))
  (check-type header (satisfies ip-header-p))
  (dolist (b buffers)
    (check-type b (satisfies byte-array-or-string-p))
    (incf length (length b)))
  (setq identifier (tp-next-identification stream))
  (setf (tp-next-identification stream) (mod (1+ identifier) #xffff))
  ;;first, set the fields the user has no control over
  (setf (ih-version header) ip-version-number)
  (setf (ih-length header) (ih-ihl-bytes header))
  (setf (ih-flags header) (logand (ih-flags header) df-flag))
  (setf (ih-fragment-offset header) 0)
  (setf (ih-protocol header) (tp-type stream))
  (setf (ih-checksum header) 0)
  (when (check-user-header header)
    (if remote-network
	(when (multiple-value-setq (gateway interface)
		(route (ip-broadcast-address-from-address remote-network)))
	  (setq sent (or (broadcast-ip-packet-on-interface header buffers interface identifier length) 0)))
      (dolist (interface net:*network-interfaces*)
	(incf sent (or (broadcast-ip-packet-on-interface header buffers interface identifier length) 0)))))
  (values sent identifier))

))

; From modified file DJ: L.NETWORK.IP-TCP.KERNEL; TCP.LISP#281 at 28-Oct-87 15:19:43
#10R TCP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "TCP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; KERNEL; TCP  "

(defun assign-local-port (remote-port remote-address)
  (without-interrupts
    (do ((port (tcp-next-local-port *tcp-stream*) (max 256 (mod (1+ port) 65536))))
	((unused-local-port port remote-port remote-address)
	 (setf (tcp-next-local-port *tcp-stream*) (max 256 (mod (1+ port) 65536)))
	 port))))

))
