1 ;;; net-utils.el --- Network functions
3 ;; Author: Peter Breton <pbreton@cs.umb.edu>
4 ;; Created: Sun Mar 16 1997
5 ;; Version: $Id: net-utils.el,v 1.5 2007-03-06 14:02:59 viteno Exp $
7 ;; Time-stamp: <Monday Mar 5, 2007 14:14:13 steve>
11 ;; There are three main areas of functionality:
13 ;; * Wrap common network utility programs (ping, traceroute, netstat,
14 ;; nslookup, arp, route). Note that these wrappers are of the diagnostic
15 ;; functions of these programs only.
17 ;; * Implement some very basic protocols in Emacs Lisp (finger and whois)
19 ;; * Support connections to HOST/PORT, generally for debugging and the like.
20 ;; In other words, for doing much the same thing as "telnet HOST PORT", and
21 ;; then typing commands.
25 ;; Revision 1.1 1998/03/26 03:39:21 steveb
26 ;; New file net-utils.el.
28 ;; Revision 1.5 1998/03/11 00:27:18 pbreton
29 ;; Changed name to net-utils
30 ;; Added AUTOLOAD comments
31 ;; Added net-utils-version variable
32 ;; Don't use /usr/sbin/ping anymore, depend on ping-program-options
33 ;; ping-program-options default set for Linux
34 ;; Finger can now take USER@HOST as an argument
35 ;; network-service-connection is no longer interactive
37 ;; Revision 1.4 1998/03/06 03:57:03 pbreton
38 ;; Changed defvars to defcustoms
39 ;; Use /usr/sbin/ping (if it exists) instead of ping
40 ;; Fixed typo in traceroute-program
41 ;; Fontlock is no longer required
43 ;; Revision 1.2 1998/03/05 12:05:15 pbreton
44 ;; Posted to gnu.emacs.sources
46 ;; Revision 1.1 1998/03/05 11:31:28 pbreton
52 ;; Put these in your .emacs, or just require the whole file.
54 ;; (autoload 'traceroute "net-utils" nil t)
55 ;; (autoload 'ping "net-utils" nil t)
56 ;; (autoload 'ipconfig "net-utils" nil t)
57 ;; (autoload 'arp "net-utils" nil t)
58 ;; (autoload 'route "net-utils" nil t)
59 ;; (autoload 'netstat "net-utils" nil t)
60 ;; (autoload 'nslookup "net-utils" nil t)
61 ;; (autoload 'nslookup-host "net-utils" nil t)
62 ;; (autoload 'finger "net-utils" nil t)
63 ;; (autoload 'whois "net-utils" nil t)
64 ;; (autoload 'network-connection "net-utils" nil t)
65 ;; (autoload 'network-connection-to-service "net-utils" nil t)
72 (autoload 'ffap-string-at-point "ffap"))
74 (defconst net-utils-version (substring "$Revision: 1.5 $" 11 -2)
75 "The version number of net-utils (as string). The complete RCS id is:
77 $Id: net-utils.el,v 1.5 2007-03-06 14:02:59 viteno Exp $")
79 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
80 ;; Customization Variables
81 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
83 (defgroup net-utils nil
84 "Network utility functions."
89 (defcustom net-utils-remove-ctl-m
90 (member system-type (list 'windows-nt 'msdos))
91 "If non-nil, remove control-Ms from output."
96 (defcustom traceroute-program
97 (if (eq system-type 'windows-nt)
100 "Program to trace network hops to a destination."
105 (defcustom traceroute-program-options nil
106 "Options for the traceroute program."
108 :type '(repeat string)
111 (defcustom ping-program "ping"
112 "Program to send network test packets to a host."
117 ;; On Linux and Irix, the system's ping program seems to send packets
118 ;; indefinitely unless told otherwise
119 (defcustom ping-program-options
120 (and (memq system-type (list 'linux 'gnu/linux 'irix))
122 "Options for the ping program.
123 These options can be used to limit how many ICMP packets are emitted."
125 :type '(repeat string)
128 (defcustom ipconfig-program
129 (if (eq system-type 'windows-nt)
132 "Program to print network configuration information."
137 (defcustom ipconfig-program-options
139 (if (eq system-type 'windows-nt)
141 "Options for ipconfig-program."
143 :type '(repeat string)
146 (defcustom netstat-program "netstat"
147 "Program to print network statistics."
152 (defcustom netstat-program-options nil
153 "Options for netstat-program."
155 :type '(repeat string)
158 (defcustom arp-program "arp"
159 "Program to print IP to address translation tables."
164 (defcustom arp-program-options
166 "Options for arp-program."
168 :type '(repeat string)
171 (defcustom route-program
172 (if (eq system-type 'windows-nt)
175 "Program to print routing tables."
180 (defcustom route-program-options
181 (if (eq system-type 'windows-nt)
184 "Options for route-program."
186 :type '(repeat string)
189 (defcustom nslookup-program "nslookup"
190 "Program to interactively query DNS information."
195 (defcustom nslookup-program-options nil
196 "List of options to pass to the nslookup program."
198 :type '(repeat string)
201 (defcustom nslookup-prompt-regexp "^> "
202 "Regexp to match the nslookup prompt."
207 (defcustom ftp-program "ftp"
208 "Progam to run to do FTP transfers."
213 (defcustom ftp-program-options nil
214 "List of options to pass to the FTP program."
216 :type '(repeat string)
219 (defcustom ftp-prompt-regexp "^ftp>"
220 "Regexp which matches the FTP program's prompt."
225 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
227 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
229 (defconst nslookup-font-lock-keywords
234 (list nslookup-prompt-regexp 0 font-lock-reference-face)
235 (list "^[A-Za-z0-9 _]+:" 0 font-lock-type-face)
236 (list "\\<\\(SOA\\|NS\\|MX\\|A\\|CNAME\\)\\>"
237 1 font-lock-keyword-face)
241 (make-list 4 "[0-9]+")
243 0 font-lock-variable-name-face)
246 (let ((host-expression "[-A-Za-z0-9]+"))
249 (make-list 2 host-expression)
251 "\\(\\." host-expression "\\)*")
253 0 font-lock-variable-name-face)
255 "Expressions to font-lock for nslookup.")
257 (defvar nslookup-abbrev-table (make-abbrev-table)
258 "Abbrev table for nslookup.")
260 (define-abbrev nslookup-abbrev-table "e" "exit")
261 (define-abbrev nslookup-abbrev-table "f" "finger")
262 (define-abbrev nslookup-abbrev-table "h" "help")
263 (define-abbrev nslookup-abbrev-table "lse" "lserver")
264 (define-abbrev nslookup-abbrev-table "r" "root")
265 (define-abbrev nslookup-abbrev-table "s" "set")
266 (define-abbrev nslookup-abbrev-table "se" "server")
267 (define-abbrev nslookup-abbrev-table "v" "viewer")
269 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
271 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
273 (defvar ftp-abbrev-table (make-abbrev-table)
274 "Abbrev table for ftp.")
276 (define-abbrev ftp-abbrev-table "q" "quit")
277 (define-abbrev ftp-abbrev-table "g" "get")
278 (define-abbrev ftp-abbrev-table "p" "prompt")
279 (define-abbrev ftp-abbrev-table "anon" "anonymous")
281 (defconst ftp-font-lock-keywords
286 (list ftp-prompt-regexp 0 font-lock-reference-face)))))
289 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
291 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
293 (defun net-utils-remove-ctrl-m-filter (process output-string)
294 "Remove trailing control Ms."
295 (let ((old-buffer (current-buffer))
296 (filtered-string output-string))
299 (set-buffer (process-buffer process))
300 (setq moving (= (point) (process-mark process)))
302 (while (string-match "\r" filtered-string)
303 (setq filtered-string
304 (replace-match "" nil nil filtered-string)))
307 ;; Insert the text, moving the process-marker.
308 (goto-char (process-mark process))
309 (insert filtered-string)
310 (set-marker (process-mark process) (point)))
311 (if moving (goto-char (process-mark process))))
312 (set-buffer old-buffer))))
314 (defmacro net-utils-run-program (name header program &rest args)
315 "Run a network information program."
317 (let ((buf (get-buffer-create (concat "*" (, name) "*"))))
320 (insert (, header) "\n")
322 (apply 'start-process (, name) buf (, program) (,@ args))
323 'net-utils-remove-ctrl-m-filter)
324 (display-buffer buf))))
326 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
327 ;; Wrappers for external network programs
328 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
330 (defun traceroute (target)
331 "Run traceroute program for TARGET."
332 (interactive "sTarget: ")
334 (if traceroute-program-options
335 (append traceroute-program-options (list target))
337 (net-utils-run-program
338 (concat "Traceroute" " " target)
339 (concat "** Traceroute ** " traceroute-program " ** " target)
347 If your system's ping continues until interrupted, you can try setting
348 `ping-program-options'."
353 (read-from-minibuffer
355 (or (ffap-string-at-point 'machine) "")))))
357 (if ping-program-options
358 (append ping-program-options (list host))
360 (net-utils-run-program
361 (concat "Ping" " " host)
362 (concat "** Ping ** " ping-program " ** " host)
369 "Run ipconfig program."
371 (net-utils-run-program
373 (concat "** Ipconfig ** " ipconfig-program " ** ")
375 ipconfig-program-options
378 ;; This is the normal name on most Unixes.
380 (defalias 'ifconfig 'ipconfig)
384 "Run netstat program."
386 (net-utils-run-program
388 (concat "** Netstat ** " netstat-program " ** ")
390 netstat-program-options
395 "Run the arp program."
397 (net-utils-run-program
399 (concat "** Arp ** " arp-program " ** ")
406 "Run the route program."
408 (net-utils-run-program
410 (concat "** Route ** " route-program " ** ")
412 route-program-options
415 ;; FIXME -- Needs to be a process filter
416 ;; (defun netstat-with-filter (filter)
417 ;; "Run netstat program."
418 ;; (interactive "sFilter: ")
420 ;; (set-buffer (get-buffer "*Netstat*"))
421 ;; (goto-char (point-min))
422 ;; (delete-matching-lines filter)
426 (defun nslookup-host (host)
427 "Lookup the DNS information for HOST."
430 (read-from-minibuffer
432 (or (ffap-string-at-point 'machine) ""))))
434 (if nslookup-program-options
435 (append nslookup-program-options (list host))
437 (net-utils-run-program
441 (list "Nslookup" host nslookup-program)
449 "Run nslookup program."
451 (comint-run nslookup-program)
452 (set-process-filter (get-buffer-process "*nslookup*")
453 'net-utils-remove-ctrl-m-filter)
455 (make-local-variable 'font-lock-defaults)
456 '((nslookup-font-lock-keywords)))
458 (make-local-variable 'local-abbrev-table)
459 nslookup-abbrev-table)
461 (make-local-variable 'comint-prompt-regexp)
462 (setq comint-prompt-regexp nslookup-prompt-regexp)
465 ;; This is a lot less than ange-ftp, but much simpler.
469 (interactive "sFtp to Host: ")
470 (let ((buf (get-buffer-create (concat "*ftp [" host "]*"))))
473 (comint-exec buf (concat "ftp-" host) ftp-program nil
474 (if ftp-program-options
475 (append (list host) ftp-program-options)
478 (make-local-variable 'font-lock-defaults)
479 '((ftp-font-lock-keywords)))
481 (make-local-variable 'comint-prompt-regexp)
482 (setq comint-prompt-regexp ftp-prompt-regexp)
484 ;; Already buffer local!
485 (setq comint-output-filter-functions
486 (list 'comint-watch-for-password-prompt))
488 (make-local-variable 'local-abbrev-table)
491 (switch-to-buffer-other-window buf)
494 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
495 ;; Network Connections
496 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
498 ;; Full list is available at:
499 ;; ftp://ftp.isi.edu/in-notes/iana/assignments/port-numbers
500 (defvar network-connection-service-alist
503 (cons 'active-users 11)
519 (cons 'netbios-name 137)
520 (cons 'netbios-data 139)
525 "Alist of services and associated TCP port numbers.
526 This list in not complete.")
529 (defmacro run-network-program (process-name host port
530 &optional initial-string)
532 (let ((tcp-connection)
535 (setq buf (get-buffer-create (concat "*" (, process-name) "*")))
545 (error "Could not open connection to %s" (, host)))
547 (set-marker (process-mark tcp-connection) (point-min))
548 (set-process-filter tcp-connection 'net-utils-remove-ctrl-m-filter)
549 (and (, initial-string)
550 (process-send-string tcp-connection
551 (concat (, initial-string) "\r\n")))
552 (display-buffer buf))))
554 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
556 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
560 (defun finger (user host)
561 "Finger USER on HOST."
562 ;; One of those great interactive statements that's actually
563 ;; longer than the function call! The idea is that if the user
564 ;; uses a string like "pbreton@cs.umb.edu", we won't ask for the
565 ;; host name. If we don't see an "@", we'll prompt for the host.
569 (let* ((answer (read-from-minibuffer "Finger User: "
570 (ffap-string-at-point 'url)))
571 (index (string-match (regexp-quote "@") answer))
575 (substring answer 0 index)
576 (substring answer (1+ index)))
579 (read-from-minibuffer
581 (or (ffap-string-at-point 'machine) "")))))))
583 (user-and-host (concat user "@" host))
585 (concat "Finger [" user-and-host "]"))
590 (cdr (assoc 'finger network-connection-service-alist))
594 (defcustom whois-server-name "whois.internic.net"
595 "Host name for the whois service."
602 (defun whois (arg search-string)
603 "Send SEARCH-STRING to server defined by the `whois-server-name' variable.
604 With argument, prompt for whois server."
605 (interactive "P\nsWhois: ")
608 (read-from-minibuffer "Whois server name: ")
614 (cdr (assoc 'whois network-connection-service-alist))
618 (defcustom whois-reverse-lookup-server "whois.arin.net"
619 "Server which provides inverse DNS mapping."
625 (defun whois-reverse-lookup ()
627 (let ((whois-server-name whois-reverse-lookup-server))
628 (call-interactively 'whois)))
630 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
631 ;;; General Network connection
632 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
635 (defun network-connection-to-service (host service)
636 "Open a network connection to SERVICE on HOST."
641 (read-from-minibuffer "Host: "
642 (ffap-string-at-point 'machine)))
643 (completing-read "Service: "
647 (list (symbol-name (car elt)))))
648 network-connection-service-alist))))
651 (cdr (assoc (intern service) network-connection-service-alist)))
655 (defun network-connection (host port)
656 "Open a network connection to HOST on PORT."
657 (interactive "sHost: \nnPort: ")
658 (network-service-connection host (number-to-string port)))
660 (defun network-service-connection (host service)
661 "Open a network connection to SERVICE on HOST."
663 (process-name (concat "Network Connection [" host " " service "]"))
664 (portnum (string-to-number service))
666 (or (zerop portnum) (setq service portnum))
670 (pop-to-buffer (get-buffer (concat "*" process-name "*")))
675 ;;; net-utils.el ends here