;;; -*- Mode:LISP; Package:UDP; Readtable:CL; Base:10 -*- #| Copyright LISP Machine, Inc. 1987 See filename "Copyright.Text" for licensing and release information. |# (defconstant *udp-namespace-server-port* 133.) (tcpa:define-network-service *udp-namespace-service* :namespace :udp "LMI Namespace" :listen-port *udp-namespace-server-port* :toplevel-function 'udp-namespace-server-function :auto-enable? nil) (defun udp-namespace-server-function (stream) (multiple-value-bind (packet length) (send stream :read-packet (make-string 128)) (reply-to-namespace-request (find-port-identification (namespace-string packet length) #'identity #'(lambda () 0.)) stream))) (defun namespace-string (buffer length) (let ((string (make-string length))) (do ((buffer-pointer 0 (1+ buffer-pointer)) (string-pointer 0 (1+ string-pointer)) (count length (1- count))) ((zerop count) string) (setf (char string string-pointer) (char-upcase (int-char (elt buffer buffer-pointer))))))) (defun reply-to-namespace-request (port-identification stream) (let ((reply-buffer (make-array 2 :element-type '(unsigned-byte 8.)))) (setf (elt reply-buffer 0) (logand #X00FF port-identification)) (setf (elt reply-buffer 1) (ash (logand #xFF00 port-identification) -8.)) (send stream :write-packet reply-buffer))) (defparameter *udp-server-alist* `( ;; As per RFC 990 ("RJE" 5.) ("ECHO" 7.) ("DISCARD" 9.) ("USERS" 11.) ("DAYTIME" 13.) ("NETSTAT" 15.) ("QUOTE" 17.) ("CHARGEN" 19.) ("FTP-DATA" 20.) ("FTP" 21.) ("TELNET" 23.) ("SMTP" 25.) ("NSW-FE" 27.) ("MSG-ICP" 29.) ("MSG-AUTH" 31.) ("DSP" 33.) ("TIME" 37.) ("RLP" 39.) ("GRAPHICS" 41.) ("NAMESERVER" 42.) ("NICNAME" 43.) ("MPM-FLAGS" 44.) ("MPM" 45.) ("MPM-SND" 46.) ("NI-FTP" 47.) ("LOGIN" 49.) ("LA-MAINT" 51.) ("DOMAIN" 53.) ("ISI-GL" 55.) ("NI-MAIL" 61.) ("VIA-FTP" 63.) ("TACACS-DS" 65.) ("BOOTPS" 67.) ("BOOTPC" 68.) ("TFTP" 69.) ("NETRJS-1" 71.) ("NETRJS-2" 72.) ("NETRJS-3" 73.) ("NETRJS-4" 74.) ("FINGER" 79.) ("HOSTS2-NS" 81.) ("MIT-ML-DEV" 83.) ;("MIT-ML-DEV" 85.) ("SU-MIT-TG" 89.) ("MIT-DOV" 91.) ("DCP" 93.) ("SUPDUP" 95.) ("SWIFT-RVF" 97.) ("TACNEWS" 98.) ("METAGRAM" 99.) ("HOSTNAME" 101.) ("ISO-TSAP" 102.) ("X400" 103.) ("X400-SND" 104.) ("CSNET-NS" 105.) ("RTELNET" 107.) ("POP-2" 109.) ("SUNRPC" 111.) ("AUTH" 113.) ("SFTP" 115.) ("UUCP-PATH" 117.) ("NNTP" 119.) ("ERPC" 121.) ("NTP" 123.) ("LOCUS-MAP" 125.) ("LOCUS-CON" 127.) ("PWDGEN" 129.) ("CISCO-FNA" 130.) ("CISCO-TNA" 131.) ("CISCO-SYS" 132.) ("SUR-MEAS" 243.) ("LINK" 245.) ;;; LMI indirection ("CONNAME" 133.) )) (defun find-port-identification (string if-found if-not-found) (let ((result (assoc string *udp-server-alist* :test #'string-equal))) (if result (funcall if-found (second result)) (funcall if-not-found)))) (defun ask-for-port-from-namespace-server (string host if-found if-unknown if-timeout if-bad-packet if-no-udp) (check-type string string) (let ((reply-packet (using-udp-socket host *udp-namespace-server-port* "Namespace Request" #'(lambda (stream ip-header) (send stream :receive) (labels ((wait-for-reply (count) (send stream :write-packet string ip-header) (cond ((zerop count) :timeout) ((process-wait-with-timeout "Namespace Reply" 60. #'(lambda () (send stream :listen))) (send stream :read-packet)) (t (wait-for-reply (1- count)))))) (wait-for-reply 5.))) #'(lambda () :udp-down)))) (cond ((eq reply-packet :timeout) (funcall if-timeout)) ((eq reply-packet :udp-down) (funcall if-no-udp)) ((not (eq (first reply-packet) :data)) (funcall if-bad-packet (first reply-packet))) (t (let ((port-number (+ (elt (third reply-packet) 0) (ash (elt (third reply-packet) 1) 8.)))) (if (zerop port-number) (funcall if-unknown) (funcall if-found port-number))))))) (defun get-port-from-namespace-server (string host) (labels ((use-local-list (message) #'(lambda (&rest cruft) (apply #'format t message host string cruft) (find-port-identification (string-upcase string) #'identity #'(lambda () (cerror "Type in your guess." "Could not find any information about contact ~A." string) (let ((your-guess (si::prompt-and-read :read "What is your guess? "))) (check-type your-guess (unsigned-byte 16)) your-guess)))))) (ask-for-port-from-namespace-server string host #'identity (use-local-list "~%Namespace server at ~A ignorant of contact ~A, using local list.") (use-local-list "~%No response for namespace request at ~A, using local list.") (use-local-list "~%During namespace request of ~a for ~a, received a ~a, using local list.") (use-local-list "~%Could not open UDP stream, using local list."))))