;;; -*- Mode:Lisp; Readtable:CL; Package:USER; Base:10; Patch-File:T -*-
;;; Patch file for System version 126.2
;;; Reason:
;;;  Add :force-p keyword to (ethernet:exos-stats) to query the board even
;;;  if the interface is not enabled.  Needed by (ethernet:netspy)...
;;; Written 26-Jul-88 17:19:38 by keith (Keith M. Corbett) at site Gigamos Cambridge
;;; while running on Azathoth from band 2
;;; with ZWEI 125.3, ZMail 73.0, Local-File 75.0, File-Server 24.0, Unix-Interface 13.0, Tape 24.1, Lambda-Diag 17.0, Experimental System 126.0, Experimental MEDIUM-RESOLUTION-COLOR 4.0, microcode 1762, SDU Boot Tape 3.14, SDU ROM 8, the old ones.



; From file DJ: L.NETWORK.DRIVERS; EXCELAN.LISP#141 at 26-Jul-88 17:20:57
#10R ETHERNET#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "ETHERNET")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; DRIVERS; EXCELAN  "

(defun exos-stats (&key (format-stream t) (reset-p nil) (print-p t) force-p)
  "Print exos board statistics."
  (cond ((null *excelan-owner*)
	 (format format-stream "~&This backplane doesn't have an Excelan board."))
	((not (i-own-excelan))
	 (format format-stream "~&This processor doesn't own the Excelan board."))
	((null *excelan-ethernet-interface*)
	 (format format-stream "~&The Excelan board is not configured."))
	((and (not force-p) (not (exc-enabled *excelan-ethernet-interface*)))
	 (format format-stream "~&The Excelan board is not enabled."))
	(t
	 (with-lock (stats-array-lock)
	   (array-initialize stats-array 0)
	   (link-net-ststcs stats-array reset-p)
	   
	   (when print-p
	     (format format-stream "~
~%*******************************************************~
~% frames transmitted:                     ~12d.~
~%-------------------------------------------------------~
~% frames aborted due to excess collisions:~12d.~
~%-------------------------------------------------------~
~% time domain reflectometer:              ~12d.~
~%-------------------------------------------------------~
~% frames received:                        ~12d.~
~%-------------------------------------------------------~
~% frames received with alignment errors:  ~12d.~
~%-------------------------------------------------------~
~% frames received with crc errors:        ~12d.~
~%-------------------------------------------------------~
~% frames lost (no receive buffers):       ~12d.~
~%*******************************************************~
~%"
		     (read-long stats-array 0 'exbdstats-xmt)
		     (read-long stats-array 0 'exbdstats-excess-coll)
		     (read-long stats-array 0 'exbdstats-tdr)
		     (read-long stats-array 0 'exbdstats-rcv)
		     (read-long stats-array 0 'exbdstats-align-err)
		     (read-long stats-array 0 'exbdstats-crc-err)
		     (read-long stats-array 0 'exbdstats-lost-err)))))))

))

; From file DJ: L.NETWORK.KERNEL; NETSPY.LISP#18 at 26-Jul-88 17:21:10
#10R ETHERNET#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "ETHERNET")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; KERNEL; NETSPY  "

(defun netspy (&key (format-stream *standard-output*)
	       peek-level types not-types sources destinations s-or-d)
  "Look at all ethernet packets seen by the Excelan board.
  Output is directed to FORMAT-STREAM unless it is NIL
    in which case a dot is PRINCed for each packet;
    use 'si:null-stream for no output except EXOS-STATS.
  PEEK-LEVEL controls level of peeking at packets;
    If peek-level is NIL, just show packet type and length;
    if non-NIL, also show destination and source;
    if n also show n data characters both as hex and as chars;
    if a list, (e.g. ip, udp, tcp, data n), interpret selected headers and n data characters.

  A packet will be selected if it satisfies the AND of the following specifications.
  TYPES is a list of ethernet types to be accepted.
  NOT-TYPES is a list of ethernet types to be rejected.
  SOURCES is a list of ethernet source addresses to be accepted.
  DESTINATIONS is a list of ethernet destination addresses to be accepted.
  S-OR-D is a list of ethernet addresses to be accepted either as source or destination.

  NETSPY runs till ABORT.
  Type any character to see EXOS-STATS, type character r to reset EXOS-STATS."
  
  (declare (special format-stream peek-level types not-types sources destinations s-or-d))
  
  (when (and (si:set-processor-owning-ethernet :find :excelan)
	     (i-own-excelan))
    (unless *excelan-ethernet-interface*
      (setup-excelan "EXCELAN" nil))
    (let ((excelan-enabled (exc-enabled *excelan-ethernet-interface*)))
      (unwind-protect
	  (progn
	    (when excelan-enabled
	      (send *excelan-ethernet-interface* :disable nil))
	    (setq *netspy-pkts* 0 *netspy-pkt-bytes* 0)
	    (link-net-mode :read-p nil :write-p t :mode 'nmode-connect-promiscuous)
	    (exos-stats :force-p t)
	    (netspy-loop))
	(send *excelan-ethernet-interface* :reset)
	(when excelan-enabled
	  (send *excelan-ethernet-interface* :enable))))))

))

; From file DJ: L.NETWORK.KERNEL; NETSPY.LISP#18 at 26-Jul-88 17:21:17
#10R ETHERNET#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "ETHERNET")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; KERNEL; NETSPY  "

(defun netspy-loop ()
  (declare (special format-stream peek-level types not-types sources destinations s-or-d))
  (terpri format-stream)
  (with-dmabuf (buf)
    (loop
      (when (listen *terminal-io*)
	(let ((c (read-char *terminal-io*)))
	  (exos-stats :reset-p (char-equal c #\r) :force-p t)))
      (let* ((n (- (link-recv buf) 4))
	     (type (read-short buf 0 'ether-type))
	     (source (read-48bits buf 0 'ether-shost))
	     (destination (read-48bits buf 0 'ether-dhost)))
	(incf *netspy-pkt-bytes* n)
	(incf *netspy-pkts*)
	(when (and (or (not types) (member type types))
		   (or (not not-types) (not (member type not-types)))
		   (or (not sources) (member source sources))
		   (or (not destinations) (member destination destinations))
		   (or (not s-or-d) (member source s-or-d) (member destination s-or-d)))
	  (cond (format-stream
		 (format format-stream "***At ~D got ~4D byte pkt" (get-universal-time) n)
		 (case type
		   (#.chaos-ethernet-type
		    (format format-stream ", type CHAOS"))
		   (#.arp-ethernet-type
		    (format format-stream ", type ARP"))
		   (#.ip-ethernet-type
		    (format format-stream ", type IP"))
		   (otherwise
		    (format format-stream ", type UNKNOWN (~X)" type)))
		 (terpri format-stream)
		 (when peek-level
		   (pkt-peek buf n type)))
		(t
		 (princ "."))))))))

))
